2017-06-23 115 views
0

我有一個程序需要一個對話框來詢問輸入字符串,該字符串存儲在一個global變量中;目前,我正在使用一個Toplevel窗口作爲主要Tk窗口的子窗口來執行此操作。問題是global變量被改變(這個工作,我在回調方法中檢查),但是一旦我在Toplevel窗口上調用destroy,值就不會保留。tkinter tk /頂層執行暫停回調的執行?

from Tkinter import * 

class GUI: 
    def __init__(self): 
     """initialization""" 
     # widgets 

     self.window = Tk() 

     get_string = Button(
      self.window, 
      command = self.on_get_string, 
      text = "Open string" 
      ) 

     # pack the widgets 

     get_string.pack() 
     return 

    def main(self): 
     """the main method""" 
     self.window.mainloop() 
     return 

    def on_get_string(self, event = None): 
     """open the string window""" 
     prompt = PromptString() # a dialog which prompts for a string 

     print str(prompt.string) # None 
     prompt.main() 
     print str(prompt.string) 
     return 

class PromptString: 
    def __init__(self): 
     """initialization""" 
     self.string = None # the string 

     # widgets 

     self.window = Toplevel() 

     self.input = Entry(self.window) 
     self.input.bind("<Return>", self.on_set_string) 

     set_button = Button(
      self.window, 
      command = self.on_set_string, 
      text = "Set" 
      ) 

     # pack the widgets 

     self.input.pack(side = LEFT) 
     set_button.pack(side = RIGHT) 
     return 

    def main(self): 
     """the main method""" 
     self.window.mainloop() # execution pauses after this line finishes 
     return 

    def get_input(self): 
     """get the input""" 
     return self.input.get() 

    def on_set_string(self, event = None): 
     """set the string variable and close the window""" 
     self.string = self.get_input() 
     self.window.destroy() 
     return 

GUI().main() 

它吃了我,我不能解決這個問題,但任何幫助,將不勝感激,我感謝你提前。

編輯:

我的混亂表示歉意,但我居然重現該錯誤這段時間,雖然它沒有那麼多的錯誤是一個問題。問題是程序的執行在第39行的prompt.main()調用中暫停。我嘗試點擊並輸入2個後續值,其中Tk實例關閉後以相反順序打印。這是否暫停執行Tkinter的產品?我怎樣才能解決這個問題?

EDIT 1:

在考慮中的變量不是全球性的,但PromptString類的屬性。

+1

您的代碼只是運行,然後很快就退出。你期望看到什麼發生?到'run_top'後面的時候,200ms將會過去,'var.set'在程序退出之前可能還沒有被調用過。 –

+0

保羅魯尼是對的。您可以通過在'run_tk()'函數中更改語句'tk.after(1000,run_top)'和'tk.after(2000,tk.destroy)'來減慢速度來證明它。之後,你的代碼將工作。另請注意,'global var'不會執行模塊級別的任何操作,並且可以省略。 – martineau

+1

如果您發佈的代碼不正確,那麼可以更改它,但是不要留下任何東西都無濟於事。你現在已經使我的回答毫無意義,並且沒有任何例子可以幫助你進行調試。請參閱[mcve]。 –

回答

0

解決方法是使用Tkwait_window(other_window)方法。這允許執行不會被Tkinter的執行結構暫停。固定代碼如下:

from Tkinter import * 

class GUI: 
    def __init__(self): 
     """initialization""" 
     # widgets 

     self.window = Tk() 

     get_string = Button(
      self.window, 
      command = self.on_get_string, 
      text = "Open string" 
      ) 

     # pack the widgets 

     get_string.pack() 
     return 

    def main(self): 
     """the main method""" 
     self.window.mainloop() 
     return 

    def on_get_string(self, event = None): 
     """open the string window""" 
     prompt = PromptString() # a dialog which prompts for a string 

     print str(prompt.string) # None 
     prompt.wait(self.window) # wait for the prompt 
     print str(prompt.string) 
     return 

class PromptString: 
    def __init__(self): 
     """initialization""" 
     self.string = None # the string 

     # widgets 

     self.window = Toplevel() 

     self.input = Entry(self.window) 
     self.input.bind("<Return>", self.on_set_string) 

     set_button = Button(
      self.window, 
      command = self.on_set_string, 
      text = "Set" 
      ) 

     # pack the widgets 

     self.input.pack(side = LEFT) 
     set_button.pack(side = RIGHT) 
     return 

    def main(self): 
     """the main method""" 
     self.window.mainloop() # execution pauses after this line finishes 
     return 

    def get_input(self): 
     """get the input""" 
     return self.input.get() 

    def on_set_string(self, event = None): 
     """set the string variable and close the window""" 
     self.string = self.get_input() 
     self.window.destroy() 
     return 

    def wait(self, other_window): 
     """run the window as an offshoot of another window""" 
     other_window.wait_window(self.window) 
     return 

GUI().main()