wxpython 对话框 return 带有销毁选项的值

wxpython dialog return values with option to destroy

我有一个 wxpython 对话框(包装在 return 用户选择的函数调用中),我用它来提示用户输入 "ok"、"cancel" 类型的问题。

我有另一个线程 运行 允许用户单击按钮并执行紧急停止(也是 wxpython)。单击紧急停止按钮时,它会执行一些操作,然后显示自己的用户对话框。

现在,假设弹出消息提示用户 yes/no 问题,同时,用户看到某物着火并决定单击紧急停止。

我需要能够销毁当前对话问题并最终显示属于 estop 线程一部分的对话。

我已经创建了在一个线程中启动对话的代码,以及另一个发出 pub.sendMessage(...) 以终止对话线程的代码,如果它在按下 estop 按钮时显示在屏幕上。

这很好用。

问题是,我无法从用户对话框中获得结果(是、否、取消等),因为线程永远不会返回 return 用户选择的内容。

如果我将 .join() 添加到我的代码中,我会收到用户响应,但如果发送了 pub.sendMessage(...),对话框不会被破坏。

这里是伪代码:

1)start up thread to monitor user emergency stop button push
2)start up test which may contain popup window (custom wxdialog) prompting user for answer
3)return user selection from dialog if selected 
  OR if user has clicked estop button: destroy current dialog and display new    dialog related to estop

够简单了,但是有了wrapper函数的实现(这是给别人调用的代码,需要提供简单的函数调用),显然有点怪怪的。但重新实现它现在可能不会成功

这里有一些代码(都是更大的 class 的一部分,所以这就是自我引用存在的原因)

    #the receiver of the pub message first:

def DestroyUI(self):
    print 'into destroy'
    #self.Hide()
    #self.Close()
    self.Destroy()

#these 2 fuctions are part of a different class 

def closeDialogs(self):
    print 'into closeDialogs'
    def destroyUI():
        if self.okToKill:
            print 'closing wx dialogs'
            pub.sendMessage("destroyUI")
    ts = threading.Thread(target = destroyUI)
    ts.start()
    ts.join()


def MB(self,blah,blah):
    def runMB(*args):
        self.okToKill= True
        self.response = self.PromptUser(*args)
        self.okToKill= False

    tr = threading.Thread(target = runMB,args=(blah,blah))
    tr.start()

    #if i add the join back in, i always return the user values
    #but the dialog is never destroyed (if needed) before user
    #clicks.
    #without the join, the destroy pub send works great, but the 
    #user values are never returned
    #tr.join()

    return self.response

我试过使用 queues,多进程池,但问题是 q.get() 和 async_result().get() 都阻塞,直到用户点击和因此不允许销毁根据需要工作。

我想弄清楚的是如何在用户单击按钮时获取用户值,而且还能够销毁当前对话框并显示新的紧急停止对话框(使用自定义按钮)。

我希望 wxpython 有一个 closeAll() :)

此外,我已经尝试根据标题名称关闭 windows,虽然这有效,但它会为下一个对话框管理我的 wx 实例。

有什么想法吗? 谢谢

因为我不太明白你在问什么,我会改为地址 "I wish wxpython just had a closeAll() :)"

def wx_closeAll():
    for win in wx.GetTopLevelWindows():
        win.Destroy()

def closeAllButPrimary():
    for win in wx.GetTopLevelWindows():
        if win != wx.GetTopLevelWindow():
           win.Destroy()

注意 这将关闭父级为 None 的所有框架和对话框 ... 如果您为框架或对话框设置父级,则该对话框将在以下时间关闭它的父级 window 已关闭

从线程执行 GUI 不是一个好主意,而且几乎总是会产生意想不到的结果。

为了从线程中显示消息框,您需要让线程请求主线程显示消息框。

您可以使用函数 wx.CallAfter

执行此操作