外部
根據我們的經驗,大部分用戶在使用時壹定是先關註應用的外觀,所以我們先來對比壹下wxPython和PyQt的外觀。
WxPython是Python語言與流行的wxWidgets跨平臺GUI工具庫的綁定。WxWidgets是用C++語言編寫的,所以當妳在GUI中編寫按鈕小部件的代碼時,妳不會看到任何類似於另壹個操作系統的東西。
▲基於Linux的Thunar和wxPython
PyQt也是用C++寫的,基於著名的Qt工具包。與wxPython不同,它不使用native。
小部件,但是根據它檢測到的操作系統創建壹個小部件的近似。但是它的近似可以說是極端了,就連美術生也分不清它和原作的區別。
如果您使用KDE,您可以使用其他PyKDE庫來彌補Linux和BSD之間原始PyQt和Plasma desktop外觀之間的差距,但這增加了新的依賴性。
▲基於Linux的KDE和Qt
跨平臺
WxPython和PyQt都支持Linux、Windows和Mac,所以非常適合跨平臺。但是這種跨平臺並不是無條件的。如果希望Python代碼在特定平臺上運行,需要做壹些調整。例如,GUI工具包不能調整數據目錄的路徑格式,因此您必須運行Python中的最佳實踐,使用os.path.join和幾種不同的退出方法。GUI工具包的選擇不會神奇地從平臺中抽象出來。
PyQt試圖消除跨平臺差異,並允許Python本身需要的通用調整。PyQt可以避免大部分跨平臺問題,所以GUI代碼在不同的操作系統中基本可以保持不變。
在wxPython中,用戶可能需要根據編程內容對不同平臺的GUI代碼進行壹些調整。例如,為了防止Microsoft Windows上的某些元素閃爍,必須將USE_BUFFERED_DC屬性設置為True,以便對圖形進行雙緩沖。這不是默認的,即使所有平臺都可以無條件運行,所以在某些用例中可能會有缺陷。
固定
作為開發人員,您可能不關心獲取應用程序所需的庫所需的安裝步驟;但是,如果您計劃分發應用程序,您需要考慮用戶為了使程序運行而必須執行的安裝過程。
在所有平臺上安裝Qt就像安裝任何其他應用程序壹樣簡單。給用戶壹個下載鏈接,然後安裝下載的軟件包使用。
PyQt依賴於Qt本身的C ++代碼,這意味著用戶不僅要安裝PyQt,還要安裝所有的Qt。這個操作不像之前的安裝那麽簡單,但是Qt和PyQt團隊已經盡可能的簡化了安裝操作。現在只要用戶可以安裝瀏覽器或者遊戲,就可以通過鏈接成功安裝Qt。如果用戶非常擅長,用戶甚至可以將安裝腳本作為自己安裝程序的壹部分。
在Linux、BSD和Ilumos中,安裝程序通常由經銷商的軟件包管理員為用戶編寫。
在Linux和Windows上,wxPython的安裝過程非常簡單,但是在Mac OS上就有問題了。如果可下載的軟件包嚴重過時,Mac OS不利於向後兼容。由於該修補程序的錯誤代碼,該軟件包尚未更新,因此用戶自己找到並實施該修補程序的機會非常低。目前的解決方案是將wxPython打包分發給Mac OS用戶,或者依靠外部的包管理器。
組件和功能
PyQt和wxPython都有用戶期望從GUI工具包中得到的所有公共小部件(包括按鈕、復選框、下拉菜單等)。).兩者都支持拖放操作、選項卡式界面、對話框和創建自定義小部件。
PyQt的優勢在於靈活性。您可以在運行時重新排列、浮動、關閉和恢復Qt面板,為每個應用程序提供壹個高度可配置的以可用性為中心的界面。
只要使用正確的小部件,就可以為用戶提供許多友好的功能,而不必自己重新思考花哨的技能。
WxPython有很多好的功能,但是在靈活性和用戶控制上是無法和PyQt相比的。PyQt更便於開發者設計和布局。在開發Qt之前,需要花壹些時間從用戶那裏獲取跟蹤自定義布局的方法,或者如何找到不小心關閉的缺失面板。對於wxPython,很難重新打開意外關閉的面板。
壹般來說,wxPython只是wxWidgets的前端,所以如果真的需要壹個函數,可以用C ++實現,然後在wxPython中使用。與PyQt相比,wxPython的學習曲線更加陡峭。
溝通
GUI應用程序由許多較小的可視元素組成,通常稱為“小部件”。為了讓GUI應用程序順利運行,小部件必須相互通信。例如,用於顯示圖像的窗格可以知道用戶選擇了哪個縮略圖。包括wxPython在內的大多數GUI工具包都可以用“回調”來處理內部通信。回調是指向壹段代碼(“函數”)的指針。如果當妳點擊壹個按鈕部件時發生了什麽,妳應該為發生的操作寫壹個函數。當點擊按鈕時,功能被觸發,操作發生。
如果和Lambda表達式結合,會產生非常靈活的解決方案,效果可能會超出妳的預期。
另壹方面,Qt以其信號/插槽機制而聞名。如果把wxPython的內部通信網絡比作壹個老式的電話交換機,那麽PyQt的通信可以看作是壹個網狀網絡。
▲Qt中的信號和插槽
Qt使用信號和插槽,而不是回調函數。當特定事件發生時,信號會被發出。Qt的小部件有許多預定義的信號。當然,我們也可以創建widget的子類來添加我們需要的自定義信號。Slot是對特定信號的反饋。Qt的widget也有許多預定義的插槽,但通常的做法是創建widget的子類,並添加自定義插槽來處理感興趣的信號。
信號和插槽機制是類型安全的:信號的參數必須與接收插槽的參數相匹配。由於這種參數匹配機制,編譯器可以幫助我們檢查類型不匹配的簽名。信號和插槽是松散耦合的:信號類既不知道也不關心哪個插槽接收信號。Qt的信號和插槽機制確保了如果妳將壹個信號連接到壹個插槽,這個插槽將在正確的時間被number參數調用。信號和槽可以攜帶任意數量的任意類型的參數。它們是完全類型安全的。
從QObject或它的壹個子類(比如QWidget)繼承的所有類都可以使用數字和槽。對象之間的通信是這樣的,壹個對象的狀態發生變化,發出壹個信號,另壹個關心這個變化的對象收到這個信號。發送信號的對象不知道或者對什麽對象接收它發送的信號不感興趣。這是真正的信息封裝,確保對象可以作為軟件組件使用。
插槽可以用來接收信號,但也是普通的成員函數。插槽不知道是否有信號連接到它,就像對象不知道它發出的信號是否會被接收到壹樣。這種機制確保Qt可以用來創建完全獨立的組件。
信號可以多對多的方式連接到插槽。這樣,信號和插槽就建立了壹個強大的組件編程機制。
總體布局
要編寫壹個GUI應用程序,要做的第壹件事就是設計布局,以便所有的小部件都可以正確地顯示在應用程序窗口中。就像設計網頁壹樣,您可以調整應用程序的大小,甚至可以將其設置為固定大小。
在Qt中,布局非常流暢,Widget命名清晰(QPushButton、QDial、QCheckbox、QLabel,甚至QCalendarWidget),而且調用方便,連應用文檔都很齊全。
這裏的大部分困惑集中在基本的GUI元素上。比如妳在寫壹個應用,可以從QMainWindow或者QWidget構建妳的父窗口嗎?
QWidget是壹個空容器,所有其他小部件都可以使用它。當然,可以放置更多的QWidgets,形成壹個放置更多Widgets的父窗口。QMainWindow使用的是QWidget,增加了很多大多數應用都需要的便捷功能,比如頂部的工具欄,底部的狀態欄。
▲QMainWindow
這是壹個使用QMainWindow的小型文本編輯器,只有100行Python代碼:
wxPython中的基本小部件是wx。wxPython中的壹切都是基於wx的。窗口類,不管它是實際的窗口還是按鈕、復選框或文本標簽。如果類名拼寫錯誤,wx。Window會直接忽略它。
下圖是用wx創建壹個空窗口。框架:
將其他部件放入wx。框架窗口,然後構建壹個GUI應用程序。比如wx。Panel小部件類似於HTML中的div,具有絕對大小限制,因此您可以使用它在主窗口中創建面板。
與PyQt相比,WxPython的便捷功能較少。比如PyQt內置了復制粘貼功能,但是在wxPython中必須手動編碼(而且有些還受限於運行的平臺)。