wxPython:如果破坏模态对话框,则使用wx.PostEvent设置焦点不起作用

时间:2014-12-11 13:32:13

标签: wxpython wxwidgets

在模式对话框被破坏后设置按钮的焦点时遇到问题。

我是否可以通过调用来销毁模态对话框或阻止它进行模态化然后将其销毁?

当wx.PostEvent触发一个事件时,它会强制在模态对话框上进行Destroy,但据我所知,它不会立即被销毁,这意味着当我执行SetFocus()时按钮仍然被禁用。

import wx
import wx.lib.newevent
from threading import Thread
import time
processFinishes, EVT_PROCESS_FINISHES = wx.lib.newevent.NewEvent()

class Dummy(Thread):
    def __init__(self, arg):
        super(Dummy, self).__init__()
        self.arg = arg

    def run(self):
        time.sleep(15)
        print "Posting"
        wx.PostEvent(self.arg , processFinishes(result=(None)))


class MyRegion(wx.Frame):
    def __init__(self, parent):
        wx.Frame.__init__(self, parent)
        self.button = wx.Button(self, label="Click me!")
        self.mybutton2 = wx.Button(self, label="I should have focus!!!")
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.button, 0, wx.ALL)
        sizer.Add(self.mybutton2, 0, wx.ALL)
        self.SetSizerAndFit(sizer)
        self.Bind(wx.EVT_BUTTON, self.OnButton)
        self.Bind(EVT_PROCESS_FINISHES, self.OnFinish)
        self.progress = None
        self.t = Dummy(self)

    def OnButton(self, event):
        self.progress = wx.ProgressDialog("Processing",
                                          "Please wait while the processing finishes.")
        self.progress.Pulse()
        self.progress.ShowModal()
        self.t.start()

    def OnFinish(self, _event):
        print "destroyed"
        self.progress.Destroy()
        print "now setting foucs"
        self.mybutton2.SetFocus()

if __name__ == "__main__":
    app = wx.App()
    frame = MyRegion(None)
    frame.Show()
    app.MainLoop()

编辑:

当试图阻止进度对话框进入模态时,下面的代码给出了错误,表明ProgressDialog不是模态的,而显然是:

    .....
    def OnButton(self, event):
        # wx.ProgressDialog can also be created with
        # style=wx.wx.PD_APP_MODAL which cannot be made non-modal later on
        # i.e. EndModal() does not work
        self.progress = wx.ProgressDialog("Processing",
                                          "Please wait while the processing finishes.")
        self.progress.Pulse()
        self.progress.ShowModal()
        self.t.start()

    def OnFinish(self, _event):
        print "destroyed"
        # By changing this line
        # wx complains indicating that the progress dialog
        # is not modal whereas a ShowModal was used

        self.progress.EndModal(0) # -> produces a "wx._core.PyAssertionError: C++ assertion "IsModal()" failed at ..\..\src\msw\dialog.cpp(221) in wxDialog::EndModal(): EndModal() called for non modal dialog"
        print "now setting foucs"
        self.mybutton2.SetFocus()

1 个答案:

答案 0 :(得分:2)

模式对话框会在ShowModal()返回时重新启用所有内容,因此只需直接从OnFinish()致电OnButton()

然而请注意wxProgressDialog根本不是模态对话框(如果你不能在它上面调用Update()那就没用了!),所以在它的情况下你应该在完成它时将其销毁(或者使用wxPD_AUTO_HIDE样式告诉它在达到最大进度值时自行消失)。