如何从另一个类 - Python - tkinter正确访问类的StringVar()

时间:2018-05-25 16:03:02

标签: python python-3.x tkinter

(我正在使用mac 10.8.5和Python3与PyCharm)

我有一个tkinter GUI TestMain()类加一个PageOne()类和一个PageTwo()类。 我需要PageOne()PageTwo()作为不同的GUI窗口,因为它们将处理不同的数据。 我最小化了代码,以便将其设置为尽可能可读。 经过多次测试后,我尝试将tk.StringVar()和一个简单的函数放在全局范围内,如下所示,但仍然存在问题。

import tkinter as tk

page1_label = tk.StringVar()
page2_entry = tk.StringVar()

def set_ebdata():
    data = page2_entry.get()
    page1_label.set(data)


class TestMain(tk.Tk):

    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)

        tk.Tk.wm_title(self, 'TEST GUI')
        container = tk.Frame(self)
        container.pack(side='top')
        container.grid_rowconfigure(0, weight=1)
        container.grid_columnconfigure(0, weight=1)
        self.frames = {}
        for F in (PageOne, PageTwo):
            frame = F(container, self)
            self.frames[F] = frame
            frame.configure(background='lightgrey')
            frame.grid(row=0, column=0, sticky='nswe')
        self.show_frame(PageOne)

    def show_frame(self, cont):
        frame = self.frames[cont]
        frame.tkraise()


class PageOne(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)

        frame_eb_data = tk.Frame(self, width=100, height=100, bg="orange", colormap="new")
        frame_eb_data.grid(row=0, column=0, sticky='w', padx=5, pady=5)
        frame_but_right = tk.Frame(self, width=240, height=60, bg="yellow", colormap="new")
        frame_but_right.grid(row=0, column=1, padx=5, pady=5, rowspan=2)
        lab_eb_data = tk.Label(frame_eb_data, background='#DDD4EF', textvariable=page1_label)
        lab_eb_data.grid(row=0, column=0, sticky='n')

        b_ebdata = tk.Button(frame_but_right, text="Page 2", width=10, height=2, command=lambda: controller.show_frame(PageTwo))
        b_ebdata.grid(row=3, column=0)


class PageTwo(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)

        frame_buttons = tk.Frame(self, width=455, bg="#DDD4EF", colormap="new")
        frame_buttons.grid(row=0, column=0, padx=5, pady=5, sticky='e')
        frame_up_left = tk.Frame(self, width=485, height=260, bg="#89E3FA", colormap="new")
        frame_up_left.grid(row=1, column=0, sticky='w', padx=5, pady=5)

        b_data = tk.Label(frame_buttons, text='Example GUI', font='TrebuchetMS 30 bold', background="#DDD4EF")
        b_data.grid(row=0, column=0, padx=13, pady=5, sticky='w')

        b5 = tk.Button(frame_buttons, text='Set Text', command=lambda: set_ebdata)
        b5.grid(row=0, column=2, padx=5, pady=5, sticky='e')

        b6 = tk.Button(frame_buttons, text='Page 1', command=lambda: controller.show_frame(PageOne))
        b6.grid(row=0, column=3, padx=5, pady=5, sticky='e')

        label_2 = tk.Label(frame_up_left, text="Name:", font=("bold", 14))
        label_2.grid(row=1, column=0, sticky='e')
        entry_nombre_fld = tk.Entry(frame_up_left, width=40, textvariable=page2_entry)
        entry_nombre_fld.grid(row=1, column=1, columnspan=3, sticky='w')


app = TestMain()

app.mainloop()

当您运行程序时,会出现一个带有“Page 2”按钮(b_ebdata)的窗口,通过单击它可以进入具有“设置文本”按钮(b5)的窗口, “第1页”按钮(b6)和输入字段(entry_nombre_fld)。

我想通过点击“设置文字”按钮({{1)设置我将在第1页标签(entry_nombre_fld)的输入字段(lab_eb_data)中输入的文字。 }})。

