Python+Qt Quick:一種便捷的桌面軟件開發(fā)模式

引言

Python大家都耳熟能詳,Qt Quick是自Qt 4.7發(fā)布的一種方式有別于傳統(tǒng)的界面開發(fā)技術(shù)辆床,從名字就能看出它追求便捷的目標佳晶。Qt Quick為Qt引入了一門叫QML(Qt Meta/Modeling Language)的腳本語言,它是ECMAScript標準的實現(xiàn)讼载,意即轿秧,有著和JavaScript一樣的語法(學過JS的朋友上手非常容易)。這意味著我們可以和開發(fā)網(wǎng)頁一樣開發(fā)程序界面咨堤,想想是不是還有點小激動呢菇篡。

開發(fā)平臺:Windows 7/10

分享一下涉及到的資源文件:http://pan.baidu.com/s/1cpftDk

開發(fā)環(huán)境搭建

■ Python

Python官網(wǎng)下載最新版(當前為3.6.1)安裝包,因為最終做出來的程序最好同時能在32位和64位機器上運行一喘,所以選擇x86版本的驱还,安裝在自己喜歡的路徑,比如:C:\Python\Python36-32凸克,并加環(huán)境變量(C:\Python\Python36-32C:\Python\Python36-32\Scripts)议蟆。

■ PyQt

PyQt是Qt的Python binding,最新版本是5.8.2萎战,可惜它在后續(xù)程序打包發(fā)布的時候存在bug(會按開發(fā)環(huán)境的絕對路徑尋找PyQt控件的資源圖片咐容,結(jié)果必然是找不到),因此我找到了PyQt 5.7.1蚂维,下載wheel文件PyQt5-5.7.1-5.7.1-cp34.cp35.cp36.cp37-none-win32.whl(我保存到了D盤根目錄下)戳粒,安裝:

pip3 install D:\PyQt5-5.7.1-5.7.1-cp34.cp35.cp36.cp37-none-win32.whl

■ Qt Creator

這是Qt提供的集成開發(fā)環(huán)境路狮,我們用Qt Quick其實不需要靠它拖控件,直接手敲所有代碼就行蔚约,但我仍建議你安裝奄妨,用它編輯QML代碼,有高亮炊琉、糾錯展蒂、標識符匹配提選等功能,同時包含有Qt文檔苔咪,可以快速查閱各個類的使用方法锰悼。

官網(wǎng)下載不但需要注冊賬號,還需要填一份承諾式的問卷团赏,讀者可以直接使用我分享的安裝包箕般。

安裝時勾選「msvc2015」組件即可,因為它包含了Qt文檔舔清。
QML文件在Qt Creator中編輯的效果

程序開發(fā)

推薦《Qt Quick核心編程》丝里,結(jié)合Qt文檔,可以解決95%以上的問題体谒,我在這里只談及一些比較重要的或很難搜到的點(示例代碼取自之前開發(fā)的次第程序)杯聚。

《Qt Quick核心編程》

■ Python與QML的結(jié)合

這種開發(fā)模式不再是通過不斷調(diào)用庫函數(shù)來生成、設(shè)置界面元素抒痒,界面乃至操作層面的響應(yīng)邏輯全部以ECMAScript的腳本形式存在幌绍,99%的代碼的都在QML文件,由Python把它驅(qū)動起來:

# cidi.py
from PyQt5.QtCore import QUrl
from PyQt5.QtGui import QGuiApplication
from PyQt5.QtQml import QQmlApplicationEngine

if __name__ == '__main__':
    app = QGuiApplication([])
    engine = QQmlApplicationEngine()
    engine.load(QUrl('./res/cidi.qml')) #QML文件的相對路徑
    app.exec_()

最簡單的QML文件示例:

// ./res/cidi.qml
import QtQuick 2.7
import QtQuick.Window 2.0

Window {
    title: qsTr("次第 3.0.0")
    visible: true
}

運行(我把代碼文件放在D:\cidi\\目錄下):

python d:\cidi\cidi.py

當然我個人喜歡寫個批處理放在旁邊故响,每次直接雙擊就行:

@echo off
python cidi.py
pause

