0

In summary, I am at the very beginning of the project.

What I'm trying to do is use a custom 'navigation rail' for navigation between pages.Now there is a problem. When I use the custom navigation rail alone, the program works, but when I want to integrate it into my project, I get an error. error = AttributeError: module 'flet_core.page' has no attribute 'controls'

* *

This is the code that works when I use the custom navigation rail alone.

import flet
from flet import *
from functools import partial
import time




class ModernNavBar(UserControl):
    def __init__(self,func):
        self.func = func
        super().__init__()


    def HighLight(self,e):
        print("e = "+str(e.data))
        if e.data == "true":
            print("girdi")
            e.control.bgcolor = "white10"
            e.control.update()

            e.control.content.controls[0].icon_color = "white"
            e.control.content.controls[1].color = "white"
            e.control.content.update()
        else:

            e.control.bgcolor=None
            e.control.update()

            e.control.content.controls[0].icon_color = "white54"
            e.control.content.controls[1].color = "white54"
            e.control.content.update()

    def UserData(self,initialise:str,name:str,description:str):

        return Container(
            content=Row(
                controls=[
                    Container(
                        width=42,
                        height=42,
                        bgcolor="bluegrey900",
                        alignment=alignment.center,
                        border_radius=8,
                        content=Text(
                            color="white",
                            value=initialise,
                            size=20,
                            weight="bold",
                        ),
                    ),
                    Column(
                        alignment=MainAxisAlignment.CENTER,
                        spacing=1,
                        controls=[
                            Text(
                                color="white",
                                value=name,
                                size=11,
                                weight="bold",
                                opacity=1,
                                animate_opacity=200,

                            ),
                            Text(
                                color="white54",
                                value=description,
                                size=9,
                                weight="bold",
                                opacity=1,
                                animate_opacity=200,

                            ),
                        ]
                    )
                ]
            )
        )
    def ContainedIcon(self,icon_name:str,text:str):
        return Container(
            width=180,
            height=45,
            border_radius=10,
            on_hover=lambda e: self.HighLight(e),
            on_click=None,
            content=Row(
                controls=[
                    IconButton(
                        icon=icon_name,
                        icon_size=18,
                        icon_color="white54",
                        style=ButtonStyle(
                            shape={
                                "":RoundedRectangleBorder(radius=7)
                            },
                            overlay_color={"":"transparent"}

                        )
                    ),
                    Text(
                        color="white54",
                        value=text,
                        size=9,
                        weight="bold",
                        opacity=1,
                        animate_opacity=200,

                    ),
                ]
            )
        )

    def build(self):
        return Container(
            width=200,
            height=580,
            padding=padding.only(top=10),
            alignment=alignment.center,

            content=Column(
                alignment=MainAxisAlignment.START,
                horizontal_alignment=CrossAxisAlignment.CENTER,
                controls=[
                    self.UserData("LI","Line Indent","Software"),
                    Container(
                        width=24,
                        height=24,
                        bgcolor="bluegrey800",
                        border_radius=8,
                        on_click=self.func

                    ),
                    Divider(height=5,color="transparent"),
                    self.ContainedIcon(icons.DASHBOARD,"Dashboard"),
                    self.ContainedIcon(icons.ANALYTICS, "Analytics"),

                    Divider(height=50,color="white24"),
                    self.ContainedIcon(icons.SETTINGS, "Settings"),

                ]
            )
        )


def main(page: Page):
    page.title = "Flet Modern Sidebar"

    page.horizontal_alignment = "center"
    page.vertical_alignment = "center"

    def AnimateSideBar(e):
        if page.controls[0].width != 62:
            for item in (
                    page.controls[0]
                            .content.controls[0]
                            .content.controls[0]
                            .content.controls[1]
                            .controls[:]
            ):
                item.opacity = 0
                item.update()

            for items in page.controls[0].content.controls[0].content.controls[3:]:
                if isinstance(items, Container):
                    items.content.controls[1].opacity = 0
                    items.content.update()
            time.sleep(0.2)

            page.controls[0].width = 62
            page.controls[0].update()
        else:

            page.controls[0].width = 200
            page.controls[0].update()

            time.sleep(0.2)

            for item in (
                    page.controls[0]
                            .content.controls[0]
                            .content.controls[0]
                            .content.controls[1]
                            .controls[:]
            ):
                item.opacity = 1
                item.update()

            for items in page.controls[0].content.controls[0].content.controls[3:]:
                if isinstance(items, Container):
                    items.content.controls[1].opacity = 1
                    items.content.update()


    page.add(Container(
        content=ModernNavBar(AnimateSideBar),
        padding=10,
        width=200,
        height=580,
        bgcolor="black",
        border_radius=20,
        alignment=alignment.center,
        animate = animation.Animation(500, "decelerate")

    ))

    page.update()
    print(str(page.controls[0]))


if __name__ == "__main__":
    flet.app(target=main)

When you run the page you see above, the program works perfectly.However, when I try to integrate it into a project as I will show below, I get an error.

