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

引言

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

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

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

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

■ Python

Python官網下載最新版(當前為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控件的資源圖片,結果必然是找不到),因此我找到了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文檔,可以快速查閱各個類的使用方法。

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

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

程序開發(fā)

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

《Qt Quick核心編程》

■ Python與QML的結合

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

# 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的事件處理機制靠信號和槽實現,PyQt中有多種使用方式,我覺得將Python類注冊到Qt的做法最清晰、便捷。例如定義一個判斷文件路徑是否為文件夾的方法(槽),使用注解@pyqtSlot描述參數和返回值的類型:

# 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 //像模塊一樣導入

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

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

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

■ 設置程序icon

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

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

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

發(fā)布

需要發(fā)布的是Python程序,Qt作為其庫被它調用即可。Python的打包工具大抵有py2exe、PyInstallercx_Freeze三種,其中py2exe只支持到Python 2.7,PyInstaller支持到3.5但操作起來比較復雜(反正我試了一下沒搞定),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文件夾下居然沒有相應的可執(zhí)行文件:

只有三個沒有后綴的文件

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

cd C:\Python\Python36-32\Scripts

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

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

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的控制臺黑框,調試時可去掉。

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

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

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

注意事項

  • 也許是PyQt庫的bug,生成的文件無法在中文路徑下運行,但我們可以通過動態(tài)設置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不住。一句話,新的技術需要新的環(huán)境。

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

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


2017年4月25日、26日 蘇州

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容