2013-04-29 32 views
-1

下面是我正在使用的函數。當我調用命令產生膩子會話時,它完全凍結了我的GUI程序,直到關閉膩子會話。有沒有什麼辦法可以解決這個問題,這樣它就可以調用命令,然後移動呢? (還有更多我傳遞的命令,但我已刪除它清理在windows命令中傳遞後繼續前進python

def SpawnSessionrmt(self,event): 
    if "SSH" in self.protormt: 
     subprocess.call('C:/bin/putty.exe ',shell=True) 
    elif "RDP" in self.protormt: 
     subprocess.call('C:/bin/rdp.exe) 
    else: 
     print "Not that you will see this...but that isn't a valid protocol" 
+0

嘗試使用subprocess.Popen代替:) – 2013-04-29 21:04:10

+0

是否有您使用的原因'殼= TRUE;在第一個?或者你在命令名的末尾添加空格? (幸運的是,這會發生在Windows上使用'shell = True'的工作......但這肯定不是你應該依賴的東西。) – abarnert 2013-04-29 21:06:28

回答

0

的問題是,作爲the docs說,call會:

運行命令描述通過ARGS。等待命令完成,然後返回返回碼屬性。

如果你不想等待命令完成,不要使用call。只要創建一個Popen插件(最好在wait之後,也許在退出時或在後臺線程中)。

例如:

def SpawnSessionrmt(self,event): 
    if "SSH" in self.protormt: 
     self.children.append(subprocess.Popen('C:/bin/putty.exe ',shell=True)) 
    elif "RDP" in self.protormt: 
     self.children.append(subprocess.Popen('C:/bin/rdp.exe')) 
    else: 
     print "Not that you will see this...but that isn't a valid protocol" 

def WaitForChildren(self): 
    for child in self.children: 
     child.wait() 

對於GUI應用程序,我認爲這樣做最簡單的事情可能只是把subprocess.call到後臺線程。這樣,您可以在實際工作完成時更新GUI。不幸的是,每個GUI框架都有不同的做法 - 一些可以讓你從任何線程做GUI東西,一些有一個run_on_main_thread函數,一些允許你將事件發佈到主線程以便被事件循環拾取,有些需要你建立你自己的線程間通信系統等等。而你並沒有告訴我們你正在使用哪個GUI框架。

所以,這裏是一個框架,我隨機挑選,wx一個例子:

def SpawnSessionrmt(self,event): 
    if "SSH" in self.protormt: 
     cmd = 'C:/bin/putty.exe' 
    elif "RDP" in self.protormt: 
     cmd = 'C:/bin/rdp.exe' 
    else: 
     print "Not that you will see this...but that isn't a valid protocol" 
     return 
    def background_function(): 
     result = subprocess.call(cmd) 
     event = wx.CommandEvent(MY_UPDATE_ID) 
     event.SetInt(result) 
     self.GetEventHandler().AddPendingEvent(event) 
    t = threading.Thread(target=background_function) 
    t.daemon = True 
    t.start() 

(PS,我恨我的隨機數發生器,因爲我討厭wx ......但至少它沒有挑Tkinter ,這將迫使我寫一個QueueCondition在我自己的跨線程的通信...)