I explain my code below:

  • main page = the part required for the application to start
  • route page = I control my app's navigation processes.
  • home page = the first page my application opens. On this page, I put the navigation rail in a row. There will be navigation rail on the left side of the window, and other content on the right. When I press the button that triggers the animation inside the navigation rail, it gives an error

What I'm trying to do is fix the animation of the navigation rail and write a function for each item to go to another page

main page

    from flet import *
    from core.init.navigation.route import Router
    def main(page : Page):  
    
        def route_change(route):
            page.views.clear()
            page.views.append(
                Router(page)[page.route]
            )
    
        page.on_route_change=route_change
        page.go("/")
    app(target=main)

route page

  from flet import *
  from product.screens.main.main import Main

  def Router(page):

    return {
        "/":View(
            route="/",
            controls=[
                Main(page)
            ]
        ),
        "/b": View(
            route="/b",
            controls=[
                Container(height=800, width=350, bgcolor="blue")
            ]
        ),

    }

home page

  import time

  from flet import *

  from product.components.side_bar import ModernNavBar


  class Main(UserControl):
    def __init__(self,page):
        super().__init__()
        self.page = page

        page.controls.append(self)
        page.update()



        print("page ===== "+str(page.controls[0]))

    def _getControlName(self):
        return "Main"

    def AnimateSideBar(e, self=None):
        if page.controls[0].width != 62:
            for item in (
                    page.controls[0]
                            .content.controls[0]
                            .content.controls[0]
                            .content.controls[1]
                            .controls[:]
            ):
                item.opacity = 0
                item.update()

            for items in page.controls[0].content.controls[0].content.controls[3:]:
                if isinstance(items, Container):
                    items.content.controls[1].opacity = 0
                    items.content.update()
            time.sleep(0.2)

            page.controls[0].width = 62
            page.controls[0].update()
        else:

            page.controls[0].width = 200
            page.controls[0].update()

            time.sleep(0.2)

            for item in (
                    page.controls[0]
                            .content.controls[0]
                            .content.controls[0]
                            .content.controls[1]
                            .controls[:]
            ):
                item.opacity = 1
                item.update()

            for items in page.controls[0].content.controls[0].content.controls[3:]:
                if isinstance(items, Container):
                    items.content.controls[1].opacity = 1
                    items.content.update()



    def build(self):
        return Container(
                    animate=animation.Animation(500, "decelerate"),
                    height=800,
                    width=200,
                    bgcolor="bluegrey",
                    content=Row(
                        controls=[
                            ModernNavBar(self.AnimateSideBar),
                            Text("Welcome to the homepage"),

                        ]
                    )

        )

When you click the button you see in the photo, it gives the following error.

enter image description here

Exception in thread Thread-8: Traceback (most recent call last):
File "C:\Users\Yonet\AppData\Local\Programs\Python\Python39\lib\threading.py", line 973, in _bootstrap_inner self.run() File "C:\Users\Yonet\AppData\Local\Programs\Python\Python39\lib\threading.py", line 910, in run self._target(*self._args, **self._kwargs) File "D:\pycharmProjectFolder\pythonProject\venv\lib\site-packages\flet_core\event_handler.py", line 28, in __sync_handler h(r) File "D:\pycharmProjectFolder\pythonProject\product\screens\main\main.py", line 24, in AnimateSideBar if page.controls[0].width != 62: AttributeError: module 'flet_core.page' has no attribute 'controls'

1 Answers1

0

seems like you were trying to use the wrong page object, therefore, it didn't have your expected controls attribute.

In your main.py snippet, you have 2 possible page use cases, one would be from the import of flet (from flet import * == from flet import page), and the other one would be one of the Main class properties also called page (self.page).

So it looks like you wanted to access the controls of your page which is stored in self.page other then in the widget you import from the flet module.

Fix the AnimateSideBar function (I just replaced all page usages to self.page which has controls attribute in it like you used in the __init__ function in Main):

def AnimateSideBar(self, e):
    if self.page.controls[0].width != 62:
        for item in (
                self.page.controls[0]
                        .content.controls[0]
                        .content.controls[0]
                        .content.controls[1]
                        .controls[:]
        ):
            item.opacity = 0
            item.update()

        for items in self.page.controls[0].content.controls[0].content.controls[3:]:
            if isinstance(items, Container):
                items.content.controls[1].opacity = 0
                items.content.update()
        time.sleep(0.2)

        self.page.controls[0].width = 62
        self.page.controls[0].update()
    else:

        self.page.controls[0].width = 200
        self.page.controls[0].update()

        time.sleep(0.2)

        for item in (
                self.page.controls[0]
                        .content.controls[0]
                        .content.controls[0]
                        .content.controls[1]
                        .controls[:]
        ):
            item.opacity = 1
            item.update()

        for items in self.page.controls[0].content.controls[0].content.controls[3:]:
            if isinstance(items, Container):
                items.content.controls[1].opacity = 1
                items.content.update()
Tim
  • 76
  • 3