為了實現一個管理本地電子書的程序,搞了一段時間 GUI,使用 wxPython。
實在難以適應和習慣,也搞不出什么太好看的效果。
最不能忍受的是,多線程處理能力太弱。遂決定放棄 GUI。
放棄之前,整理一點筆記。
GUI 的核心都是基于事件編程,開啟一個loop,不停的監聽事件。
監聽到事件以后,交給對應的 handler 來處理。
wxPython 中,需要有一個 wx.App 和 至少一個 Frame。
wx.App 管理程序的生命周期,比如,開啟一個 loop。
wx.Frame 內添加各種控件 widgets 控制樣式和具體的行為。
GUI 中的窗口,除了wx.Frame,還是wx.Dialog, wx.Dialog 多為 Modal 模式。
Modal 模式,即阻塞了別的窗口部件接收用戶事件,直到該模式對話框被關閉。
二者在使用和運行機制上,略有差別,參見 wxPython Modal Dialog 模式對話框
GUI的操作必須發生在主線程或應用程序的主循環所處的地方中。
在一個單獨的線程中執行GUI操作,容易導致無法預知的程序崩潰,而且難以調試。
基于技術方面的原因,
如許多Unix的GUI庫不是線程安全性的,以及在微軟Windows下UI對象的創建問題,
wxPython沒有設計它自己的發生在多線程中的事件。
我們自己最好也不要嘗試。
后臺執行長時間運行的程序,并在界面上顯示進度。
實現的原理如下圖:
在 main_thread 上創建子線程,用于執行長時間運行的程序。
子線程只負責給 main_thread(UI 線程)發消息,而不關心 GUI 的更新。
主線程響應子線程觸發的事件,不如,更新 UI。
最簡單的實現方式是,
子線程調用 wx.CallAfter(func, (args)) 注冊新事件,并將 func 注冊到新事件的處理句柄中。
新消息執行時,func 在主線程中執行并更新UI。
也可以自定義事件,自定義處理句柄。
sizer 內可以直接 Add(seizer), 像 Add 其他控件一樣。
最終需要把主 sizer SetLayout 即可。
新聞熱點
疑難解答