2016-08-17 64 views
1

我有一个wxpython对话框(包裹在一个函数调用,返回用户选择),我用来提示用户“确定”,“取消”类型的问题。wxpython对话框返回值与选项销毁

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

现在,假设弹出消息已经提示用户有是/否的问题,并且在同一时间,用户看到某事着火并决定点击紧急停止。

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

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

这工作得很好。

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

如果我添加一个.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 

很简单,但用的包装功能的实现(这是给别人调用代码,并需要提供简单的函数调用),它显然有点怪异。但重新实现它可能不是现在

继承人一些代码(均为大类因此多数民众赞成的一部分,为什么自我引用是有)

#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 

我已经使用队列,多处理池尝试,但问题飞与那些是q.get()和async_result()。get()都阻塞,直到用户点击,因此不会允许销毁按需工作。

id喜欢弄清楚的是如果用户点击按钮,如何获取用户值,但也能够销毁当前对话框并显示新的紧急停止对话框(带有自定义按钮)。

我希望的wxPython刚刚有了一个CLOSEALL():)

而且,我已经尝试基于标题名称关闭窗户,而工作,它软管我的WX实例在下一个对话框。

任何想法? 感谢

+0

你的问题是什么?我不明白 –

+0

附近的帖子:“如果用户点击按钮,如何获得用户值,但是也能够销毁当前对话框并显示新的紧急停止对话框(使用自定义按钮)“。 – pyNewbie

+0

你做错了什么(我认为)...你的不完整代码向我们展示了你的(可能是不正确的)解决方法并不真正告诉我你正在尝试做什么,你的解释并不清楚(至少对我来说)...我可以回答你的问题,如果你能帮助我理解你想做什么(如果你必须写一些伪代码)(例如你可以使用'wx.CallAfter'直接从一个线程调用一个方法(方法将在主线程中运行))... pubsub很酷,但你不需要它,只是因为你在做线程 –

回答

2

,因为我真的不明白你问什么,我反而会解决“我希望的wxPython刚刚有了一个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的对话框...如果您为框架或对话框设置父级,则在父级窗口关闭时该对话框将被关闭

+0

感谢您的代码。这实际上让我得到了我想要的东西,而没有所有的酒吧和销毁电话。虽然这可能是老牌wx编码器的常识,但我并没有意识到这一点,所以希望它能帮助其他人!再次感谢! – pyNewbie

2

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

为了显示线程中的消息框,您需要让线程询问主线程以显示消息框。

这样做使用的功能wx.CallAfter

+1

好的答案....我不知何故也认为'wx.CallAfter'也是正确的答案以及 –

+0

我的线程运行良好,除了这个,但尝试了一个简单的wx.CallAfter()没有成功。不久之后发生了什么试验 – pyNewbie