本文旨在通過一個簡單的demo,介紹基於Python3、PyQT5的環境下開發桌面應用程序的一種方案,當然開發Python的桌面應用程序不止是PyQT 這一種方案,還可以使用Python自帶的Tkinter 來實現。
本文目錄:
1. 安裝依賴環境
Eric6官網:http://eric-ide.python-projects.org/
Eric6 依賴的組件必須先安裝好,依賴組件列表如下:
依賴:
為了使用 eric6 你應該預先安裝好下列組件:
- Python 3.4.0 or better
- Python 2.7.10 or better
- Qt 5.3.0 or better (from The Qt Company)
- Qt 4.8.0 or better (from The Qt Company)
- PyQt 5.3.0 or better (from Riverbank)
- PyQt 4.10.0 or better (from Riverbank)
- QScintilla 2.8.0 or better (from Riverbank)
組件太多,並且他們之間的依賴關系一言不合就出錯,這里介紹個比較好的集成環境 Anaconda3 (64-bit) ,用它來安裝Pyqt等可以比較省心。
我本機的環境是:
- Win7 64位
- Anaconda 3-5.2.0-Windows-x86_64
- Python 3.6.5
- pip 10.0.1
- Eric6 18.10
- Pyqt 5.9.2
- QScintilla
- PyInstaller 3.5.dev0
其中QScintilla
是通過命令pip3 install QScintilla
安裝的。
2. 安裝Eric6
依賴環境都搞定后,下載Eric6:
Eric6穩定版官方下載地址:Eric6-18 :點我去下載
由於18.0版本開始沒有了漢化包(或者是現在到了18.10版本都還沒有出來?),我們可以用17.12里面的中文包來達到漢化的目標。
Eric6-17.12:點我去下載
下載后,把18.10的主程序zip包解壓,然后把17.12這個中文語言包解壓,覆蓋到18.10目錄,然后在cmd進入這個18.10主程序包解壓目錄,執行下面的命令安裝:
pyton install.py
安裝完成后啟動,雙擊eric6.cmd
文件啟動(我的因為是安裝了Anaconda3,所以這個cmd文件所在路徑為:C:\ProgramData\Anaconda3\Scripts
),如果界面是中文的表示前面的漢化操作成功。
這里有個小問題,雙擊這個批處理啟動的時候,會一閃而過一個黑色的cmd窗口,不能忍,用一個簡單的方法搞定… ,給這個文件創建個快捷方式發送到桌面,然后在這個快捷方式上右鍵屬性,在運行方式
那里把【常規窗口
】改為 最小化:
然后點應用-確定,下次雙擊啟動就妥妥的看不到一閃而過的憂傷了…
3. 配置Eric
啟動eric6后,界面如下,可以看到中文漢化成功:
首次啟動,會自動彈出對配置對話框提示讓你配置信息,如果你錯過了也沒關系,從Eric6的應用程序界面菜單[設置-首選項]
進入,具體配置如下:
從菜單的
插件-插件
存儲庫進入,安裝jedi
插件:
最后配置一下默認工作目錄:
4. 創建窗口應用
4.1 創建窗體UI
然后項目文件夾多了以下內容:
回到Eric6界面,左側的源碼Tab頁簽切換到GUI窗體頁簽,右鍵選擇
新建窗體
:
然后會引導你選擇位置保存這個窗體文件,然后會自動進入QT Designer設計界面:
這個界面,就跟MFC的設計界面差不多,哈哈,左側鼠標按住
Push Button
按鈕控件不放,拖動至中間的窗體中,然后雙擊這個控件,輸入名字:測試按鈕
,再添加一個text文本控件,然后設置窗體名字:
4.2 實現代碼邏輯
在前面設計好ui界面后,保存代碼並關閉QT Designer窗口回到Eric6界面
然后在左側ui文件上右鍵選擇
編譯窗體
生成ui界面組件對應的python代碼:
這時會在項目目錄生成一個Ui_Test.py 腳本文件,內容如下:
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'D:\andy\Rep\eric6\Test.ui'
#
# Created by: PyQt5 UI code generator 5.11.3
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_dialog(object):
def setupUi(self, dialog):
dialog.setObjectName("dialog")
dialog.resize(400, 343)
dialog.setSizeGripEnabled(True)
# 定義的按鈕
self.pushButton = QtWidgets.QPushButton(dialog)
self.pushButton.setGeometry(QtCore.QRect(130, 120, 75, 23))
self.pushButton.setObjectName("pushButton")
# 定義的文本
self.plainTextEdit = QtWidgets.QPlainTextEdit(dialog)
self.plainTextEdit.setGeometry(QtCore.QRect(110, 170, 181, 31))
self.plainTextEdit.setObjectName("plainTextEdit")
self.retranslateUi(dialog)
QtCore.QMetaObject.connectSlotsByName(dialog)
def retranslateUi(self, dialog):
_translate = QtCore.QCoreApplication.translate
dialog.setWindowTitle(_translate("dialog", "測試應用名"))
self.pushButton.setText(_translate("dialog", "測試按鈕"))
self.plainTextEdit.setPlainText(_translate("dialog", "點擊按鈕,改變此處文本"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
dialog = QtWidgets.QDialog()
ui = Ui_dialog()
ui.setupUi(dialog)
dialog.show()
sys.exit(app.exec_())
里面可以看到我們在窗體界面定義的兩個控件:按鈕、文本顯示的對應python類中的變量名為:pushButton
、plainTextEdit
接着在左側窗體視圖的UI文件上右鍵選擇生成對話框代碼:
選擇對話框上兩個控件所需的響應事件后保存:
然后切換到python源碼頁簽可以看到生成了一個py類文件,里面自動生成了剛才在對話框中選擇的兩個響應事件的代碼邏輯:
# -*- coding: utf-8 -*-
""" Module implementing dialog. """
from PyQt5.QtCore import pyqtSlot
from PyQt5.QtWidgets import QDialog
from .Ui_Test import Ui_dialog
class dialog(QDialog, Ui_dialog):
""" Class documentation goes here. """
def __init__(self, parent=None):
""" Constructor @param parent reference to the parent widget @type QWidget """
super(dialog, self).__init__(parent)
self.setupUi(self)
@pyqtSlot()
def on_pushButton_clicked(self):
""" Slot documentation goes here. """
# TODO: not implemented yet
raise NotImplementedError
@pyqtSlot()
def on_plainTextEdit_textChanged(self):
""" Slot documentation goes here. """
# TODO: not implemented yet
raise NotImplementedError
我們修改下這個類:
- 加上main方法
- 修正引用的ui資源路徑:把這里的
from .Ui_Test import Ui_dialog
那個點.去掉,否則會提示找不到這個模塊 - 修改按鈕響應函數,改變文本控件顯示的內容
- 修改文本內容改變響應函數,彈出一個消息提示框
修改完成的內容如下:
# -*- coding: utf-8 -*-
""" Module implementing dialog. """
import sys
#這里我們提供必要的引用。基本控件位於pyqt5.qtwidgets模塊中。
from PyQt5.QtWidgets import QApplication
from PyQt5.QtCore import pyqtSlot
from PyQt5.QtWidgets import QDialog, QMessageBox
from Ui_Test import Ui_dialog
class dialog(QDialog, Ui_dialog):
""" Class documentation goes here. """
def __init__(self, parent=None):
""" Constructor @param parent reference to the parent widget @type QWidget """
super(dialog, self).__init__(parent)
self.setupUi(self)
@pyqtSlot()
def on_pushButton_clicked(self):
""" Slot documentation goes here. """
# 按鈕按下,改變label標簽的文本內容
self.plainTextEdit.setPlainText(u"按鈕觸發,我改變了自己!")
@pyqtSlot()
def on_plainTextEdit_textChanged(self):
""" Slot documentation goes here. """
# TODO: not implemented yet
reply = QMessageBox.question(self, '信息', '文本框內容改變了',QMessageBox.Yes)
if __name__ == '__main__':
#每一pyqt5應用程序必須創建一個應用程序對象。sys.argv參數是一個列表,從命令行輸入參數。
app = QApplication(sys.argv)
#QWidget部件是pyqt5所有用戶界面對象的基類。他為QWidget提供默認構造函數。默認構造函數沒有父類。
dialog = dialog()
#resize()方法調整窗口的大小。這離是400px寬248px高
dialog.resize(400, 248)
#設置窗口的標題
dialog.setWindowTitle('我修改了標題')
#顯示在屏幕上
dialog.show()
#系統exit()方法確保應用程序干凈的退出
#的exec_()方法有下划線。因為執行是一個Python關鍵詞。因此,exec_()代替
sys.exit(app.exec_())
然后點擊Eric6應用的菜單:
項目-屬性
,配置主腳本為我們這個Test.py
:
最后,通過菜單或者快捷鍵Ctrl+F2啟動我們這個對話框應用:
點擊按鈕后:
5. 打包py腳本輸出exe
5.1 安裝pyinstaller
下載pyinstaller源碼,源碼github地址,有時候用git拉取下來網速很慢,這里可以從csdn下載我上傳的最新版本(20181026更新的):點我下載20181026版本源碼
然后解壓這個源碼到某個目錄,cmd進入這個解壓目錄,通過以下命令安裝:
python setup.py install
5.2 打包輸出exe程序
然后來到我們的.py源碼目錄,通過以下命令打包成exe文件:
pyinstaller -F -w -i "D:\\xxxxxx\\app.ico" Test.py
基礎的命令格式是 pyinstaller [opts] [目標程序.py]
可選的opts有:
-F, –onefile 打包成一個exe文件。
-D, –onedir 創建一個目錄,包含exe文件,但會依賴很多文件(默認選項)。
-c, –console, –nowindowed 使用控制台,無界面(默認)
-w, –windowed, –noconsole 使用窗口,無控制台
-i "D:\\xxxxxx\\app.ico"
這個是更改exe的icon,如果不需要可以去掉。
最后打包出來的exe有35MB大小… 因為把QT核心的dll文件打包在一起了,否則在沒有安裝python以及PyQt的電腦上無法運行的。
更多內容請查看:pyinstaller官方說明
參考資料:
[1]: Pyqt5官方文檔
[2]: Python3官方文檔
[3]: 廖雪峰老師的Python3 在線學習手冊
[4]: 菜鳥學堂-Python3在線學習
[5]: 其他所有分享過python學習填坑網友的經驗