Multithreading 单tkinter按钮可实现多功能

Multithreading 单tkinter按钮可实现多功能,multithreading,button,python-2.7,tkinter,Multithreading,Button,Python 2.7,Tkinter,我试图实现一个tkinter按钮,它应该在远程服务器中跟踪一些日志文件。它还应该在本地停止进程,并在第二次单击远程尾部进程时终止该进程。我试着不使用tkinter,但成功了。当按下ctrl c时,tkinter停止 单击tailbutton3按钮时,它将挂起并等待作业完成。在此之前,它不会接受任何新事件。我知道tkinter是单线程的,我相信这是导致问题的原因。代码如下,感谢您的帮助 from Tkinter import * from re import * import paramiko i

我试图实现一个tkinter按钮,它应该在远程服务器中跟踪一些日志文件。它还应该在本地停止进程,并在第二次单击远程尾部进程时终止该进程。我试着不使用tkinter,但成功了。当按下ctrl c时,tkinter停止

单击tailbutton3按钮时,它将挂起并等待作业完成。在此之前,它不会接受任何新事件。我知道tkinter是单线程的,我相信这是导致问题的原因。代码如下,感谢您的帮助

from Tkinter import *
from re import *
import paramiko
import time
import select


class MyApp:
    def __init__(self, parent):
                self.myParent = parent   
                self.myContainer1 = Frame(parent,width=500,height=500)
                self.myContainer1.pack()
   #------------------ LABEL  #1 for MAC ------------------------------------               
        #mac label field
                self.label = Label (self.myContainer1, text='enter MAC').pack(side=TOP,padx=10,pady=10)
   #------------------ ENTRY FIELD  #1 for MAC ------------------------------------    
        #mac entry field
                mac_var=StringVar()
                self.entry = Entry(self.myContainer1,textvariable= mac_var ,width=10)
                self.entry.pack(side=TOP,padx=100,pady=10)
                mac_var.set("XXXXX")
                s=mac_var.get()




   #------------------ LABEL  #2 for MAC OWNER ------------------------------------                
        #name label field
                self.label = Label (self.myContainer1, text='enter MAC owner').pack(side=TOP,padx=10,pady=10)
   #------------------ ENTRY  #2 for MAC OWNER ------------------------------------     
        #name entry field
                name_var=StringVar()
                self.entry = Entry(self.myContainer1,textvariable= name_var ,width=25)
                self.entry.pack(side=TOP,padx=100,pady=10)
                name_var.set("name surname")
                s=name_var.get()




         #------------------ BUTTON #3 ------------------------------------      

        # event binding
                self.button3 = Button(self.myContainer1)
                self.button3.bind("<Button-1>", self.button3Click)
                self.button3.configure(text="tail", background="purple")
                self.button3.pack(side=LEFT)





    def button3Click(self, event):  
        if self.button3["background"] == "purple":
            self.button3.configure(text="Cancel Tail", background="yellow")
            self.tail_flag=True
            print "tail_flag is" , self.tail_flag
            self.taillogg()
        else:
            self.button3.configure(text="Tail", background="purple")
            self.canceltaillogg()
            #root.destroy()

    def canceltaillogg(self):
        self.tail_flag=False
        print "tail_flag is" , self.tail_flag

    def taillogg(self):
        server, port, username, password = ('myserver', 22, 'root', 'passw')
        paramiko.util.log_to_file("C:\\log_transport_paramiko.txt")
        nbytes = 100
        trans = paramiko.Transport((server, port))
        trans.connect(username = username, password = password)
        trans.set_keepalive(1) # when ssh dies (with Ctrl C) processes spawned by that ssh connections will die, too ( in one sec)
        sess = trans.open_channel("session")
        #Once the channel is established, we can execute only one command.
        #To execute another command, we need to create another channel
        sess.exec_command('tail -f /usr/local/var/log/radius/radius.log')
        timeout = 10
        timestart       =time.time()
        while True:
           try:
               rl, wl, xl = select.select([sess],[],[],0.0)
               if len(rl) > 0:   #stdout
                   print sess.recv(1024)
                   if  time.time()-timestart > timeout or self.tail_flag==False :
                        print "timeout 30 sec"
                        trans.close()
                        sess.close()
                        break
           except KeyboardInterrupt :
               print("Caught Control-C")
               trans.close()
               sess.close()
               break


           """if self.tail_flag==False:
               break"""



print ("\n")*100 # clear the screen
print "Starting program"                               
root = Tk()
root.title('MAC REGISTRATION APPLET')
myapp = MyApp(root)
print ("Ready to start executing the event loop.")
root.mainloop()
print ("Finished       executing the event loop.")

试试这个-看看它是否给你想要的行为

self.button3.bind("<Button-1>", lambda:self.root.after(0, self.button3Click)

然后,您需要从button3Click函数中删除事件参数,因为按钮回调不接收任何参数。

这没有什么区别。当按下tail时,直到超时,它才接受任何新的点击。
self.button3 = Button(self.myContainer1, command=lambda:self.root.after(0, self.button3Click))
# self.button3.bind("<Button-1>", self.button3Click)  (don't need this)