眾所周知傀广,Qt的事件處理機制靠信號和槽實現(xiàn),PyQt中有多種使用方式彩届,我覺得將Python類注冊到Qt的做法最清晰伪冰、便捷。例如定義一個判斷文件路徑是否為文件夾的方法(槽)樟蠕,使用注解@pyqtSlot描述參數(shù)和返回值的類型:

# cidi.py
from PyQt5.QtCore import QUrl, QObject, pyqtSlot, QFileInfo
from PyQt5.QtGui import QGuiApplication
from PyQt5.QtQml import QQmlApplicationEngine

class Dealer(QObject):
    @pyqtSlot(str, result=bool)
    def isDir(self, url):
        fileInfo = QFileInfo(url)
        return fileInfo.isDir()

if __name__ == '__main__':
    app = QGuiApplication([])
    qmlRegisterType(Dealer, "cidi.qt.Dealer", 1, 0, "Dealer") #將Dealer注冊到Qt
    engine = QQmlApplicationEngine()
    engine.load(QUrl('./res/cidi.qml'))
    app.exec_()
// ./res/cidi.qml
import QtQuick 2.7
import QtQuick.Window 2.0
import cidi.qt.Dealer 1.0 //像模塊一樣導(dǎo)入

Window {
    title: qsTr("次第 3.0.0")
    visible: true

    //像一般控件一樣定義后使用
    Dealer {
        id: dealer
    }

    //可以在任何地方直接調(diào)dealer.isDir(pathStr)使用
}

■ 設(shè)置程序icon

即程序窗口左上角的小圖標贮聂。在QGuiApplication實例化語句后添加:

QGuiApplication.setWindowIcon(QIcon("./res/cidi.ico"))

icon制作推薦Axialis IconWorkshop,試過諸多工具坯墨,唯有Axialis能生成256×256的超大圖標(此處不需要這么大寂汇,但程序發(fā)布時需要),但它的試用版只能用一個月捣染,暫時沒找到破解版骄瓣。

發(fā)布

需要發(fā)布的是Python程序,Qt作為其庫被它調(diào)用即可。Python的打包工具大抵有py2exe榕栏、PyInstallercx_Freeze三種畔勤,其中py2exe只支持到Python 2.7,PyInstaller支持到3.5但操作起來比較復(fù)雜(反正我試了一下沒搞定)扒磁,cx_Freeze支持到3.6且操作便捷庆揪,缺點是會把許多沒用到的庫也打包進來,需要手動篩減妨托,但可能前兩者也存在同樣的問題缸榛。

安裝和使用cx_Freeze

PyPI下載cx_Freeze-5.0.1-cp36-cp36m-win32.whl,安裝:

pip3 install D:\cx_Freeze-5.0.1-cp36-cp36m-win32.whl

注意莫把whl文件放在中文路徑下兰伤,不知為何内颗,pip3似乎不支持。

與其他Python工具不同的是敦腔,cx_Freeze裝完后均澳,Scripts文件夾下居然沒有相應(yīng)的可執(zhí)行文件:

只有三個沒有后綴的文件

我一臉懵逼,根本不知道怎么用符衔,試了幾次才琢磨出來找前。先切換到Scripts目錄:

cd C:\Python\Python36-32\Scripts

使用python cxfreeze -h命令查看cx_Freeze文檔:

有些選項如目標路徑、圖標設(shè)置一目了然判族,有些選項不明所以躺盛。官網(wǎng)和一些技術(shù)博客喜歡介紹編輯一個setup.py文件的使用方法,但我覺得一般使用不需要這么復(fù)雜形帮,一句簡單的命令足矣:

python cxfreeze --target-dir="d:/cidi/dist" --icon="d:/cidi/res/cidi.ico" --base-name=win32gui D:\cidi\cidi.py
  • --base-name選項指定生成目錄颗品。
  • --icon選項用于嵌入圖標文件,即最終所得exe文件的圖標沃缘。
  • --base-name=win32gui選項隱藏Python的控制臺黑框,調(diào)試時可去掉则吟。

這條命令下去槐臀,只見命令行刷刷地滾動,D:\cidi\\目錄下分分鐘多了個200M左右(嚇死人)的dist文件夾氓仲,里頭內(nèi)容狗血式的豐富:

一堆Python和Qt庫水慨,Qt占了大半體積,需要人工甄別哪些是沒用的(這一過程并不復(fù)雜)敬扛。

我的次第程序最終刪減到30余M晰洒,這一數(shù)量級還是可以接受的。

注意事項

  • 也許是PyQt庫的bug啥箭,生成的文件無法在中文路徑下運行谍珊,但我們可以通過動態(tài)設(shè)置PyQt查找模塊的路徑(原路徑可能存在字符編碼的問題)來解決這一問題:
engine.setImportPathList([sys.path[0] + "/PyQt5/Qt/qml"]) #engine為QQmlApplicationEngine實例
  • Python 3.6基于VS 2015,部分缺少其庫的電腦需要安裝「Visual C++ Redistributable for Visual Studio 2015」補丁才能運行我們發(fā)布的程序急侥。

  • Python從3.5開始不再支持XP砌滞,我們的程序要求系統(tǒng)至少是Vista侮邀。同時,所用的PyQt版本可能對顯卡提出要求贝润,太老舊的電腦hold不住绊茧。一句話,新的技術(shù)需要新的環(huán)境打掘。

  • 生成的主程序(即可執(zhí)行程序)在修改文件名后無法正常運行华畏,這個問題有待后續(xù)解決。

比如我把它命名成「次第.exe」


2017年4月25日尊蚁、26日 蘇州

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末亡笑,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子枝誊,更是在濱河造成了極大的恐慌况芒,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,378評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件叶撒,死亡現(xiàn)場離奇詭異绝骚,居然都是意外死亡,警方通過查閱死者的電腦和手機祠够,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,970評論 3 399
  • 文/潘曉璐 我一進店門压汪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人古瓤,你說我怎么就攤上這事止剖。” “怎么了落君?”我有些...
    開封第一講書人閱讀 168,983評論 0 362
  • 文/不壞的土叔 我叫張陵穿香,是天一觀的道長。 經(jīng)常有香客問我绎速,道長皮获,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,938評論 1 299
  • 正文 為了忘掉前任纹冤,我火速辦了婚禮洒宝,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘萌京。我一直安慰自己雁歌,他們只是感情好,可當我...
    茶點故事閱讀 68,955評論 6 398
  • 文/花漫 我一把揭開白布知残。 她就那樣靜靜地躺著靠瞎,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上较坛,一...
    開封第一講書人閱讀 52,549評論 1 312
  • 那天印蔗,我揣著相機與錄音,去河邊找鬼丑勤。 笑死华嘹,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的法竞。 我是一名探鬼主播耙厚,決...
    沈念sama閱讀 41,063評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼岔霸!你這毒婦竟也來了薛躬?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,991評論 0 277
  • 序言:老撾萬榮一對情侶失蹤呆细,失蹤者是張志新(化名)和其女友劉穎型宝,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體絮爷,經(jīng)...
    沈念sama閱讀 46,522評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡趴酣,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,604評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了坑夯。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片岖寞。...
    茶點故事閱讀 40,742評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖柜蜈,靈堂內(nèi)的尸體忽然破棺而出仗谆,到底是詐尸還是另有隱情,我是刑警寧澤淑履,帶...
    沈念sama閱讀 36,413評論 5 351
  • 正文 年R本政府宣布隶垮,位于F島的核電站,受9級特大地震影響秘噪,放射性物質(zhì)發(fā)生泄漏岁疼。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,094評論 3 335
  • 文/蒙蒙 一缆娃、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧瑰排,春花似錦贯要、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,572評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春宅广,著一層夾襖步出監(jiān)牢的瞬間葫掉,已是汗流浹背末盔。 一陣腳步聲響...
    開封第一講書人閱讀 33,671評論 1 274
  • 我被黑心中介騙來泰國打工修陡, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留群凶,地道東北人拍顷。 一個月前我還...
    沈念sama閱讀 49,159評論 3 378
  • 正文 我出身青樓谜慌,卻偏偏與公主長得像籽暇,于是被迫代替她去往敵國和親洞拨。 傳聞我的和親對象是個殘疾皇子罢浇,可洞房花燭夜當晚...
    茶點故事閱讀 45,747評論 2 361

推薦閱讀更多精彩內(nèi)容