首页 > 解决方案 > 如何在 tkinter for python 中保存共享数据?

问题描述

我对使用 Python 的 GUI 世界非常陌生,并试图用多个页面构建我的第一个 GUI,但是从输入框中共享一个变量真的让我陷入了一个循环。我知道代码可能有很多错误,但是现在,我真的只是想更好地了解如何从用户名输入框在页面之间共享变量。

这是与此相关的代码:(分页符只是一些不相关代码的地方)

import tkinter as tk
from tkinter import Tk, Label, Button, StringVar

class Keep(tk.Tk):

    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
        self.shared_data ={
            "email": tk.StringVar(),
            "password": tk.StringVar()
        }
# Skipping some code to get to the good stuff

class StartPage(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller
        # LABELS, ENTRIES, AND BUTTONS

        # page break

        self.entry1 = tk.Entry(self, textvariable=self.controller.shared_data["email"])
        entry2 = tk.Entry(self, show = '*')
        button1 = tk.Button(text="Submit", command=lambda: [controller.show_frame("PageTwo"), self.retrieve()])

    # page break

    def retrieve(self):
        self.email = self.controller.shared_data["email"].get()
        self.controller.email = self.email

class PageTwo(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller
        self.email = self.controller.shared_data["email"].get()

        label1 = tk.Label(self, text="Welcome, {}".format(self.email))

if __name__ == "__main__":
    keep = Keep()
    keep.mainloop()

我知道检索功能看起来很时髦,可能根本不正确,但我已经研究这个特定问题大约一个星期了,它让我陷入了一些野兔洞。

最终目标是为了label1显示,“欢迎,(插入输入的pageTwo电子邮件)”。entry1startPage

我认为我的问题在于pageTwo从 检索空字符串shared_data,但我不明白为什么会这样。

任何帮助都非常感谢!

标签: pythontkinter

解决方案


我猜问题是因为框架是在你运行时创建的Keep.__init__,而不是在你运行时创建的show_frame(),所以PageTwo.__init__()是在开始时执行的,而文本Welcome...是在开始时创建的——甚至在你看到之前StartPage

您应该在其中创建空标签并在其他方法(即。)中__init__创建文本,如果所有类都将具有>Welcome...update_widgets()show_frame()show_frame()update_widgets()


最小的工作代码:

import tkinter as tk


class Keep(tk.Tk):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.shared_data ={
            "email": tk.StringVar(),
            "password": tk.StringVar()
        }

        self.frames = {
            'StartPage': StartPage(self, self),
            'PageTwo': PageTwo(self, self),
        }

        self.current_frame = None
        self.show_frame('StartPage')

    def show_frame(self, name):
        if self.current_frame:
            self.current_frame.forget()
        self.current_frame = self.frames[name]
        self.current_frame.pack()

        self.current_frame.update_widgets() # <-- update data in widgets


class StartPage(tk.Frame):

    def __init__(self, parent, controller):
        super().__init__(parent)
        self.controller = controller

        self.entry1 = tk.Entry(self, textvariable=self.controller.shared_data["email"])
        self.entry1.pack()
        entry2 = tk.Entry(self, show='*')
        entry2.pack()
        button = tk.Button(self, text="Submit", command=lambda:controller.show_frame("PageTwo"))
        button.pack()

    def update_widgets(self):
        pass

class PageTwo(tk.Frame):

    def __init__(self, parent, controller):
        super().__init__(parent)
        self.controller = controller

        self.label = tk.Label(self, text="") # <-- create empty label
        self.label.pack()

    def update_widgets(self):
        self.label["text"] = "Welcome, {}".format(self.controller.shared_data["email"].get()) # <-- update text in label


if __name__ == "__main__":
    keep = Keep()
    keep.mainloop()

推荐阅读