2011-05-16 116 views
3

平臺自動關閉計時器:Windows和OS XwxMessageBox在wxPython中

Python版本:活動狀態的Python 2.7

wxPython的版本:Version 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() 

根據上面的代碼,如果主機名不是「超人」,那麼美國er會顯示一個消息框並提示按'確定'。如果用戶在消息框上按下「OK」按鈕,則控制移動到代碼中的下一行(即行號10),其中該框被銷燬。我希望能夠自動關閉對話框並轉到代碼中的下一行,即如果用戶在接下來的2秒內未按下「確定」按鈕,則返回self.Destroy()。任何關於如何在wxpython中執行此操作的想法?

回答

3

我想你可能不得不爲此使用自定義的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() 
+0

好的解決方案。謝謝。我們可以讓消息顯示計時器隨着時間的推移,意思是「3s結束......」,「以2s結束......」,「以1s結束......」然後關閉。 – user699540 2011-05-16 04:26:40

+0

當然,雖然我對wxPython不夠熟悉,無法準確地說出如何。可能想查看下面的代碼:http://www.wxpython.org/docs/api/wx.ProgressDialog-class.html – zeekay 2011-05-16 04:35:02

+0

使用wx.Timer,你可以綁定到它的EVT_TIMER,例如這裏 - > http://wiki.wxpython.org/Timer,這樣你可以在長時間更新用戶他已經離開每次計時器事件觸發,再經過X事件觸發摧毀... – volting 2011-05-16 06:32:21

6

如果您創建通過繼承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()