2013-12-17 23 views
1

我已經創建了的Tkinter/Python的十個問題選擇題測驗。我創建了一個類來存儲所有按鈕,然後創建了另外10個類來存儲出現在子窗口中的每個問題,並將問題作爲標籤和單選按鈕/校驗按鈕進行存儲。對於每個問題,當用戶按下「回車」時,程序會將他們的選擇與正確的回答者進行比較,並在必要時增加1分以得分。我如何讓變量'Score'可用於程序中的所有內容(即每個類)?我是否必須在課程之間傳遞分數值?如何在tkinter中的類之間傳遞值?

class Question_5_Window(tk.Toplevel): 
    '''A simple instruction window''' 
    def __init__(self, parent): 
     tk.Toplevel.__init__(self, parent) 
     self.text = tk.Label(self, width=100, height=4, text = "5) What would you do if you were walking to class and you saw a first year crying? Tick all correct answers.") 
     self.text.pack(side="top", fill="both", expand=True) 

     question_5_Var1 = IntVar() 
     question_5_Var2 = IntVar() 
     question_5_Var3 = IntVar() 

     A_5 = Checkbutton(self, text = "Keep walking", variable = question_5_Var1, onvalue = 1, offvalue = 0, height=5, width = 20) 
     A_5.pack() 

     B_5 = Checkbutton(self, text = "Take them to guidance", variable = question_5_Var2, onvalue = 1, offvalue = 0, height=5, width = 20) 
     B_5.pack() 

     C_5 = Checkbutton(self, text = "Talk to them to resolve issue", variable = question_5_Var3, onvalue = 1, offvalue = 0, height=5, width = 20) 
     C_5.pack() 

     def calculate_score(): 

      if (question_5_Var2.get() == 1) and (question_5_Var3.get() == 1) and not question_5_Var1.get(): 
       print("calculate score has worked") 
       score = score + 1 
      else: 
       print("not worked") 

      return score 

     Enter_5 = Button(self, text= "Enter", width=10, command = calculate_score) 
     Enter_5.pack() 

     return score 
+0

你有任何示例代碼? – Ffisegydd

+0

是的,我已經編輯了問題 – user3056786

+0

@ user3056786我認爲這是要採取一些討論/修改/編輯。誰想要幫忙,也許你可以使用[此聊天室](http://chat.stackoverflow.com/rooms/43338/how-do-i-pass-a-value-between-classes-in-tkinter) 。 – KobeJohn

回答

4

根據我們的討論,最快捷的方法是將tk對象中包含問題按鈕的屬性添加到您的tk對象中。

class WhateverContainer(tk.Frame): 
    def __init__(self) # ... *args, **kwargs or whatever is appropriate 
     # ... other stuff 
     self.scores = dict() # common storage 

class Question(tk.TopLevel): 
    def __init__(self, parent, question_id): # ... whatever arguments 
     # ... 
     def callback() 
      if nice_answer: 
       parent.scores[question_id] = 1 

需要明確的是,這不是一個「好」的解決方案,因爲至少,子窗口不應該直接與父的數據搞亂。但是,我認爲它適用於您的應用程序。如果你想獲得關於你的設計和編碼的反饋,你可能會在CodeReview上碰運氣。

我希望測驗很適合你。

0

另一種完成此操作的方法是在主模塊中聲明一個Tkinter控制變量(在你的情況下是一個IntVar,因爲它處理測驗分數),然後使這個相同的控制變量成爲需要的每個類的屬性分享/更新它。當你這樣做時,每個類都可以使用IntVar的get/set方法,並且所有更新都會傳遞給其他類(以及主模塊)。

我寫了一個簡短的演示程序中,我稱之爲「絆網」,以證明自己是這個工程:

import Tkinter as tk 

#Clumsy thief who crosses the tripwire 
#The twVar is a Tkinter IntVar 
class Thief1: 
    def __init__(self,twVar): 
     self.twVar = twVar 

    def cross(self): 
     self.twVar.set(1) 

#Second thief who silences the alarm 
#The twVar here is the same one as Thief1 
class Thief2: 
    def __init__(self,twVar): 
     self.twVar = twVar 

    def silence(self): 
     self.twVar.set(0) 

#Main module 
root = tk.Tk() 

#Declare and initialize the IntVar 
ctrlTW = tk.IntVar() 
ctrlTW.set(0) 

#Instantiate each class, using the same 
#IntVar for each 
t1 = Thief1(ctrlTW) 
t2 = Thief2(ctrlTW) 

#Now call each thief's method 
print 'Initial value: '+str(ctrlTW.get()) 
t1.cross() 
print 'After Thief #1: '+str(ctrlTW.get()) 
t2.silence() 
print 'After Thief #2: '+str(ctrlTW.get()) 

該技術的一個偏涼的好處是,你可以使用控制變量的觀察員執行的回調每當任何類都對值做些什麼的時候。這(部分)解決了科比約翰關於讓孩子的窗戶與父母的數據混淆的擔憂。回調允許主模塊至少監視每個類正在處理的共享數據並作出相應的反應。

#Main module with trace and callback added 
root = tk.Tk() 

def twObserve(*args): 
    if (ctrlTW.get()): 
     print 'Hey! Intruder detected!' 
    else: 
     print 'Oh... never mind.' 

#Declare and initialize the IntVar 
ctrlTW = tk.IntVar() 
ctrlTW.set(0) 

#Set the callback for updates 
ctrlTW.trace('w',twObserve) 

#Instantiate each class, using the same 
#IntVar for each 
t1 = Thief1(ctrlTW) 
t2 = Thief2(ctrlTW) 

#Now call each thief's method. The callback 
#will activate with each update. 
t1.cross() 
t2.silence()