当我在while循环中在后台运行某些东西时,UI在Tkinter中冻结

时间:2016-03-17 05:28:41

标签: multithreading python-2.7 tkinter

我知道很多次都会问过这个问题。不幸的是,没有一个答案能解决我的目的。我有一个代码,它将在while循环中持续ping并检查连接。应该实例化ping的频率来自用户。除非用户关闭应用程序,否则此ping将永远不会结束。

我有两个类,一个用于UI,另一个用于要完成的操作。

以下是示例代码。

class Net:

     def main(self,interval):

        try:
           while thread1.is_alive():
                 p = subprocess.Popen("Do something like ping",
                                      stdout = PIPE, 
                                      stderr = PIPE)  #--> This is definitely required

        except KeyboardInterrupt as e:
                 print "Exiting", e



class UI:

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

         tk.Tk.__init__(self, *args, **kwargs)

         self.wm_title("Network Test")
         self.geometry('250x75')
         self.resizable(width = False, height = False)

         self.label = tk.Label(text = "Frequency(seconds)")
         self.label.grid(row = 0, column = 0)

         self.entry = tk.Entry(bd = 5)
         self.entry.grid(row = 0, column = 1)

         self.button = tk.Button(text = "Start Test", command = self.callthread)

         self.button.grid(row = 1, column = 0)

         self.button1 = tk.Button(text = "Stop Test")
         self.button1.grid(row = 1, column = 1)

         self.mainloop()

   def callthread(self):

       print "Inside Call thread"

       n = NetTest()
       thread2 = threading.Thread(target = n.main(int(self.entry.get())))
       #thread2.setDaemon(True)
       thread2.start()


if __name__ == "__main__":

    thread1 = threading.Thread(target = MyUI)

    thread1.start()
    #print threading.activeCount()

我尝试在线程中运行它们但是徒劳无功。也许我错误地实现了线程。应用程序执行它应该执行的操作。唯一的问题是UI挂起,而它确实。我也尝试过使用。这也没有帮助。非常感谢任何帮助。

TIA

1 个答案:

答案 0 :(得分:0)

我已经找到了问题。问题是,我没有从run方法()调用main方法。此示例可能对尝试使用Tkinter实现线程的人有帮助,以便UI不会冻结。

最好的解决方案是继承线程模块并从重写的run方法调用无限循环,如下所示。

class Net(threading.Thread):

   def __init__(self, interval):
     threading.Thread.__init__(self)
     self.interval = interval

   def run(self):

     self.main()

   def main(self,interval):

       try:
         while thread1.is_alive():
             p = subprocess.Popen("Do something like ping",
                                  stdout = PIPE, 
                                  stderr = PIPE)  #--> This is definitely required

       except KeyboardInterrupt as e:
             print "Exiting", e



class UI:

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

     tk.Tk.__init__(self, *args, **kwargs)

     self.wm_title("Network Test")
     self.geometry('250x75')
     self.resizable(width = False, height = False)

     self.label = tk.Label(text = "Frequency(seconds)")
     self.label.grid(row = 0, column = 0)

     self.entry = tk.Entry(bd = 5)
     self.entry.grid(row = 0, column = 1)

     self.button = tk.Button(text = "Start Test", command = self.callthread)

     self.button.grid(row = 1, column = 0)

     self.button1 = tk.Button(text = "Stop Test")
     self.button1.grid(row = 1, column = 1)

     self.mainloop()

   def callthread(self):

       thread2 = Net(self.entry.get())
       thread2.start()


if __name__ == "__main__":

    thread1 = threading.Thread(target = MyUI)
    thread1.start()