I can't organize interaction between two classes, belonging to different frames in tkinter

你。 提交于 2021-01-29 11:08:22

问题


The two classes belong to different frames. The challenge is to read data from the window ʻent_dataclass a parent ofForLeftFrame in a descendant class of ForRightFrameChild`. When calling the parent class, a message appears in the console: "name 'left_frame' is not defined". Can't figure out why? Everything works in one frame. Please help me figure it out. The code is as follows:

import tkinter as tk

#-----------
class ForLeftFrame():
    def __init__(self, left_frame):
        self.left_frame = left_frame

        self.ent_data = tk.Entry(left_frame, width=8, bg='#3de',
            fg='#dff')
        self.ent_data.grid(column=0, row=1)

#-----------
class ForRightFrameChild(ForLeftFrame):
    def __init__(self, right_frame):
        self.right_frame = right_frame

        super().__init__(self, left_frame)
        self.left_frame = left_frame

        self.transf_button = tk.Button(right_frame, text="Transfer to...",
            bg='#489', fg='#dff', command=self.transferTo)
        self.transf_button.grid(column=0, row=1)

    def transferTo(self):
        self.ent_data_st = self.ent_data.get()
        print('Transfer to...', self.ent_data_st)

#-----------
class Application(tk.Frame):
    """Главный класс приложения"""
    def __init__(self, master):
        super().__init__()

        left_frame = tk.Frame(master, bg='tan', relief='groove', bd=3)
        left_frame.pack(side='left', fill='both', expand=1)
        righr_frame = tk.Frame(master, bg='aqua', relief='groove', bd=3)
        righr_frame.pack(side='right', fill='both', expand=1)

        self.for_left_frame = ForLeftFrame(left_frame)
        self.for_right_frame_child = ForRightFrameChild(righr_frame)

#-----------------------------
root = tk.Tk()
app = Application(root)
root.mainloop()

回答1:


To achive this you need to have references and that is exactly what the error suggests.

So what I did in the code below is first to write your application as a subclass of tk.Tk() so the root parameter or you window is now your own class to modify, also it becomes the controller/director in this ensemble.

Also I created your frames as a subclass of frames, how you did it first with only the application class.

Now, all the magic is in this line and I will explain what happens here for a better understanding.

self.master.left_frame.ent_data.get()

So self reference to the instance of the class which we had bound to self.right_frame in our class named Application.

The class Application is also the master of self/right_frame. The Application has the attribute left_frame which we did by self.left_frame in the Application class. self.left_frame was bound to a reference of an instance from the class LeftFrame were we have defined the attribute ent_data which is an tk.Entry that has the method get.

I know it seems confusing in the beginning and you may need to read this text more then onnce, but this is how it works. It is more or less a straight way to go.

import tkinter as tk

#-----------
class LeftFrame(tk.Frame):
    def __init__(self, master):
        tk.Frame.__init__(self, master)

        self.ent_data = tk.Entry(self, width=8, bg='#3de',fg='#dff')
        self.ent_data.grid(column=0, row=1)

#-----------
class RightFrame(tk.Frame):
    def __init__(self, master):
        tk.Frame.__init__(self,master)

        self.transf_button = tk.Button(self, text="Transfer to...",
                                       bg='#489', fg='#dff',
                                       command=self.transferTo)
        self.transf_button.grid(column=0, row=1)

    def transferTo(self):
        self.ent_data_st = self.master.left_frame.ent_data.get()
        print('Transfer to...', self.ent_data_st)

#-----------
class Application(tk.Tk):
    def __init__(self):
        super().__init__()

        self.left_frame = LeftFrame(self)
        self.right_frame = RightFrame(self)

        self.left_frame.pack(side='left', fill='both', expand=1)
        self.right_frame.pack(side='right', fill='both', expand=1)


#-----------------------------
app = Application()
app.mainloop()

EDIT:

import tkinter as tk

#-----------
class LeftFrame(object):
    def __init__(self, frame):
        self.f = frame
        self.ent_data = tk.Entry(self.f, width=8, bg='#3de',fg='#dff')
        self.ent_data.grid(column=0, row=1)

#-----------
class RightFrame(object):
    def __init__(self, frame):
        self.f = frame
        self.transf_button = tk.Button(self.f, text="Transfer to...",
                                       bg='#489', fg='#dff',
                                       command=self.transferTo)
        self.transf_button.grid(column=0, row=1)

    def transferTo(self):
        self.ent_data_st = self.f.master.for_left_frame.ent_data.get()
        print('Transfer to...', self.ent_data_st)

#-----------
class Application(tk.Tk):
    def __init__(self):
        super().__init__()

        frame1 = tk.Frame(self)
        frame2 = tk.Frame(self)

        self.for_left_frame = LeftFrame(frame1)
        self.for_right_frame = RightFrame(frame2)

        frame1.pack()
        frame2.pack()


#-----------------------------
app = Application()
app.mainloop()


来源:https://stackoverflow.com/questions/64291845/i-cant-organize-interaction-between-two-classes-belonging-to-different-frames

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!