麥子學(xué)院---《使用pyqt開(kāi)發(fā) windows gui程序及打包》學(xué)習(xí)筆記
1. python GUI框架簡(jiǎn)介候衍,pyqt介紹慧域,為什么使用pyqt
python開(kāi)發(fā)GUI程序,了解一個(gè)框架需要了解:
(1)運(yùn)行效果
(2)能夠運(yùn)行在哪些平臺(tái)
(3)學(xué)習(xí)成本唇敞,因?yàn)槊恳粋€(gè)GUI框架都有自己的特點(diǎn)
(4)開(kāi)發(fā)效率的比較厢拭,python的運(yùn)行效率比c c++低吩跋,但是開(kāi)發(fā)效率是比較快的
python GUI框架:
(1)Tkinter: python內(nèi)置的GUI框架,使用TCL實(shí)現(xiàn)窖认,python中內(nèi)嵌了TCL解釋器豫柬,使用它的時(shí)候不用安裝額外的擴(kuò)展包,直接import扑浸,跨平臺(tái)烧给。不足之處在于UI布局全靠代碼實(shí)現(xiàn),只有15種常用部件首装,顯示效果簡(jiǎn)陋创夜。
(2)Wxpython:用得比較廣泛,跨平臺(tái)仙逻,C++編寫(xiě)驰吓,需要安裝擴(kuò)展模塊;文檔少系奉,遇到問(wèn)題不好解決檬贰,代碼布局控件,不直觀缺亮。
(3)Pygtk: python對(duì)GTK+GUI庫(kù)的封裝翁涤,在linux平臺(tái)上運(yùn)行的比較好,需要安裝擴(kuò)展模塊,在windows下的兼容性有一些問(wèn)題葵礼。
(4)pyqt:QT原本是諾基亞的產(chǎn)品号阿,源碼用C++寫(xiě)的容诬,python對(duì)QT的包裝祟身,跨平臺(tái)妙蔗,本地顯示效果涵妥,根據(jù)系統(tǒng)決定芦缰,在win7下就是win7的顯示效果鉴嗤;pyqt與qt的函數(shù)接口一致堵漱,qt開(kāi)發(fā)問(wèn)的那個(gè)豐富祷愉,所以pyqt開(kāi)發(fā)文檔也比較豐富艰山;控件豐富湖雹,函數(shù)/方法多,拖曳布局曙搬;方便打包成二進(jìn)制文件摔吏;GPL協(xié)議,商業(yè)程序需要購(gòu)買(mǎi)商業(yè)版授權(quán)
(5)pyside:諾基亞的親兒子织鲸,python對(duì)QT的封裝舔腾,安裝擴(kuò)展模塊,跨平臺(tái)搂擦,與pyqt的API一樣稳诚,LGPL協(xié)議,新軟件可以是私有的瀑踢,代碼布局
(6)Kivy: 針對(duì)多點(diǎn)觸控程序扳还,智能手機(jī)平板等,也可以在沒(méi)有觸屏功能的系統(tǒng)上橱夭,全平臺(tái)支持氨距;使用python和cython(python和c語(yǔ)言的接口)編寫(xiě);中文支持差棘劣,需要自己下載中文庫(kù)并且制定路徑俏让。
為什么使用pyqt:
- 因?yàn)锳PI與qt一致,學(xué)會(huì)了pyqt再使用qt很簡(jiǎn)單
- 文檔豐富
- 學(xué)習(xí)成本低
- 開(kāi)發(fā)迅速茬暇,qt designer拖曳布局首昔,如果使用代碼布局還需要構(gòu)建全局并且調(diào)試
- 學(xué)習(xí)經(jīng)驗(yàn)容易遷移到pyside來(lái)開(kāi)發(fā)商業(yè)應(yīng)用
- 方便打包發(fā)布軟件,python本身解釋語(yǔ)言的特點(diǎn)是寫(xiě)好的程序不編譯和鏈接糙俗,使用文本運(yùn)行解釋器勒奇,邊解釋邊執(zhí)行,用戶不可能裝一個(gè)解釋器再發(fā)源碼再執(zhí)行巧骚,所以打包成exe再發(fā)布
本課程內(nèi)容(假設(shè)已經(jīng)掌握python語(yǔ)法):
(1)pyqt常用控件使用(標(biāo)簽赊颠,按鈕格二,radio button,文本框竣蹦,旋鈕顶猜,滑塊,圖片顯示)
(2)python一些常用擴(kuò)展包的使用痘括,結(jié)合pyqt完成實(shí)用小軟件(從大量excel中查找關(guān)鍵詞驶兜,語(yǔ)音識(shí)別程序開(kāi)發(fā))
(3)使用python和百度云語(yǔ)音完成語(yǔ)音識(shí)別程序,并通過(guò)語(yǔ)音控制臺(tái)燈開(kāi)關(guān)(需要硬件支持)
(4)pyqt程序在windows平臺(tái)下的打包远寸,linux下可以直接運(yùn)行打包
2. 使用python開(kāi)發(fā)pyqt程序的環(huán)境搭建
python版本選擇:python3
永遠(yuǎn)選擇easy模式,不在搭建環(huán)境中浪費(fèi)時(shí)間屠凶,傳統(tǒng)開(kāi)發(fā)模式在網(wǎng)上下載python各種安裝包驰后,再一個(gè)個(gè)安裝,python原生的IDE不是很好用矗愧。
Anaconda介紹與安裝
Eric6安裝灶芝,需要安裝一個(gè)集成環(huán)境,可以作為python的IDE唉韭,在官網(wǎng)上下載的安裝包是一個(gè)文件目錄夜涕,使用python命令運(yùn)行install.py文件完成安裝,安裝后安裝目錄到anaconda下scripts文件中属愤,其實(shí)也就相當(dāng)于一個(gè)包女器,雙擊eric6.bat文件運(yùn)行
- 下載地址:https://sourceforge.net/projects/eric-ide/files/latest/download
- 解壓后安裝,安裝后可以刪去下載的文件
安裝pycharm住诸,(老師使用的eclipse+pydev插件驾胆,并且還要配置解釋器位置)
還需要配置環(huán)境
3. 第一個(gè)eric GUI程序的創(chuàng)建以及運(yùn)行方法
eric開(kāi)發(fā)流程:
- 新建工程
- 新建ui文件,后綴名為.ui
- 編輯ui文件
- 編譯ui文件為py文件贱呐,編譯為py文件才能運(yùn)行丧诺,直接在eric中文件右鍵點(diǎn)擊compile from,成功會(huì)提示編譯成功奄薇。
- 運(yùn)行py文件
新建好項(xiàng)目之后驳阎,會(huì)自動(dòng)生成一個(gè)init.py文件,這個(gè)文件的存在意義就是告訴python解釋器馁蒂,接下來(lái)都是python腳本呵晚。
點(diǎn)擊forms,在空白區(qū)域右鍵新建一個(gè)窗體远搪,默認(rèn)是dialog類(lèi)型劣纲,我們選擇main window主窗體,然后保存為.ui文件谁鳍。步驟如下圖:
run script后彈窗不需要設(shè)置選項(xiàng)內(nèi)容癞季,直接ok劫瞳,那么第一個(gè)eric GUI程序就運(yùn)行成功了。
報(bào)錯(cuò)1: 找不到designer绷柒,新建文件過(guò)程中報(bào)錯(cuò)了志于,如圖,原因?yàn)椋?/h4>
解決辦法:
- 在cmd中執(zhí)行pip install PyQt5-tools废睦,安裝designer工具伺绽,會(huì)在anaconda3\Lib\site-packages目錄下,多出pyqt5-tools這個(gè)文件夾
-
在eric6中settings-preferences中-QT中指明designer.exe所在的bin目錄嗜湃,問(wèn)題就解決了奈应,如圖:
解決好問(wèn)題之后,可以順利創(chuàng)建.ui文件购披,并且創(chuàng)建好文件之后自動(dòng)彈出Qt designer工作界面杖挣。
報(bào)錯(cuò)2: py文件無(wú)法run,eric6中start和debug選項(xiàng)都是灰色的
在eric6中settings-preferences中-QT中指明designer.exe所在的bin目錄嗜湃,問(wèn)題就解決了奈应,如圖:
解決好問(wèn)題之后,可以順利創(chuàng)建.ui文件购披,并且創(chuàng)建好文件之后自動(dòng)彈出Qt designer工作界面杖挣。
原因是python解釋器沒(méi)有配置好刚陡,解決辦法在settings-preferences中debugger-python3一項(xiàng)惩妇,選擇默認(rèn)的解釋器。針對(duì)自己用python版本筐乳,檢查debugger是否配置好歌殃。
4. Qt designer的使用
拖曳布局,多種空間蝙云,屬性界面(修改控件屬性)
常用的界面布局:
- 橫向布局
- 縱向布局
- 網(wǎng)格布局
沒(méi)有整體布局氓皱,直接拖動(dòng)控件其實(shí)也是一種布局,叫做絕對(duì)位置布局贮懈,每一個(gè)控件在窗口中的位置都有一組坐標(biāo)確定的匀泊,geometry屬性,里面有4個(gè)參數(shù)朵你,分別是距離左上角的高與寬各聘,以及這個(gè)控件的高度和寬度。優(yōu)點(diǎn)是可以隨意拖動(dòng)抡医,不用考慮其余控件躲因,缺點(diǎn)是兩個(gè)控件實(shí)現(xiàn)對(duì)齊等操作時(shí)很困難。
會(huì)自動(dòng)計(jì)算間距忌傻,排列整齊大脉,前三種比較常用,并且這些布局可以嵌套使用水孩,混合使用镰矿,比如某個(gè)格子里面再使用一個(gè)垂直布局之類(lèi)的。
報(bào)錯(cuò)3:could not start pyuic5
每次使用qt designer布局保存之后俘种,需要重新編譯文件秤标,如果編譯時(shí)報(bào)錯(cuò)绝淡,could not start pyuic5,找到報(bào)錯(cuò)原因是苍姜,在settings-preference設(shè)置中牢酵,重復(fù)設(shè)置了qt tools和pyqt tools的工具目錄,刪除掉pyqt tools設(shè)置的地址就解決了衙猪。
6. 第一個(gè)控件:label控件使用
- 主要目的是顯示信息,label框以及字體的顏色通過(guò)stylesheet中進(jìn)行修改垫释,可以增加顏色丝格,字體等,要注意修改樣式時(shí)必須保證語(yǔ)法正確棵譬,比如每條樣式設(shè)置間“铁追;”不能丟失等。否則會(huì)報(bào)錯(cuò):invalid style sheet茫船,修改樣式無(wú)效。
- 可以發(fā)射信號(hào)扭屁,配合槽函數(shù)實(shí)現(xiàn)特定功能
- 可以修改樣式表算谈,顯示圖片
7. 加入一點(diǎn)交互,button控件的使用
button控件經(jīng)常是用戶發(fā)起請(qǐng)求料滥,確認(rèn)或者取消然眼,發(fā)出請(qǐng)求之后程序要做相應(yīng)的處理
初步了解pyqt的信號(hào)與槽
掌握在Qt designer編輯信號(hào)與槽的方法
實(shí)現(xiàn)button和label控件聯(lián)動(dòng)
button控件作用:
- 主要用于用戶提交,確認(rèn)葵腹,關(guān)閉窗口等情況高每,button用相應(yīng)的用戶處理,比如點(diǎn)擊之類(lèi)的
- 需要有時(shí)間處理函數(shù)實(shí)現(xiàn)特定功能
pyqt的信號(hào)與槽
總步驟:
1. 切換編輯模式到信號(hào)與槽模式
2. 拖動(dòng)鏈接
3. 選擇相應(yīng)的槽函數(shù)
在Qt designer編輯信號(hào)與槽的方法:
- 默認(rèn)的是在編輯UI的界面践宴,在edit下選擇edit signals/slots,切換到編輯信號(hào)和槽的界面鲸匿。
- 鼠標(biāo)在push button上是,按住鼠標(biāo)向左拖動(dòng)出現(xiàn)像地線一樣的符號(hào)阻肩,并且彈出配置鏈接的窗口带欢,左邊就是push button所支持的發(fā)射信號(hào)的方法,即感知用戶的哪些動(dòng)作烤惊。選擇一個(gè)動(dòng)作可以發(fā)射一個(gè)信號(hào)乔煞,右側(cè)即為槽可以接收發(fā)射出來(lái)的信號(hào),右側(cè)小窗口內(nèi)為空白柒室,當(dāng)勾選繼承主窗口的事件之后渡贾,可以出來(lái)一堆的事件,從而可以進(jìn)行選擇事件雄右。比如空骚,選擇纺讲,close(),那么保存ui文件編譯好之后執(zhí)行府怯,效果就是刻诊,點(diǎn)擊push button按鈕,整個(gè)窗口將關(guān)閉牺丙。
- 選擇的槽函數(shù)可以對(duì)控件進(jìn)行操作则涯,或者mian window,也可以對(duì)跟控件無(wú)關(guān)的東西進(jìn)行操作冲簿。
button與label聯(lián)動(dòng)
將push button拖動(dòng)到鏈接上label粟判,那么就可以發(fā)射信號(hào),對(duì)label進(jìn)行操作峦剔,后面會(huì)深入講解button控件槽函數(shù)的使用和控制方法档礁,這里使用GUI方式拖拽,不是特別方便吝沫,并且只能操作GUI上面的控件呻澜,功能比較少,有的方法還不是很靈活惨险,后面會(huì)用代碼的方式去實(shí)現(xiàn)羹幸,這樣不會(huì)限制控件的操作,點(diǎn)擊控件之后后臺(tái)可以完成很多事件辫愉。
8. 理解信號(hào)與槽栅受,QT的核心概念
學(xué)習(xí)內(nèi)容:
1. 了解QT的信號(hào)與槽機(jī)制
2. 了解通過(guò)代碼鏈接信號(hào)與槽的方法
3. 掌握使用eric生成槽函數(shù)的方法
4. 理解pyqt自動(dòng)連接信號(hào)與槽的機(jī)制
5. 編寫(xiě)槽函數(shù)
QT對(duì)時(shí)間響應(yīng)提供了兩種機(jī)制:和大多數(shù)GUI一樣相對(duì)底層的(按鈕的鼠標(biāo)點(diǎn)擊或者觸摸屏的點(diǎn)擊,鍵盤(pán)選中敲回車(chē)點(diǎn)擊恭朗,這三種事件底層不一樣屏镊,有不同的實(shí)現(xiàn))和高級(jí)的信號(hào)與槽的機(jī)制(底層響應(yīng)沒(méi)有太多的意義)
信號(hào)與槽
屏蔽底層細(xì)節(jié),不管你是鼠標(biāo)點(diǎn)擊還是觸屏點(diǎn)擊或者鍵盤(pán)各種動(dòng)作來(lái)源痰腮,只要被點(diǎn)擊而芥,就有一種槽函數(shù)去處理,對(duì)減少代碼量很重要膀值。
所有控件都支持信號(hào)與槽機(jī)制蔚出,預(yù)定義信號(hào)和槽〕嬉福控件觸發(fā)后骄酗,QT默認(rèn)的機(jī)制就是發(fā)出信號(hào),就不管了悦冀,信號(hào)需要連接到槽才能獲得處理趋翻。預(yù)定義的信號(hào)和槽(即內(nèi)置的一些動(dòng)作和響應(yīng)事件)可以連接到一起,零代碼實(shí)現(xiàn)一定功能盒蟆,但是功能有限踏烙,需要自己使用代碼去擴(kuò)展师骗。
不同控件發(fā)射出的信號(hào)類(lèi)型可能不同,比如按鈕只有點(diǎn)擊信號(hào)發(fā)出來(lái)不帶有參數(shù)讨惩,但是輸入框可能發(fā)出的信號(hào)可能會(huì)帶有一段字符串辟癌。
pyqt比C++版的QT更加強(qiáng)大,C++版的qt的槽函數(shù)必須固定格式聲明荐捻,定義以及實(shí)現(xiàn)黍少,pyqt槽函數(shù)的特點(diǎn)是可以是任何能夠調(diào)用的東西,也沒(méi)有特殊格式要求处面。
通過(guò)代碼連接信號(hào)與槽
1. 手動(dòng)連接信號(hào)與槽的方法有以下幾種:
這些方法是在生成的GUI主類(lèi)里面的初始化函數(shù)中去實(shí)現(xiàn)厂置,或者是自定義一個(gè)函數(shù)去實(shí)現(xiàn)這個(gè)信號(hào)與槽的連接。
self.connect(widgets, SIGNAL("signal"),func)
# widgets控件魂角,這個(gè)控件帶有一個(gè)信號(hào)參數(shù)昵济,引號(hào)里面signal表示信號(hào)名稱,比如click野揪,拖拽之類(lèi)的访忿,func就是pyqt定義的槽函數(shù),可以是自己去定義的一個(gè)函數(shù)來(lái)實(shí)現(xiàn)
self.connect(widgets, SIGNAL("signal"), instance.methodname)
# instance.methodname 這個(gè)是調(diào)用一個(gè)類(lèi)其他控件的方法斯稳,這個(gè)方法與上一個(gè)不同的是醉顽,上一個(gè)直接自己定義的槽函數(shù),第二種是從已有的類(lèi)里邊去調(diào)用一個(gè)方法作為槽函數(shù)
self.connect(widgets, SIGNAL("signal"), instance, SLOT("slotSignature"))
# 前面一樣平挑,是哪一個(gè)控件,去發(fā)出一個(gè)信號(hào)系草,然后instance去實(shí)現(xiàn)這個(gè)槽函數(shù)通熄,這個(gè)instance是另外一個(gè)控件,slotSignature自定義的槽去接受前面發(fā)出的信號(hào)找都。
2. Eric生成槽函數(shù)
類(lèi)似python的核心價(jià)值觀唇辨,方便,eric可以自動(dòng)生成能耻,就不要手動(dòng)編寫(xiě)赏枚。以一個(gè)push button
來(lái)做測(cè)試,首先需要記住這button
的編號(hào),實(shí)現(xiàn)步驟如下:
步驟1:在form欄中晓猛,在ui文件上鼠標(biāo)右鍵選擇饿幅,generate dialog code,出現(xiàn)一個(gè)彈框戒职,需要設(shè)置classname
栗恩,點(diǎn)擊new新增一個(gè)會(huì)出來(lái)一個(gè)彈框,默認(rèn)里面內(nèi)容洪燥。
步驟2: 在彈窗下面找到剛才指定的push button
磕秤,點(diǎn)開(kāi)前面的三角符號(hào)乳乌,出來(lái)一系列動(dòng)作。on_pushButton_3_clicked()
表示在這個(gè)控件上的點(diǎn)擊事件市咆。勾選后點(diǎn)擊OK汉操。
之后我們會(huì)看到工程項(xiàng)目下自動(dòng)生成了一個(gè)文件,名字與項(xiàng)目名字相同的一個(gè)py文件蒙兰。這個(gè)文件就包含了對(duì)信號(hào)的處理磷瘤,單獨(dú)運(yùn)行這個(gè)文件是無(wú)法顯示窗體的,因?yàn)檫@個(gè)文件中癞己,類(lèi)沒(méi)有實(shí)例化膀斋。需要自己補(bǔ)充代碼,并且運(yùn)行痹雅。
Eric如何連接信號(hào)與槽
沒(méi)有使用IDE去連接信號(hào)和槽仰担,實(shí)際上,Eric6自動(dòng)生成的代碼里面有一句調(diào)用了setupUi函數(shù)绩社,其中最后一句就很有用摔蓝。關(guān)于文件中代碼的作用見(jiàn)代碼注釋。
QtCore.QMetaObject.connectSlotsByName(MainWindow)
# 調(diào)用這個(gè)函數(shù)之后愉耙,pyqt就做了一件事情贮尉,自動(dòng)連接信號(hào)與槽通過(guò)控件的名字去連接
如何編寫(xiě)槽函數(shù)
告別拖曳式編輯信號(hào)和槽,拖曳方式實(shí)現(xiàn)的功能實(shí)在有限朴沿,通過(guò)代碼實(shí)現(xiàn)猜谚,更加靈活,可以實(shí)現(xiàn)復(fù)雜的功能赌渣,Pyqt開(kāi)發(fā)過(guò)程中魏铅,主要的代碼也就是實(shí)現(xiàn)槽函數(shù)的地方。首先注釋掉自動(dòng)生成的槽函數(shù)中拋出異常的這句代碼raise NotImplementedError
坚芜,然后編寫(xiě)要執(zhí)行的內(nèi)容览芳。
下面是push button
修改文本框顯示內(nèi)容并且在控制臺(tái)輸出內(nèi)容的槽函數(shù)例子:
@pyqtSlot()
# 裝飾器,避免重復(fù)命名產(chǎn)生錯(cuò)誤
def on_pushButton_3_clicked(self):
# 自動(dòng)生成的槽函數(shù)很傻鸿竖,只有函數(shù)聲明沧竟,沒(méi)有定義
"""
Slot documentation goes here.
這是測(cè)試按鈕的槽函數(shù)
"""
# TODO: not implemented yet
# raise NotImplementedError
# 這句話就是拋出異常,就是槽函數(shù)還沒(méi)有實(shí)現(xiàn)
print ('按鈕被按下')
# 注意缚忧,我們使用的是python3悟泵,關(guān)于print函數(shù)需要使用括號(hào)
self.label.setText(u'修改文本框內(nèi)容測(cè)試成功啦')
總的來(lái)說(shuō),在有好的IED工具基礎(chǔ)上闪水,我們可以使用界面化的方式完成pyqt開(kāi)發(fā)GUI的界面快速布局魁袜,然后再自己完成槽函數(shù)部分,這樣開(kāi)發(fā)的效率也很快,不用自己寫(xiě)代碼布局盡量就不寫(xiě)代碼峰弹,還節(jié)約時(shí)間店量。Eric6可以自己調(diào)用qt designer,快速設(shè)計(jì)界面以及簡(jiǎn)單的低級(jí)信號(hào)和槽鞠呈。最主要的寫(xiě)代碼部分也就是鏈接好以后補(bǔ)充槽函數(shù)的內(nèi)容融师,以及實(shí)現(xiàn)py文件的啟動(dòng)部分,弄清楚窗口間的繼承關(guān)系蚁吝。