-1

以下是我正在使用的功能。当我调用命令 spawn a putty session 时,它会完全冻结我的 gui 程序,直到我关闭 putty 会话。有没有办法解决这个问题,以便它调用命令,然后继续前进?(还有更多我要传递给命令,但我已将其删除以进行清理。

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"
4

1 回答 1

0

问题是,正如文档所说,call将:

运行 args 描述的命令。等待命令完成,然后返回 returncode 属性。

如果您不想等待命令完成,请不要使用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……但至少它没有选择,这将迫使我围绕 a或……Tkinter编写自己的跨线程通信)QueueCondition

于 2013-04-29T21:04:40.077 回答