【问题标题】:wxMessageBox with an auto-close timer in wxPythonwxPython 中带有自动关闭计时器的 wxMessageBox
【发布时间】:2011-08-26 02:59:06
【问题描述】:

平台:Windows、OS X

Python 版本:活动状态 Python 2.7

wxPython 版本:2.9 版

这是我使用 wxMessageBox 的示例代码:

import wx,os

class Frame(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, size=(100, 100),style=wx.MINIMIZE_BOX | wx.SYSTEM_MENU | wx.CAPTION | wx.CLOSE_BOX | wx.CLIP_CHILDREN)

        host=os.system('hostname')
        if host!='superman':            
            self.dialogBox=wx.MessageBox('The host name should be superman. Closing this dialog box in 2s...','Info')            
            self.Destroy()
        else:
            self.Center()
            self.Show()

if __name__ == '__main__':
    app = wx.App(redirect=False)
    frame = Frame(None, -1, 'Sample')
    app.MainLoop()

根据上面的代码,如果主机名不是 'superman' ,则会显示一个消息框并提示用户按'OK'。如果用户按下消息框上的“确定”按钮,则控件将移至代码中的下一行(即第 10 行),其中框架被销毁。如果用户在接下来的 2 秒内没有按下“确定”按钮,我希望能够自动关闭对话框并转到代码中的下一行,即 self.Destroy()。关于如何在 wxpython 中执行此操作的任何想法?

【问题讨论】:

    标签: python wxpython auto-close


    【解决方案1】:

    我认为您可能必须为此使用自定义 wx.Dialog。以后可以使用wx.FutureCall 调用触发事件。比如:

    class MessageDialog(wx.Dialog):
        def __init__(self, message, title):
            wx.Dialog.__init__(self, None, -1, title,size=(300, 120))
            self.CenterOnScreen(wx.BOTH)
    
            ok = wx.Button(self, wx.ID_OK, "OK")
            ok.SetDefault()
            text = wx.StaticText(self, -1, message)
    
            vbox = wx.BoxSizer(wx.VERTICAL)
            vbox.Add(text, 1, wx.ALIGN_CENTER|wx.TOP, 10)
            vbox.Add(ok, 1, wx.ALIGN_CENTER|wx.BOTTOM, 10)
            self.SetSizer(vbox)
    
    class Frame(wx.Frame):
        def __init__(self, parent, id, title):
            wx.Frame.__init__(self, parent, id, title, size=(100, 100),style=wx.MINIMIZE_BOX | wx.SYSTEM_MENU | wx.CAPTION | wx.CLOSE_BOX | wx.CLIP_CHILDREN)
    
            host=os.system('hostname')
            if host!='superman':
                dlg = MessageDialog('The host name should be superman. Closing this dialog box in 2s...', 'Info')        
                wx.FutureCall(2000, dlg.Destroy)
                dlg.ShowModal()
            else:
                self.Center()
                self.Show()
    

    【讨论】:

    • 很好的解决方案。谢谢。我们能否让消息随着时间的推移显示计时器,意思是“在 3 秒内关闭……”、“在 2 秒内关闭……”、“在 1 秒内关闭……”然后关闭。
    • 当然,虽然我对 wxPython 不够熟悉,无法准确地说出如何操作。可能想查看代码:wxpython.org/docs/api/wx.ProgressDialog-class.html
    • 使用 wx.Timer,你可以绑定到它的 EVT_TIMER,例如这里 -->wiki.wxpython.org/Timer,这样你可以在每次定时器事件触发时更新用户离开的时间,然后在 x 事件触发后销毁...
    • 以后有时间我会用一个例子添加一个完整的答案。
    • 很好的解决方案,但是在 Python 2.7.12 上使用 wx 4.0.1 时,我得到 wxPyDeprecationWarning: Using deprecated class. Use CallLater instead.。只需将上述答案中的wx.FutureCall 更改为wx.CallLater 即可删除警告。
    【解决方案2】:

    如果您通过子类化wx.Dialog 创建自己的自定义对话框,您可以使用wx.Timer 生成一个周期性事件,您可以绑定一个处理程序,该处理程序在每次触发计时器事件时更新消息,然后在触发 x 事件你可以销毁对话框。

    工作示例:

    import wx
    import os
    
    class MessageDialog(wx.Dialog):
        def __init__(self, message, title, ttl=10):
            wx.Dialog.__init__(self, None, -1, title,size=(400, 150))
            self.CenterOnScreen(wx.BOTH)
            self.timeToLive = ttl
    
            stdBtnSizer = self.CreateStdDialogButtonSizer(wx.OK|wx.CANCEL) 
            stMsg = wx.StaticText(self, -1, message)
            self.stTTLmsg = wx.StaticText(self, -1, 'Closing this dialog box in %ds...'%self.timeToLive)
    
            vbox = wx.BoxSizer(wx.VERTICAL)
            vbox.Add(stMsg, 1, wx.ALIGN_CENTER|wx.TOP, 10)
            vbox.Add(self.stTTLmsg,1, wx.ALIGN_CENTER|wx.TOP, 10)
            vbox.Add(stdBtnSizer,1, wx.ALIGN_CENTER|wx.TOP, 10)
            self.SetSizer(vbox)
    
            self.timer = wx.Timer(self)
            self.timer.Start(1000)#Generate a timer event every second
            self.timeToLive = 10 
            self.Bind(wx.EVT_TIMER, self.onTimer, self.timer)
    
        def onTimer(self, evt):
            self.timeToLive -= 1
            self.stTTLmsg.SetLabel('Closing this dialog box in %ds...'%self.timeToLive)
    
            if self.timeToLive == 0:
                self.timer.Stop()
                self.Destroy()
    
    class Frame(wx.Frame):
        def __init__(self, parent, id, title):
            wx.Frame.__init__(self, parent, id, title, size=(100, 100),style=wx.MINIMIZE_BOX | wx.SYSTEM_MENU | wx.CAPTION | wx.CLOSE_BOX | wx.CLIP_CHILDREN)
    
            host=os.system('hostname')
            if host!='superman':
                dlg = MessageDialog('The host name should be superman', 'Info', ttl=10)               
                dlg.ShowModal()
            else:
                self.Center()
                self.Show()
    
    if __name__ == "__main__":
        app = wx.PySimpleApp()
        frame = Frame(None, -1, "") 
        frame.Show(1)
        app.MainLoop()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-10-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-31
      • 2023-04-09
      相关资源
      最近更新 更多