2014-03-12 62 views
0

,所以我有一个程序,是做如下:不允许功能,使Tk的GUI杭

  1. 连接到我的MySQL数据库,并提取某些表IP地址 在
  2. 店地址名单
  3. 在列表中的每个IP,depeding用户偏好,通过套接字,我发送或接收的文件到该IP地址

因此,可以说,我有一个发送()函数,即开始时的IP RESS从另外一个功能按钮,它做到这一点:

for host in IP_list: 
    socket.connect((host,5005))... 
    socket.send(data)... 

现在,当服务器处于活动状态,代码的作品,一切都拷贝速度非常快。 但是,目前我正在进行代码轮询,并且当服务器没有启动,并且客户端无法连接时,代码执行速度很慢,并且GUI挂起(例如,列表中有25个IP-s需要连接到该功能)。

所以我想要做的是socket.connect((host,5005))在另一个线程(或任何不挂我的GUI)

现在,我试图与线程,但它的行为古怪。它从来没有与tkinter很好,因为除了上面的代码行,我有tk.progressbar和在该函数中的其他几个Tk的东西。

我不知道如何处理多处理,显然它对IO挂起没有影响。

谁能为我提供一些想法?

这里是我试图与线程:

def connect(): 
    global host 
    global socket 
    socket.connect((host,5005)) 


def my_original_function(): 
    global host 
    global socket 
    t1=threading.Thread(target=connect) 
    for host in IP_list: 
     t1.start() 
     t1.join() 
+0

你能告诉我们你是如何尝试使用线程吗? –

+0

已更新的主要帖子 – sale1902

回答

0

这是比较简单的,开始在多超过一两件事。我通常把所有的东西都放在一个班级里,以保持连接。一个警告是只创建一个TK()类实例。不止一个会导致问题。 time.sleep()用于start_running函数,而不是after()模拟一个线程挂起。如果你打算使用Tkinter并进入更高级的编程,使用类将简化你的生活恕我直言。

from multiprocessing import Process 
import time 

try: 
    import Tkinter as tk ## Python 2.x 
except: 
    import tkinter as tk ## Python 3.x 

class ProgressBar(): 
    def __init__(self, root): 
     self.root=root 
     self.root.geometry("75x50+900+100") 
     self.ctr=25 

    def mainloop(self): 
     self.root.mainloop() 

    def start_countdown(self): 
     """ a separate process in a separate GUI 
     """ 
     self.root.withdraw() 
     self.top_count=tk.Toplevel(self.root) 
     self.top_count.geometry("75x50+750+50") 
     self.label_ctr = tk.IntVar() 
     self.label_ctr.set(self.ctr) 
     label = tk.Label(self.top_count, textvariable=self.label_ctr) 
     label.pack() 
     if self.ctr > 0: 
      self.top_count.after(750, self.update) 

    def start_running(self): 
     """ create the progress bar widget 
     """ 
     self.top=tk.Toplevel(self.root, takefocus=True) 
     self.top.title("Progress Bar") 
     self.top.geometry("+700+200") 
     canvas = tk.Canvas(self.top, width=261, height=60, bg='lightgray') 
     canvas.pack() 

     rc2 = canvas.create_rectangle(15, 20, 243, 50, outline='blue',          fill='lightblue') 
     rc1 = canvas.create_rectangle(24, 20, 34, 50, outline='white',          fill='blue') 

     total=100 
     x = 5 
     ## only use after() while the countdown is running (self.ctr > 0) 
     ## to avoid a dangling after() when the program terminates 
     while self.ctr:  ## move the small rectangle +5 or -5 units 
      total += x 
      if total > 311: 
       x = -5 
      elif total < 100: 
       x = 5 
      time.sleep(0.2) 
      canvas.move(rc1, x, 0) 
      canvas.update() 

    def update(self): 
     self.ctr -= 1 
     self.label_ctr.set(self.ctr) 

     if self.ctr > 0: 
      self.top_count.after(750, self.update) 
     else: 
      ## sleep to allow any remaining after() to execute 
      ## can also use self.root.after_cancel(id) 
      self.top_count.after(500, self.root.destroy) ## destroy root when ctr==0 

root = tk.Tk() 

PB=ProgressBar(root) 
pr1=Process(target=PB.start_countdown(), args=()) 
pr1.start() 

pr2=Process(target=PB.start_running(), args=()) 
pr2.start() 

## start mainloop in a separate process as a function of the class 
## don't know if this is really necessary or not 
## the theory is, it is detached from the other 2 processes and so 
## can react to both independently 
## also the mainloop() process can be killed=shut down properly 
pr3=Process(target=PB.mainloop(), args=()) 
pr3.start() 

## safety clean up 
pr1.terminate() 
pr2.terminate() 
pr3.terminate()