2016-06-01 3 views
0

Это, вероятно, простая проблема, связанная с тем, как переменные, хранящиеся в словаре, задаются значениями внутри функции.Получение правильных значений из переменных в функциях в 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() 

Когда я исполняю выше (теперь отредактированный за предложения Флорана в) код, я получаю следующие результаты:

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", который вызывает функцию StatusCheck из опции конфигурации команды tk.Button.

Почему это может случиться? Почему функция StatusCheck не работает в первый раз, когда я ее выполняю, но потом работаю во второй раз, когда я ее выполню. В идеале, я хотел бы, чтобы код сразу обнаружил, что переменная "Step1Complete" установлена ​​в "True" без нажатия на кнопку.

У меня есть основания полагать, что эта проблема имеет что-то делать, с которой функция записи значений переменных, так как я могу правильно сделать работу программы, когда я установил "Step1Complete" к "True" в функции __init__ в StartPage классе.

Будучи Python N00b, я знаю, что я должен упустить что-то довольно очевидное, но я очень ценю любую помощь, которую вы могли бы предоставить.

+0

Отступ вашего кода сломан. Методы не вложены внутри определения класса. –

+0

Брайан, я просто исправил форматирование. – CJG

ответ

1

Короткий вариант ответа таков: когда вы используете переменные tkinter, вам нужно использовать set и get функции для доступа к значению переменных. Также в несвязанной проблеме, в классе вам не нужно определять функцию перед ее вызовом, и лучше иметь __init__ поверх вашего класса (cf class PageFifteen).

Теперь, специально для вашего кода и почему вы получите эти отпечатки: в настоящее время, вы называете 2 отпечатки при создании PageFifteen Рама:

  • в первом, вы распечатайте tk.BooleanVar, который дает вы его дескриптор, а не его значение (var.get(), чтобы напечатать значение)
  • во втором, вы правильно используете get() и распечатаете текущее значение вашего var (которое является значением по умолчанию для BooleanVar: False)

Затем вы показываете StartPag e, нажмите на кнопку, и вы перезапишите свой Booleanvar с помощью bool True, поэтому ваш последний 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") 
+0

Привет Florent. Я внедрил ваши предложенные изменения и теперь получаю следующий вывод: True или false: на шаге 15, шаг 1 завершен - a False Теперь мой вопрос: почему команда .set(), похоже, не изменяет значение «Step1Complete» от False до True? – CJG

+0

Просто подумал: будет ли StatusCheck возвращать значение «Step1Complete»? – CJG

+0

С внесенными вами изменениями вы должны получить следующие ответы: False, False, True. Если вы не хотите первого False, вам просто нужно подавить self.StatusCheck() из вашего \ __ init__. или инициализировать self.Page1_data ["Step1Complete"] как True, используя self.Page1_data ["Step1Complete"] .set (True) в функции \ __ init__ SampleApp. В настоящее время он установлен в значение True, только когда вы нажимаете кнопку17 – Florent

Смежные вопросы