2015-11-30 72 views
0

我知道我可以通過打開兩個終端窗口來手動輕鬆地完成此操作。我試圖通過創建帶有兩個按鈕的GUI來儘可能自動化該過程。一個連接並運行監聽器,另一個運行監聽器。如何在GUI中並行運行兩個非終止腳本?

這是我的代碼:

#python 3 
#from tkinter import * 
#from tkinter import ttk 

#python 2 
from Tkinter import * 
import ttk 

import time 
import subprocess 
import paramiko 

def calculate(*args): 
    try: 
     value = float(feet.get()) 
     meters.set((0.3048 * value * 10000.0 + 0.5)/10000.0) 
    except ValueError: 
     pass 


def connect(): 
    ssh = paramiko.SSHClient() 
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 
    ssh.connect('192.168.1.2', username='pi', password='raspberry') 
    stdin, stdout, stderr = ssh.exec_command('cd') 
    stdin, stdout, stderr = ssh.exec_command('roscore &') 
    time.sleep(20) 
    stdin, stdout, stderr = ssh.exec_command('\n') 
    stdin, stdout, stderr = ssh.exec_command('cd scripts') 
    stdin, stdout, stderr = ssh.exec_command('python /home/pi/scripts/listener2.py') 
    return 

def run(): 
    stdin, stdout, stderr = ssh.exec_command('python ES96_Vivaldi/talker2.py') 


root = Tk() 

mainframe = ttk.Frame(root, padding="3 3 12 12") 
mainframe.grid(column=0, row=0, sticky=(N, W, E, S)) 
mainframe.columnconfigure(0, weight=1) 
mainframe.rowconfigure(0, weight=1) 

ttk.Button(mainframe, text="Connect", command=connect).grid(column=1, row=3, sticky=S) 
ttk.Button(mainframe, text="Run", command=run).grid(column=3, row=3, sticky=S) 

ttk.Label(mainframe, text="Click 'Connect' to establish link.").grid(column=1, row=1, sticky=W) 
ttk.Label(mainframe, text="Click 'Run' to control using the arrow keys").grid(column=1, row=2, sticky=W) 

for child in mainframe.winfo_children(): child.grid_configure(padx=5, pady=5) 


root.mainloop() 

它打開一個小的GUI與連接按鈕和一個運行按鈕。連接工作正常,但由於listener2.py腳本不終止,圖形用戶界面凍結,我不能按運行按鈕(嘗試以相反的順序時,同樣的問題)。

有沒有辦法啓動一個腳本並讓它在後臺運行,這樣GUI不會被凍結,我可以啓動下一個腳本?

謝謝!

回答

0

您可以在後臺線程中運行處理程序。在你當前的設置中,處理程序不會給gui任何反饋,所以它只是將按鈕命令切換到啓動線程的函數。

我添加了一些代碼來禁用按鈕,所以處理程序只能啓動一次。這裏的技巧是,你需要一些地方來存儲按鈕小部件,以便以後可以再次訪問它們。

#python 3 
#from tkinter import * 
#from tkinter import ttk 

#python 2 
from Tkinter import * 
import ttk 

import time 
import subprocess 
import paramiko 

import threading 

# keep track of widgets for event handlers 
widget_track = {} 

# event handler creates connect thread 
def connect_evt(): 
    t = threading.Thread(target=connect) 
    t.daemon = True 
    t.start() 
    widget_track['connect'].config(text="Connected", state="disabled", command=None) 

def connect(): 
    time.sleep(5) # todo: temporary for test 
    return 
    ssh = paramiko.SSHClient() 
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 
    ssh.connect('192.168.1.2', username='pi', password='raspberry') 
    stdin, stdout, stderr = ssh.exec_command('cd') 
    stdin, stdout, stderr = ssh.exec_command('roscore &') 
    time.sleep(20) 
    stdin, stdout, stderr = ssh.exec_command('\n') 
    stdin, stdout, stderr = ssh.exec_command('cd scripts') 
    stdin, stdout, stderr = ssh.exec_command('python /home/pi/scripts/listener2.py') 
    return 

# event handler creates run thread 
def run_evt(): 
    t = threading.Thread(target=run) 
    t.daemon = True 
    t.start() 
    widget_track['run'].config(text="Running", state="disabled", command=None) 

def run(): 
    time.sleep(5)  # todo: temporary for test 
    return 
    stdin, stdout, stderr = ssh.exec_command('python ES96_Vivaldi/talker2.py') 


root = Tk() 

mainframe = ttk.Frame(root, padding="3 3 12 12") 
mainframe.grid(column=0, row=0, sticky=(N, W, E, S)) 
mainframe.columnconfigure(0, weight=1) 
mainframe.rowconfigure(0, weight=1) 

# connect button starts connect background thread 
btn = ttk.Button(mainframe, text="Connect", command=connect_evt) 
btn.grid(column=1, row=3, sticky=S) 
widget_track['connect'] = btn 

# run button start run background thread 
btn = ttk.Button(mainframe, text="Run", command=run_evt) 
btn.grid(column=3, row=3, sticky=S) 
widget_track['run'] = btn 

ttk.Label(mainframe, text="Click 'Connect' to establish link.").grid(column=1, row=1, sticky=W) 
ttk.Label(mainframe, text="Click 'Run' to control using the arrow keys").grid(column=1, row=2, sticky=W) 

for child in mainframe.winfo_children(): child.grid_configure(padx=5, pady=5) 


root.mainloop() 
+0

這是完美的,感謝您的幫助! – Indigo