我正在尝试实现一个tkinter按钮,它应该“尾随-f”远程服务器中的某些日志文件。它还应该在本地停止进程并在第二次单击时终止远程尾进程。我试过这个没有使用tkinter成功。当按下ctrl c时停止。
单击尾部(按钮3)按钮时,它会挂起并等待作业完成。在此之前它不接受任何新事件。我知道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.")
答案 0 :(得分:1)
试试这个 - 看看它是否能满足你的需要。
self.button3.bind("<Button-1>", lambda:self.root.after(0, self.button3Click)
此外,这是不相关的,但您不必在按钮上调用“bind” - 它具有一个名为command
的内置回调属性:
self.button3 = Button(self.myContainer1, command=lambda:self.root.after(0, self.button3Click))
# self.button3.bind("<Button-1>", self.button3Click) (don't need this)
然后你会想要从event
函数中删除button3Click
参数,因为按钮回调没有收到任何参数。