如何从 tkinter 中的另一个框架调用函数而不出现 AttributeError: object has no attribute

问题描述 投票:0回答:1

大家好,我对 python 和 Tkinter 有点陌生,我几个月前开始使用。 我目前正在为我的工作开发 tkinter 应用程序。这是一个简单的应用程序,有 3 个页面,其中一个是主页,另一个是用于将条目发送到数据库的表单,最后一个是用于更改在数据库中发送的条目。

我尝试向应用程序添加夜间模式,以通过交换主题来更改 GUI。我每页创建一个函数,它适用于每个页面,但现在我尝试创建一个函数来调用另一个函数并将所有应用程序置于黑暗模式,但这就是问题。当我从这个新函数调用另一个函数时,我收到此错误: AttributeError: 'PageEdition' object has no attribute 'night_mode'

我将添加两个页面(主页和表单页)的代码,以便更好地理解问题:

class PageAccueil(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller
        canvas = Canvas(
            self,
            bg="#FFFFFF",
            height=699,
            width=1300,
            bd=0,
            highlightthickness=0,
            relief="ridge"
        )
        canvas.place(x=0, y=0)
        canvas.create_rectangle(
            0.0,
            0.0,
            1300.0,
            79.0,
            fill="#FA0096",
            outline=""
        )
        canvas.create_rectangle(
            0.0,
            79.0,
            107.0,
            699.0,
            fill="#D9D9D9",
            outline=""
        )
        button_image_1 = PhotoImage(file="assets/frame/button_1.png")
        button_1 = Button(
            image=button_image_1,
            borderwidth=0,
            highlightthickness=0,
            command=lambda: controller.show_frame(PageEdition),
            relief="flat",
            bg="#D9D9D9"
        )
        button_1.image=button_image_1
        button_1.place(
            x=16.0,
            y=110.0,
            width=75.0,
            height=75.0
        )
        button_image_2 = PhotoImage(file="assets/frame/button_2.png")
        button_2 = Button(
            image=button_image_2,
            borderwidth=0,
            highlightthickness=0,
            command=lambda: controller.show_frame(PageRecherche),
            relief="flat",
            bg="#D9D9D9"
        )
        button_2.image=button_image_2
        button_2.place(
            x=16.0,
            y=350.0,
            width=75.0,
            height=75.0
        )

        def swap():
            if button_switch['bg'] == colours_day:
                button_switch.config(image=button_switch_night_img,bg=colours_night,activebackground=colours_night)
                canvas.configure(background=colours_night)
                textAcc.configure(bg=colours_night,fg=colours_day)
                logo_label.configure(image=logo_divia_night,background=colours_night)

            else:
                button_switch.config(image=button_switch_day_img, bg=colours_day, activebackground=colours_day)
                canvas.configure(background=colours_day)
                textAcc.configure(bg=colours_day, fg=colours_night)
                logo_label.configure(image=logo_divia_day, background=colours_day)

        colours_day='#FFFFFF'
        colours_night='#2b2a33'

        logo_divia_day = tk.PhotoImage(file='assets/frame/image_1.png')
        logo_divia_night = tk.PhotoImage(file='assets/frame/logodivia_dark.png')
        logo_label = Label(self, image=logo_divia_day, borderwidth=0, background=colours_day)
        logo_label.place(x=1100, y=600)



        def dark_on_off():
            swap()
            page_instance = self.controller.get_page(PageEdition)
            page_instance.night_mode()
class PageEdition(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller

        scrollbar=Scrollbar(self,orient="vertical",bg="grey")
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)

        canvas = Canvas(
            self,
            bg="#FFFFFF",
            height=699,
            width=1300,
            bd=0,
            highlightthickness=0,
            relief="ridge"
        )
        canvas.place(x=0, y=0)
        canvas.create_rectangle(
            0.0,
            0.0,
            1300.0,
            79.0,
            fill="#FA0096",
            outline=""
        )
        canvas.create_rectangle(
            0.0,
            79.0,
            107.0,
            699.0,
            fill="#D9D9D9",
            outline=""
        )
        canvas.create_text(
            410.0,
            0.0,
            anchor="nw",
            text="Edition des données",
            fill="#FFFFFF",
            font=("Inter", 64 * -1)
        )

        def on_validate(p):
            if p.isdigit() or p=="":
                return True
            else:
                return False

        vcmd = (self.register(on_validate), '%P')



        colours_night = '#2b2a33'
        colours_day = '#FFFFFF'

        def change_text_color_to_white(widget):
            if canvas['background'] == colours_night:
                if isinstance(widget, tk.Label):
                    widget.config(fg=colours_day, background=colours_night)
                if isinstance(widget, tk.Button):
                    widget.config(background=colours_night)
                if isinstance(widget, tk.Radiobutton):
                    widget.config(fg=colours_day, background=colours_night)
                if isinstance(widget, tk.Checkbutton):
                    widget.config(fg=colours_day, background=colours_night)
            else:
                if isinstance(widget, tk.Label):
                    widget.config(fg=colours_night, background=colours_day)
                if isinstance(widget, tk.Button):
                    widget.config(background=colours_day)
                if isinstance(widget, tk.Radiobutton):
                    widget.config(fg=colours_night, background=colours_day)
                if isinstance(widget,tk.Checkbutton):
                    widget.config(fg=colours_night, background=colours_day)

        def night_mode(self):
            if canvas['background'] == colours_day:
                canvas.configure(background=colours_night)
                children = self.winfo_children()
                for child in children:
                    change_text_color_to_white(child)


            else:
                canvas.configure(background=colours_day)
                children = self.winfo_children()
                for child in children:
                    change_text_color_to_white(child)

        testbtn = Button(
            self,
            text="il vas faire tout noir",
            borderwidth=0,
            highlightthickness=0,
            command=lambda:night_mode(self),
            relief="flat"
        )
        testbtn.pack()

调用函数 dark_on_off() 时发生错误,它确实执行函数 swap() 但当函数调用 page_instance.night_mode() 时,我收到此错误: AttributeError: 'PageEdition' object has no attribute 'night_mode'

我在网上搜索了一下,然后在这里询问,我尝试改变我创建其他类的实例的方式,但我没有取得太大成功,我尝试在类的初始化参数上添加该函数,但它不起作用最近我尝试从 def__init__() 中定义该函数,但它根本不起作用。我看到了与我相似的帖子,但答案与我的情况不符,这就是我寻求帮助的原因。

如果有人有解决这个问题的想法, 我非常感谢您提供的任何支持!

提前谢谢您

纳尔逊

python function class tkinter frame
1个回答
0
投票

感谢 matszwecja 的帮助,我设法找到了一种重新组织代码的方法,并在函数 init 之外定义了 night_mode 函数,以便从我的主页调用它,将所有应用程序切换为深色或浅色模式。她是我在两个类中更改的代码(我在其中调用该函数以及在其中定义它):

class PageAccueil(tk.Frame):
    def __init__(self, parent, controller):
        def dark_on_off():
            swap()
            pageEd_instance = self.controller.get_page(PageEdition)
            pageEd_instance.night_mode()

class PageEdition(tk.Frame):
    colours_night = '#2b2a33'
    colours_day = '#FFFFFF'
    
    def __init__(self, parent, controller):
    
    def change_text_color_to_white(self, widget):
        if self.canvas['background'] == self.colours_night:
            if isinstance(widget, tk.Label):
                widget.config(fg= self.colours_day, background= self.colours_night)
            if isinstance(widget, tk.Button):
                widget.config(background= self.colours_night)
            if isinstance(widget, tk.Radiobutton):
                widget.config(fg= self.colours_day, background= self.colours_night)
            if isinstance(widget, tk.Checkbutton):
                widget.config(fg= self.colours_day, background= self.colours_night)
        else:
            if isinstance(widget, tk.Label):
                widget.config(fg=  self.colours_night, background=  self.colours_day)
            if isinstance(widget, tk.Button):
                widget.config(background= self.colours_day)
            if isinstance(widget, tk.Radiobutton):
                widget.config(fg=  self.colours_night, background=  self.colours_day)
            if isinstance(widget, tk.Checkbutton):
                widget.config(fg =  self.colours_night, background=  self.colours_day)
    def night_mode(self):
        if self.canvas['background'] == self.colours_day:
            self.canvas.configure(background = self.colours_night)
            children = self.winfo_children()
            for child in children:
                self.change_text_color_to_white(child)
        else:
            self.canvas.configure(background = self.colours_day)
            children = self.winfo_children()
            for child in children:
                self.change_text_color_to_white(child)

再次感谢 matszwecja 的帮助

© www.soinside.com 2019 - 2024. All rights reserved.