程式語言:Python
Package:PyQt5
官網
官網文件
功能:建立 GUI 人機介面
範例
簡單視窗
import sys
from PyQt5.QtWidgets import QApplication, QWidget
if __name__ == '__main__':
# Qt GUI 需要唯一一個 QApplication 負責管理,可傳入 sys.argv 參數
app = QApplication(sys.argv)
# 建立 QWidget
w = QWidget()
# 設定尺寸
w.resize(250, 150)
# 設定位置
w.move(300, 300)
# 設定標題
w.setWindowTitle('Simple')
# 顯示,因圖形元件被創造時都是 hidden 狀態
w.show()
# app.exec_() 讓 QApplication 進入 event loop
# exec 是 Python keyword,所以會多出底線
sys.exit(app.exec_())
簡單按鈕
import sys
from PyQt5.QtWidgets import QApplication, QPushButton
if __name__ == '__main__':
# Qt GUI 需要唯一一個 QApplication 負責管理,可傳入 sys.argv 參數
app = QApplication(sys.argv)
# & + 字元,可設定快捷鍵 Alt + E
# Qt 設定 action focus 的簡便方法
button = QPushButton("H&ello!")
# 設定尺寸
button.resize(200, 75)
# 設定位置
button.move(500, 400)
# 設定視窗標題
button.setWindowTitle("Hello World")
# 顯示,因圖形元件被創造時都是 hidden 狀態
button.show()
# app.exec_() 讓 QApplication 進入 event loop
# exec 是 Python keyword,所以會多出底線
sys.exit(app.exec_())
簡單排版
- 由上到下的概念
- 通常只需要一個 top-level window,也就是 parent 為 None
- top-level window 擁有標題列和邊框
- 每個 widget 可有其所屬的 parent ( 預設參數 parent=None )
- 當 parent 解構時,child 們也會一同解構
- 如何成為 parent
- 當 A 調用 addWidget(w),A 就會成為 w 的 parent
- 當 A 調用 setLayout(layout) ,A 就會成為 layout 的 parent,並接管 layout 的所有 child
- 不只這些,不同物件有不同的 function
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QHBoxLayout
if __name__ == '__main__':
# Qt GUI 需要唯一一個 QApplication 負責管理,可傳入 sys.argv 參數
app = QApplication(sys.argv)
# & + 字元,可設定快捷鍵 Alt + E
# Qt 設定 action focus 的簡便方法
ok = QPushButton("&OK")
cancel = QPushButton("&Cancel")
# 基本排版元件,有 QHBoxLayout() & QVBoxLayout()
layout = QHBoxLayout()
# 加入 ok button 並設為 child
layout.addWidget(ok)
# 加入彈簧元件,可將兩邊元件推到底,用在視窗放大時的介面調整
# 數量可設定,增加彈力
layout.addStretch(1)
# 加入 cancel button 並設為 child
layout.addWidget(cancel)
# 加入彈簧元件,可將兩邊元件推到底,用在視窗放大時的介面調整
# 數量可設定,增加彈力
layout.addStretch(2)
# 建立 widget 元件,並為 top-level window
widget = QWidget()
# 設定 layout 元件,並設為 child
widget.setLayout(layout)
# 顯示,因圖形元件被創造時都是 hidden 狀態
widget.show()
# app.exec_() 讓 QApplication 進入 event loop
# exec 是 Python keyword,所以會多出底線
sys.exit(app.exec_())
簡單 Signals & Slots 範例
- 多 singals 對 多 slots
- slots 可為任意 function
- 參數可為 Python 任意型態
- signal 與 signal 可互相連接,產生連鎖反應
- 可 connect,也可 disconnect
import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QHBoxLayout, QSpinBox, QSlider, QMessageBox
def helloWorld():
QMessageBox.information(None, 'Message', 'Hello World', QMessageBox.Ok)
if __name__ == '__main__':
# Qt GUI 需要唯一一個 QApplication 負責管理,可傳入 sys.argv 參數
app = QApplication(sys.argv)
# & + 字元,可設定快捷鍵 Alt + E
# Qt 設定 action focus 的簡便方法
button = QPushButton("H&ello!")
# 建立 QSpinBox
spinBox = QSpinBox()
# 設定前罝符號
spinBox.setPrefix("$")
# 設定範圍
spinBox.setRange(0, 100)
# 建立橫向 QSlider
slider = QSlider(Qt.Horizontal)
# 設定範圍
slider.setRange(0, 100)
# signals 連接 slots
button.clicked.connect(helloWorld)
spinBox.valueChanged.connect(slider.setValue)
slider.valueChanged.connect(spinBox.setValue)
# 基本排版元件,有 QHBoxLayout() & QVBoxLayout()
layout = QHBoxLayout()
# 加入 ok button 並設為 child
layout.addWidget(button)
# 加入 spinBox 並設為 child
layout.addWidget(spinBox)
# 加入彈簧元件,可將兩邊元件推到底,用在視窗放大時的介面調整
# 數量可設定,增加彈力
layout.addStretch(1)
# 加入 slider 並設為 child
layout.addWidget(slider)
# 加入彈簧元件,可將兩邊元件推到底,用在視窗放大時的介面調整
# 數量可設定,增加彈力
layout.addStretch(2)
# 建立 widget 元件,並為 top-level window
widget = QWidget()
# 設定 layout 元件,並設為 child
widget.setLayout(layout)
# 顯示,因圖形元件被創造時都是 hidden 狀態
widget.show()
# app.exec_() 讓 QApplication 進入 event loop
# exec 是 Python keyword,所以會多出底線
sys.exit(app.exec_())
簡單 OOP 寫法
建議使用 OOP 撰寫 PyQt
import sys
from PyQt5.QtWidgets import QApplication, QWidget
from PyQt5.QtGui import QIcon
class Example(QWidget):
def __init__(self, parent = None):
# 繼承的 parent 初始化 fucntion
super().__init__(parent)
self.initUI()
def initUI(self):
# 設定位置尺寸
# 同 self.move(300, 300)
# 同 self.resize(250, 150)
self.setGeometry(300, 300, 250, 150)
# 設定標題
self.setWindowTitle('Simple')
# 顯示,因圖形元件被創造時都是 hidden 狀態
self.show()
if __name__ == '__main__':
# Qt GUI 需要唯一一個 QApplication 負責管理,可傳入 sys.argv 參數
app = QApplication(sys.argv)
# 建立 Exxample instance
ex = Example()
# app.exec_() 讓 QApplication 進入 event loop
# exec 是 Python keyword,所以會多出底線
sys.exit(app.exec_())
簡單 Main Window 範例
- QMainWindow
- 預設內建 menubar、toolbar 跟 status bar
- QWidget 可擁有這些元件,但必須自行調整
- 擁有自己的 layout 風格如圖,無法變更
- central widget 必須被指定,不然顯示會有問題
import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QMainWindow, QWidget, QDockWidget, QHBoxLayout, QPushButton, QTextEdit, QAction, QApplication, QDesktopWidget
from PyQt5.QtGui import QIcon
class Example(QMainWindow):
def __init__(self, parent = None):
# 繼承的 parent 初始化 fucntion
super().__init__(parent)
self.initUI()
def initUI(self):
# & + 字元,可設定快捷鍵 Alt + 字元
# Qt 設定 action focus 的簡便方法
button1 = QPushButton("H&ello1!")
button2 = QPushButton("&Hello2!")
# 基本排版元件,有 QHBoxLayout() & QVBoxLayout()
layout = QHBoxLayout()
# 加入 button 並設為 child
layout.addWidget(button1)
layout.addWidget(button2)
# 建立 QWidget 元件
widget = QWidget()
# 設定 layout 元件,並設為 child
widget.setLayout(layout)
# 設定主要 widget
self.setCentralWidget(widget)
# 建立 QTextEdit
textEdit = QTextEdit()
# 建立 QDockWidget 附屬視窗
dockwidget = QDockWidget()
# 設定特性 AllDockWidgetFeatures => DockWidgetClosable | DockWidgetMovable | DockWidgetFloatable
dockwidget.setFeatures(QDockWidget.DockWidgetClosable)
# 設定可能的擺放位置
dockwidget.setAllowedAreas(Qt.LeftDockWidgetArea|Qt.TopDockWidgetArea)
# 設定 widget 為 textEdit 並設為 child
dockwidget.setWidget(textEdit)
# 可由 allowedAreas() 得知可擺放的位置,但不理會也會成功設定
self.addDockWidget(Qt.RightDockWidgetArea, dockwidget);
# 建立 QAction 並設置 Icon,Parent 為 self
# QAction 可用在 menu 或 toolbar,且可重覆使用
# exit.jpg 需自行定義
exitAction = QAction(QIcon('exit.jpg'), 'Exit', self)
# 設定快捷鍵
exitAction.setShortcut('Ctrl+Q')
# 設定 status bar 顯示
exitAction.setStatusTip('Exit application')
exitAction.triggered.connect(self.close)
# 回傳 statusbar,若不存在則建立
statusbar = self.statusBar()
# 回傳 menuBar,若不存在則建立
menubar = self.menuBar()
# 建立 menu 清單
fileMenu = menubar.addMenu('&File')
# 附加 exitAction
fileMenu.addAction(exitAction)
# 回傳 toolBar,若不存在則建立
toolbar = self.addToolBar('Exit')
# 附加 exitAction
toolbar.addAction(exitAction)
# 設定尺寸
self.resize(500, 500)
# 設定標題
self.setWindowTitle('Simple')
# 顯示,因圖形元件被創造時都是 hidden 狀態
self.show()
# 確定系統已畫,尺寸才會正確
# 此時 frameGeometry 位置仍是錯的,因尚未把視窗放好
def showEvent(self, e):
super().showEvent(e)
# 視窗置中
self.center()
def center(self):
# 得到 frameGeometry 的 QRect
qr = self.frameGeometry()
# QDesktopWidget 可得到和桌面相關的資訊
# 得到桌面可用的 geometry 的中心點
cp = QDesktopWidget().availableGeometry().center()
# 將 qr 的中心點移至此中心點
qr.moveCenter(cp)
# 將視窗的左上角移至 qr 的左上角座標
self.move(qr.topLeft())
if __name__ == '__main__':
# Qt GUI 需要唯一一個 QApplication 負責管理,可傳入 sys.argv 參數
app = QApplication(sys.argv)
# 建立 Exxample instance
ex = Example()
# app.exec_() 讓 QApplication 進入 event loop
# exec 是 Python keyword,所以會多出底線
sys.exit(app.exec_())
簡單 OpenCV 範例
import sys
import cv2
from PyQt5.QtWidgets import QMainWindow, QApplication, QLabel, QScrollArea, QDesktopWidget, QSizePolicy
from PyQt5.QtGui import QImage, QPixmap, QPalette
class Example(QMainWindow):
def __init__(self, parent = None):
# 繼承的 parent 初始化 fucntion
super().__init__(parent)
self.initUI()
def initUI(self):
# 建立 QLabel 元件
imgLabel = QLabel()
# openCV 讀檔
cvImage = cv2.imread("test.jpg")
# 得到 大小 與 幾個 byte 組成一個顏色
height, width, byteValue = cvImage.shape
# 得到寬有多少 byte
byteValue = byteValue * width
# openCV 預設顏色排列為 BGR 故需再轉換為 RGB
temp = cv2.cvtColor(cvImage, cv2.COLOR_BGR2RGB)
# 設定 imgLabel 圖片
# 因 setPixmap 輸入需為 QPixmap,所以還得多做一層轉換
imgLabel.setPixmap(QPixmap().fromImage(QImage(temp, width, height, byteValue, QImage.Format_RGB888)))
# 建立 QScrollArea for 滾動圖片
scrollArea = QScrollArea()
# 設定背景顏色
scrollArea.setBackgroundRole(QPalette.Dark)
# 將 imgLabel 設定為 child
scrollArea.setWidget(imgLabel)
# 設定主要 widget
self.setCentralWidget(scrollArea)
# 設定尺寸
self.resize(500, 500)
# 視窗置中
self.center()
# 設定標題
self.setWindowTitle('Simple')
# 顯示,因圖形元件被創造時都是 hidden 狀態
self.show()
def center(self):
# 得到 frameGeometry 的 QRect
qr = self.frameGeometry()
# QDesktopWidget 可得到和桌面相關的資訊
# 得到桌面可用的 geometry 的中心點
cp = QDesktopWidget().availableGeometry().center()
# 將 qr 的中心點移至此中心點
qr.moveCenter(cp)
# 將視窗的左上角移至 qr 的左上角座標
self.move(qr.topLeft())
if __name__ == '__main__':
# Qt GUI 需要唯一一個 QApplication 負責管理,可傳入 sys.argv 參數
app = QApplication(sys.argv)
# 建立 Exxample instance
ex = Example()
# app.exec_() 讓 QApplication 進入 event loop
# exec 是 Python keyword,所以會多出底線
sys.exit(app.exec_())
簡單設計方法
使用官方的 designer.exe 設計 GUI 並存檔為 .ui
轉換方法
python -m PyQt5.uic.pyuic xxx.ui > xxx.py
PS. 直接用 pip 安裝並不會有此 designer.exe,需至官網下載安裝後才有
Componets 介紹
- 範例可使用 python qtdemo.pyw 觀看
- 位置:...\site-packages\PyQt5\examples\qtdemo
- QAxContainer
- 控制 ActiveX controls 跟 COM objects
- 不支援寫入 ActiveX servers in Python
- 只限於 Windows
- QtBluetooth
- QtCore
- 主要的核心 classes,像是 event loop 和 Qt’s signal and slot mechanism.
- 另外還有 abstractions for animations,state machines,threads,mapped files, shared memory,regular expressions 和 user and application settings
- QtDBus
- D-Bus protocol
- 不支援 Windows.
- QtDesigner
- QtGui
- windowing system integration,event handling,2D graphics,basic imaging,fonts 和 text.
- OpenGL 和 OpenGL ES bindings
- QtHelp
- QtLocation
- 控制 geocoding,navigation information,位置尋找
- QtMacExtras
- 額外的 classes for OS X 和 iOS
- QtMultimedia
- multimedia content and APIs to access camera and radio functionality
- QtMultimediaWidgets
- 元件可 handle multimedia content
- QtNetwork
- UDP and TCP clients and servers
- HTTP clients and support DNS lookups
- QtNfc
- QtOpenGL
- QtPositioning
- 定位借由 satellite,Wi-Fi,a text file,and so on
- QtPrintSupport
- 影印功能,甚至可產生 PostScript 和 PDF
- QtQml
- QtQuick
- 基本元件 for creating user interfaces with QML.
- QtQuickWidgets
- 顯示 QML scene in a traditional widget.
- QtSensors
- Sensor 控制,像是 accelerometers,altimeters,ambient light,temperature sensors,gyroscopes 和 magnetometers
- 未支援 gestures
- QtSerialPort
- QtSql
- QtSvg
- QtTest
- 測試
- PyQt5 不支援,因 python 本身有更好用的 unittest
- QtWebChannel
- 控制 QObject or QML objects from HTML clients.
- QtWebEngine
- Web Engine objects created in QML to Python.
- QtWebEngineCore
- QtWebEngineWidgets 的核心 classes
- QtWebEngineWidgets
- Chromium based implementation of a web browser
- 取代 QtWebKit 擁有更好的功能,但消耗更多資源,且無法直接利用 Python APIs 控制 network 跟 HTML
- Windows 只支援 v3.5+
- QtWebKit
- WebKit2 based implementation of a web browser
- QtWebKitWidgets
- WebKit1 based implementation of a web browser
- QtWebSockets
- WebSocket protocol described in RFC 6455
- QtWidgets
- QtWinExtras
- QtX11
- QtXml
- SAX and DOM interfaces to Qt’s XML parser.
- QtXmlPatterns
- XPath, XQuery, XSLT and XML Schema validation.
- Enginio
- Qt Cloud Services Managed Application Runtime.
- Qt
- uic
- 控制 .ui files created by Qt Designer
- 轉換指令:python -m PyQt5.uic.pyuic xxx.ui > xxx.py
參考
PyQt5 tutorial
PyQt 实践教学(一)--First programs in PyQt5
[PyQt 教學] Part 1: Introduction
留言
張貼留言