0

リモートサーバーのログファイルを「tail -f」する単一のtkinterボタンを実装しようとしています。また、プロセスをローカルで停止し、2 回目にクリックしたときにリモートのテール プロセスを強制終了する必要があります。tkinter を使用せずにこれを試してみましたが、ctrl c が押されると停止します。

tail(button3) ボタンをクリックするとハングし、ジョブが完了するのを待ちます。それまで新しいイベントは受け付けていません。私は 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.")
4

1 に答える 1

1

これを試してみてください - それがあなたの望む動作をするかどうか見てください.

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

また、これは関係ありませんが、ボタンで「バインド」を呼び出す必要はありません。次のコールバック属性が組み込まれています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

于 2013-08-15T16:45:33.957 に答える