解决方案是将b5放入page1_label = tk.StringVar()课程,将PageOne()放入page2_entry = tk.StringVar()课程,并让他们互相访问吗?

还有其他建议吗?

提前帮助你!

1 个答案:

答案 0 :(得分:0)

我不得不改变一些事情,但在大多数情况下,主要的解决方案是将controller移到主要课程中。接下来我们可以使用其他2个类中的controller参数来操作数据。

我在第2页添加了一个函数来处理更新标签StringVar。 因此我删除了你的另一个功能。

我必须将您的输入字段更改为类属性,以便我们可以在新方法中使用其内容。我还必须在第2页中为import tkinter as tk class TestMain(tk.Tk): def __init__(self, *args, **kwargs): tk.Tk.__init__(self, *args, **kwargs) self.title('TEST GUI') # Moved StringVar()'s to the main class self.page1_label = tk.StringVar() self.page2_entry = tk.StringVar() container = tk.Frame(self) container.pack(side='top') container.grid_rowconfigure(0, weight=1) container.grid_columnconfigure(0, weight=1) self.frames = {} for F in (PageOne, PageTwo): frame = F(container, self) self.frames[F] = frame frame.configure(background='lightgrey') frame.grid(row=0, column=0, sticky='nswe') self.show_frame(PageOne) def show_frame(self, cont): frame = self.frames[cont] frame.tkraise() # Deleted this function class PageOne(tk.Frame): def __init__(self, parent, controller): tk.Frame.__init__(self, parent) frame_eb_data = tk.Frame(self, width=100, height=100, bg="orange") frame_eb_data.grid(row=0, column=0, sticky='nsew', padx=5, pady=5) frame_but_right = tk.Frame(self, width=240, height=60, bg="yellow") frame_but_right.grid(row=1, column=0, padx=5, pady=5, sticky='nsew') lab_eb_data = tk.Label(frame_eb_data, background='#DDD4EF', textvariable=controller.page1_label) lab_eb_data.grid(row=0, column=0) b_ebdata = tk.Button(frame_but_right, text="Page 2", width=10, height=2, command=lambda: controller.show_frame(PageTwo)) b_ebdata.grid(row=0, column=0) class PageTwo(tk.Frame): def __init__(self, parent, controller): tk.Frame.__init__(self, parent) # Added the self.controller so the method below can use it. self.controller = controller frame_buttons = tk.Frame(self, width=455, bg="#DDD4EF", colormap="new") frame_buttons.grid(row=0, column=0, padx=5, pady=5, sticky='e') frame_up_left = tk.Frame(self, width=485, height=260, bg="#89E3FA", colormap="new") frame_up_left.grid(row=1, column=0, sticky='w', padx=5, pady=5) b_data = tk.Label(frame_buttons, text='Example GUI', font='TrebuchetMS 30 bold', background="#DDD4EF") b_data.grid(row=0, column=0, padx=13, pady=5, sticky='w') b5 = tk.Button(frame_buttons, text='Set Text', command= self.update_p2_label) b5.grid(row=0, column=2, padx=5, pady=5, sticky='e') b6 = tk.Button(frame_buttons, text='Page 1', command=lambda: controller.show_frame(PageOne)) b6.grid(row=0, column=3, padx=5, pady=5, sticky='e') self.entry_nombre_fld = tk.Entry(frame_up_left, width=40) self.entry_nombre_fld.grid(row=1, column=1, columnspan=3, sticky='w') label_2 = tk.Label(frame_up_left, text="Name:", font=("bold", 14)) label_2.grid(row=1, column=0, sticky='e') # Added this function to update the page1_label StringVar. def update_p2_label(self): self.controller.page1_label.set(self.entry_nombre_fld.get()) app = TestMain() app.mainloop() 创建一个类属性,这样我们也可以在方法中使用控制器。

现在可能有一种更简单的方法,但这是我用你的代码管理的。

{{1}}