从Tkinter中的函数中的变量中获取正确的值

时间:2016-06-01 03:33:46

标签: python function variables tkinter

这可能是一个简单的问题,与存储在字典中的变量如何在函数中给出值有关。

我正在尝试获取布尔变量的值,我将其存储在我在下面的代码中设置为(self.controller.Page1_data["Step1Complete"])的字典"True"中。

#!/usr/local/bin/env python3
import tkinter as tk   # python3
from tkinter import BooleanVar

TITLE_FONT = ("Helvetica", 18, "bold")

class SampleApp(tk.Tk):

    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
        container = tk.Frame(self)
        container.pack(side="top", fill="both", expand=True)
        container.grid_rowconfigure(0, weight=1)
        container.grid_columnconfigure(0, weight=1)      
        self.Page1_data={"Step1Complete": BooleanVar()}          
        self.frames = {}
        for F in (StartPage, PageFifteen): 
            page_name = F.__name__
            frame = F(container, self)
            self.frames[page_name] = frame
            frame.grid(row=0, column=0, sticky="nsew")          
        self.show_frame("StartPage")

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

class StartPage(tk.Frame):

     def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller
        controller.title("Part B Data Collection")
        controller.geometry("600x500")
        label = tk.Label(self, text="Welcome to the Part B Test!", font=TITLE_FONT)
        label.pack(side="top", fill="x", pady=10)
        button1 = tk.Button(self, text="Complete Step 1", command=self.MakeStep1Complete)
        button1.place(relx=0.385, rely=0.65)

    def MakeStep1Complete(self):

        Step1Complete=True
        self.controller.Page1_data["Step1Complete"]=Step1Complete
        self.controller.show_frame("PageFifteen")




class PageFifteen(tk.Frame):



    def StatusCheck(self):
        Step1Complete=self.controller.Page1_data["Step1Complete"]
        print("True or false: at Step 15, Step 1 completed -a ")
        print(Step1Complete)




    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller
        label = tk.Label(self, text="Check the data", font=TITLE_FONT)
        label.pack(side="top", fill="x", pady=10)

        self.StatusCheck()

        tk.Label(self, text="Click on each of the buttons below to review the data you have inputted").place(relx=0.15, rely=0.12)  

        Step1Complete=self.controller.Page1_data["Step1Complete"].get()
        print("True or false: at Step 15, Step 1 completed - b")
        print(Step1Complete)

        button17=tk.Button(self, text="Check if we did everything", 

command=self.StatusCheck)
        button17.place(relx=0.7, rely=0.75)        

    if __name__ == "__main__":
        app = SampleApp()
        app.mainloop()

当我执行上述(现在根据Florent的建议编辑)代码时,我得到以下结果:

True or false: at Step 15, Step 1 completed -a 
False
True or false: at Step 15, Step 1 completed - b
False
True or false: at Step 15, Step 1 completed -a 
True

第一个结果是第一次执行StatusCheck函数,我只是调用函数。第二个结果来自于我明确执行应该(但没有)获得正确布尔数据的命令(Step1Complete=self.controller.Page1_data["Step1Complete"].get())。当用户单击"Check if we did everything"时,会生成第三个结果,也就是获得正确布尔数据的唯一结果,StatusChecktk.Button命令配置选项调用StatusCheck函数。

为什么会发生这种情况?为什么"Step1Complete"函数在第一次执行时不起作用,但第二次执行时它会工作。理想情况下,我希望代码能够立即发现"True"变量已设置为"Step1Complete"而无需用户单击按钮。

我有理由相信这个问题与哪些函数将值写入变量有关,因为当我将"True"设置为__init__时,我能够使程序正常工作。 StartPage类中的9999999999函数。

作为Python N00b,我知道我必须遗漏一些非常明显的东西,但我真的很感激你能提供的任何帮助。

1 个答案:

答案 0 :(得分:1)

答案的简短版本是:当您使用tkinter变量时,您需要使用set和get函数来访问变量的值。同样在一个不相关的问题中,在一个类中,你不需要在调用它之前定义一个函数,最好在你的类之上使用__init__(参见类PageFifteen)。

现在,专门针对您的代码以及获取这些打印的原因: 目前,在创建PageFifteen Frame时调用2次打印:

  • 在第一个打开时,你打印一个tk.BooleanVar,它给你的句柄而不是它的值(var.get()打印值)
  • 在第二个中,你正确使用get()并打印你的var的当前值(这是BooleanVar的默认值:False)

然后你显示StartPage,点击按钮,你用bool True覆盖你的Booleanvar,这就是为什么你的最后一个StatusCheck在没有get的情况下工作的原因。

在您的代码中,您需要替换:

def StatusCheck(self):
    Step1Complete=self.controller.Page1_data["Step1Complete"]
    print("True or false: at Step 15, Step 1 completed -a ")
    print(Step1Complete)by

由:

def StatusCheck(self):
    Step1Complete=self.controller.Page1_data["Step1Complete"].get()    
    print("True or false: at Step 15, Step 1 completed -a ")
    print(Step1Complete)

def MakeStep1Complete(self):
    Step1Complete=True
    self.controller.Page1_data["Step1Complete"]=Step1Complete
    self.controller.show_frame("PageFifteen")

由:

def MakeStep1Complete(self):
    Step1Complete=True
    self.controller.Page1_data["Step1Complete"].set(Step1Complete)
    self.controller.show_frame("PageFifteen")