PyQt6,用 Python 開發高級 GUI
Python 憑借其簡潔易用和龐大的生態系統,已成為各領域開發人員的首選語言。在創建桌面應用程序方面,Qt6 無疑是一款強大的工具包。Qt6 是 Qt 框架的最新版本,相比前代產品,它提供了增強的特性和功能,使其成為構建跨平臺 GUI 應用程序的首選。
Qt6 的設計理念是更加模塊化、高效和適應性。它在圖形處理、性能和易用性方面進行了改進,確保開發人員擁有一個強大的應用程序框架。借助 PyQt6 或 PySide6 綁定,Python 與 Qt6 的集成將 Python 的易腳本編寫能力與 Qt 豐富的 GUI 功能完美結合。
今天就跟云朵君一起學習 PyQt6 吧~
設置開發環境
要開始使用 Python 開發 Qt6 應用程序,你需要設置開發環境。這包括安裝 Python 和 Qt6 綁定。PyQt6 和 PySide6 是 Python 的兩個主要綁定。
- 安裝 Python:從官方網站下載并安裝最新版本的 Python。確保將 Python 添加到系統的 PATH 中。
- 安裝PyQt6或PySide6:
- PyQt6:你可以使用 pip 安裝 PyQt6:
pip install PyQt6- PySide6:同樣,對于 PySide6:
pip install PySide6- Qt Designer:為了直觀地設計你的應用程序,你可能需要安裝 Qt Designer,它包含在 Qt 工具包中。你也可以通過 pip 安裝它:
pip install PyQt6-tools # 對于 PyQt6
pip install pyside6-tools # 對于 PySide6基本小部件
QPushButton
QPushButton是一個可點擊的按鈕,用于執行操作或回答問題。
from PyQt6.QtWidgets import QApplication, QPushButton, QWidget, QVBoxLayout
def on_click ():
print ( '按鈕被點擊!' )
app = QApplication([])
window = QWidget()
layout = QVBoxLayout()
button = QPushButton( '點擊我' )
button.clicked.connect(on_click) # 將信號連接到插槽
layout.addWidget(button)
window.setLayout(layout)
window.show()
app. exec ()QLabel
QLabel顯示文本或圖像。它通常用于指示表單字段、提供提示或顯示圖像。
from PyQt6.QtWidgets import QApplication, QLabel, QWidget, QVBoxLayout
app = QApplication([])
window = QWidget()
layout = QVBoxLayout()
label = QLabel( 'Hello, PyQt6!' )
layout.addWidget(label)
window.setLayout(layout)
window.show()
app.exec ( )布局管理
QVBoxLayout 和 QHBoxLayout
QVBoxLayout 和 QHBoxLayout用于垂直和水平排列小部件。
from PyQt6.QtWidgets import QApplication, QPushButton, QVBoxLayout, QHBoxLayout, QWidget
app = QApplication([])
window = QWidget()
v_layout = QVBoxLayout()
h_layout = QHBoxLayout()
btn1 = QPushButton('按鈕 1')
btn2 = QPushButton('按鈕 2')
v_layout.addWidget(btn1)
h_layout.addWidget(btn2)
window.setLayout(v_layout)
window.setLayout(h_layout)
window.show()
app.exec()對話框
QMessageBox
QMessageBox用于顯示消息。
from PyQt6.QtWidgets import QApplication, QMessageBox
app = QApplication([])
msg_box = QMessageBox()
msg_box.setText( "這是一個消息框。" )
msg_box.exec ( )高級小部件
QTableView
QTableView提供使用模型來管理數據的表格視圖。
from PyQt6.QtWidgets import QApplication, QTableView, QWidget, QVBoxLayout
from PyQt6.QtCore import QAbstractTableModel, Qt
class MyTableModel(QAbstractTableModel):
def rowCount(self,parent):
return 5 # 示例行數
def columnCount(self,parent):
return 3 # 示例列數
def data(self,index,role):
if role == Qt.ItemDataRole.DisplayRole:
returnf"Cell ({index.row()},{index.column()})"
app = QApplication([])
window = QWidget()
layout = QVBoxLayout()
table_view = QTableView()
model = MyTableModel()
table_view.setModel(model)
layout.addWidget(table_view)
window.setLayout(layout)
window.show()
app.exec()圖形視圖框架
QGraphicsView 和 QGraphicsScene
QGraphicsView是一個提供QGraphicsScene可視化表示的小部件。它用于復雜的圖形和自定義項目。
from PyQt6.QtWidgets import QApplication, QGraphicsScene, QGraphicsView
app = QApplication([])
scene = QGraphicsScene()
scene.addText("Hello, PyQt6 Graphics View!")
view = QGraphicsView(scene)
view.show()
app.exec()自定義小部件
創建自定義小部件涉及從現有小部件或直接從現有小部件進行QWidget子類化,然后覆蓋方法來定制行為和外觀。
from PyQt6.QtWidgets import QApplication, QWidget, QPainter, QBrush, QPen
from PyQt6.QtCore import Qt
class CustomWidget(QWidget):
def paintEvent(self, event):
painter = QPainter(self)
painter.setPen(QPen(Qt.blue, 8, Qt.SolidLine))
painter.setBrush(QBrush(Qt.green, Qt.SolidPattern))
painter.drawRect(10, 10, 200, 200)
app = QApplication([])
custom_widget = CustomWidget()
custom_widget.show()
app.exec()輸入小部件
QLineEdit
QLineEdit小部件允許用戶輸入和編輯單行純文本。
from PyQt6.QtWidgets import QApplication, QLineEdit, QWidget, QVBoxLayout
app = QApplication([])
window = QWidget()
layout = QVBoxLayout()
line_edit = QLineEdit()
line_edit.setPlaceholderText( "輸入一些文本..." )
layout.addWidget(line_edit)
window.setLayout(layout)
window.show()
app.exec ()QTextEdit
QTextEdit提供了一個用于編輯和顯示純文本和富文本的小部件。
from PyQt6.QtWidgets import QApplication, QTextEdit, QWidget, QVBoxLayout
app = QApplication([])
window = QWidget()
layout = QVBoxLayout()
text_edit = QTextEdit()
text_edit.setPlainText( "這是一個 QTextEdit 小部件。您可以編輯我!" )
layout.addWidget(text_edit)
window.setLayout(layout)
window.show()
app. exec ()選擇小部件
QComboBox
QComboBox是一個小部件,允許用戶從選項列表中選擇或輸入自己的選項。
from PyQt6.QtWidgets import QApplication, QComboBox, QWidget, QVBoxLayout
app = QApplication([])
window = QWidget()
layout = QVBoxLayout()
combo_box = QComboBox()
combo_box.addItems(["選項 1", "選項 2" , "選項 3"])
layout.addWidget(combo_box)
window.setLayout(layout)
window.show()
app.exec()QSpinBox 和 QDoubleSpinBox
QSpinBox和QDoubleSpinBox是分別允許用戶從整數或浮點值范圍中進行選擇的小部件。
from PyQt6.QtWidgets import QApplication, QSpinBox, QDoubleSpinBox, QWidget, QVBoxLayout
app = QApplication([])
window = QWidget()
layout = QVBoxLayout()
spin_box = QSpinBox()
spin_box.setRange(0, 100)
layout.addWidget(spin_box)
double_spin_box = QDoubleSpinBox()
double_spin_box.setRange(0.0, 100.0)
layout.addWidget(double_spin_box)
window.setLayout(layout)
window.show()
app.exec()控制部件
QSlider
QSlider是一個控制小部件,允許用戶通過滑動手柄從線性范圍中選擇一個值。
from PyQt6.QtWidgets import QApplication, QSlider, QWidget, QVBoxLayout
from PyQt6.QtCore import Qt
app = QApplication([])
window = QWidget()
layout = QVBoxLayout()
slider = QSlider(Qt.Orientation.Horizontal)
slider.setRange(0 , 100 )
layout.addWidget(slider)
window.setLayout(layout)
window.show()
app.exec()QDial
QDial 與 QSlider 類似,但提供圓形撥號界面。
from PyQt6.QtWidgets import QApplication, QDial, QWidget, QVBoxLayout
app = QApplication([])
window = QWidget()
layout = QVBoxLayout()
dial = QDial()
dial.setRange(0 , 100)
layout.addWidget(dial)
window.setLayout(layout)
window.show()
app.exec()顯示小部件
QProgressBar
QProgressBar提供水平或垂直進度條。
from PyQt6.QtWidgets import QApplication, QProgressBar, QWidget, QVBoxLayout
app = QApplication([])
window = QWidget()
layout = QVBoxLayout()
progress_bar = QProgressBar()
progress_bar.setRange( 0 , 100 )
progress_bar.setValue( 75 )
layout.addWidget(progress_bar)
window.setLayout(layout)
window.show()
app.exec ( )QLCD編號
QLCDNumber以類似 LCD 的風格顯示數字。
from PyQt6.QtWidgets import QApplication, QLCDNumber, QWidget, QVBoxLayout
app = QApplication([])
window = QWidget()
layout = QVBoxLayout()
lcd_number = QLCDNumber()
lcd_number.display(123)
layout.addWidget(lcd_number)
window.setLayout(layout)
window.show()
app.exec()創建第一個 Qt6 應用程序
下面就和云朵君一起開始創建一個簡單的 Qt6 應用程序,它會打開一個帶有問候消息的窗口。此示例使用 PyQt6,但你可以通過更改 import 語句輕松地將其適配到 PySide6。
import sys
from PyQt6.QtWidgets import QApplication, QLabel, QWidget
app = QApplication(sys.argv)
window = QWidget()
window.setWindowTitle('Hello Qt6')
label = QLabel('Welcome to Qt6 with Python', window)
window.setGeometry(100, 100, 280, 80)
label.move(50, 20)
window.show()
sys.exit(app.exec())探索 Qt6 GUI 元素
小部件
小部件是 Qt6 應用程序的基石。從簡單的標簽到復雜的滑塊,Qt6 提供了豐富的小部件。以下是創建 QPushButton 的方法:
from PyQt6.QtWidgets import QApplication, QPushButton
app = QApplication([])
button = QPushButton('Click Me')
button.clicked.connect(lambda: print('Button clicked!'))
button.show()
app.exec()布局
布局有助于組織窗口內的小部件。Qt6 提供了多種布局,例如 QHBoxLayout、QVBoxLayout 和 GridLayout。以下是使用 QVBoxLayout 的示例:
from PyQt6.QtWidgets import QApplication, QVBoxLayout, QWidget, QPushButton
app = QApplication([])
window = QWidget()
layout = QVBoxLayout()
layout.addWidget(QPushButton('按鈕 1'))
layout.addWidget(QPushButton('按鈕 2'))
window.setLayout(layout)
window.show()
app.exec ( )對話框和窗口
對話框是用于用戶交互的特殊窗口。在 Qt6 中創建對話框非常簡單:
from PyQt6.QtWidgets import QApplication, QDialog, QDialogButtonBox, QVBoxLayout
app = QApplication([])
dialog = QDialog()
buttonBox = QDialogButtonBox(QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel)
buttonBox.accepted.connect(dialog.accept)
buttonBox.rejected.connect(dialog.reject)
layout = QVBoxLayout()
layout.addWidget(buttonBox)
dialog.setLayout(layout)
dialog.exec()高級 Qt6 功能
圖形和自定義小部件
Qt6 增強了對圖形的支持,允許創建自定義小部件和復雜的圖形元素。以下是繪制簡單矩形的代碼片段:
from PyQt6.QtWidgets import QApplication, QWidget
from PyQt6.QtGui import QPainter, QColor
from PyQt6.QtCore import Qt
class MyWidget(QWidget):
def paintEvent(self, event):
painter = QPainter(self)
painter.setBrush(QColor(255, 0, 0, 180))
painter.drawRect(10, 10, 100, 100)
app = QApplication([])
myWidget = MyWidget()
myWidget.show()
app.exec()數據庫集成
Qt6 提供了強大的數據庫集成支持,可以輕松連接到主流數據庫。以下是連接到 SQLite 數據庫的方法:
from PyQt6.QtSql import QSqlDatabase, QSqlQuery
db = QSqlDatabase.addDatabase("QSQLITE")
db.setDatabaseName(":memory:")
if db.open():
query = QSqlQuery()
query.exec("CREATE TABLE people (id INTEGER PRIMARY KEY, name TEXT)")Qt6 中的多線程
Qt6 支持多線程,這對于在執行長時間操作時保持 UI 的響應至關重要。以下是使用 QThread 的示例:
from PyQt6.QtCore import QThread, pyqtSignal
from PyQt6.QtWidgets import QApplication, QLabel
class Worker(QThread):
updated = pyqtSignal(str)
def run(self):
# Long running task
self.updated.emit("Task Finished")
app = QApplication([])
label = QLabel("Starting...")
label.show()
worker = Worker()
worker.updated.connect(lambda text: label.setText(text))
worker.start()
app.exec()高級 PyQt6 概念
PyQt6 的高級概念可用于創建更復雜、交互性更強的 GUI 應用程序。以下是一些高級主題的講解和代碼示例,包括模型-視圖-控制器 (MVC) 架構、自定義控件、圖形視圖框架以及 PyQt6 中的線程處理。
1. 模型-視圖-控制器(MVC)架構
MVC 架構將數據模型、用戶界面和控制邏輯分離到不同的組件中。這種分離使得應用程序更易于維護和擴展。
示例:為列表編輯器應用程序實現簡單的 MVC。
from PyQt6.QtWidgets import QApplication, QMainWindow, QListWidget, QVBoxLayout, QWidget, QPushButton
class Model:
def __init__(self, data):
self.data = data
class View(QMainWindow):
def __init__(self, model):
super().__init__()
self.model = model
self.initUI()
def initUI(self):
self.setWindowTitle('MVC Example')
self.listWidget = QListWidget()
for entry in self.model.data:
self.listWidget.addItem(entry)
self.addButton = QPushButton("Add Item")
self.layout = QVBoxLayout()
self.layout.addWidget(self.listWidget)
self.layout.addWidget(self.addButton)
self.container = QWidget()
self.container.setLayout(self.layout)
self.setCentralWidget(self.container)
class Controller:
def __init__(self, model, view):
self.model = model
self.view = view
self.connectSignals()
def connectSignals(self):
self.view.addButton.clicked.connect(self.addItem)
def addItem(self):
itemText = f"Item {len(self.model.data) + 1}"
self.model.data.append(itemText)
self.view.listWidget.addItem(itemText)
if __name__ == '__main__':
app = QApplication([])
model = Model(['Item 1', 'Item 2', 'Item 3'])
view = View(model)
controller = Controller(model, view)
view.show()
app.exec()2. 自定義小部件
創建自定義小部件涉及對現有的 PyQt6 小部件或基QWidget類進行子類化,然后重寫方法來自定義小部件的外觀和行為。
示例:創建自定義按鈕小部件。
from PyQt6.QtWidgets import QPushButton, QApplication, QWidget, QVBoxLayout
from PyQt6.QtGui import QPainter, QColor
from PyQt6.QtCore import Qt
class ColorButton(QPushButton):
def __init__(self, color, parent=None):
super().__init__(parent)
self.color = color
def paintEvent(self, event):
painter = QPainter(self)
painter.setBrush(QColor(self.color))
painter.drawRect(self.rect())
if __name__ == '__main__':
app = QApplication([])
window = QWidget()
layout = QVBoxLayout()
redButton = ColorButton('red')
greenButton = ColorButton('green')
layout.addWidget(redButton)
layout.addWidget(greenButton)
window.setLayout(layout)
window.show()
app.exec()3. 圖形視圖框架
圖形視圖框架提供了基于場景的畫布,用于管理和與大量自定義 2D 圖形項目進行交互。
示例:在場景中顯示自定義項目。
from PyQt6.QtWidgets import QApplication, QGraphicsView, QGraphicsScene, QGraphicsEllipseItem
from PyQt6.QtCore import Qt
class GraphicsExample(QGraphicsView):
def __init__(self):
super().__init__()
self.scene = QGraphicsScene()
self.setScene(self.scene)
self.initUI()
def initUI(self):
ellipse = QGraphicsEllipseItem(0, 0, 100, 50)
self.scene.addItem(ellipse)
if __name__ == '__main__':
app = QApplication([])
view = GraphicsExample()
view.show()
app.exec()4. PyQt6 中的線程
對于長時間運行的操作,將工作負載移至單獨的線程可防止 GUI 卡死。PyQt6 不僅集成了 Python 的線程模塊,還提供了自己的QThread線程管理類。
示例:QThread用于后臺任務。
from PyQt6.QtWidgets import QApplication, QPushButton, QVBoxLayout, QWidget
from PyQt6.QtCore import QThread, pyqtSignal
import time
class Worker(QThread):
finished = pyqtSignal()
def run(self):
time.sleep(5) # Simulate a long-running task
self.finished.emit()
class MainWindow(QWidget):
def __init__(self):
super().__init__()
self.button = QPushButton("Start Task")
self.button.clicked.connect(self.startTask)
layout = QVBoxLayout()
layout.addWidget(self.button)
self.setLayout(layout)
def startTask(self):
self.thread = Worker()
self.thread.finished.connect(self.taskFinished)
self.thread.start()
def taskFinished(self):
self.button.setText("Task Finished")
if __name__ == '__main__':
app = QApplication([])
window = MainWindow()
window.show()
app.exec()這些示例展示了 PyQt6 在開發復雜應用程序方面的多功能性和強大功能。通過利用這些先進的概念,開發人員可以創建兼具功能性和視覺吸引力的應用程序。
簡單計算器示例
創建一個簡單的計算器是熟悉 PyQt6 的好方法,它可以演示如何與小部件交互、處理事件以及執行基本操作。以下是創建可執行加、減、乘、除運算的基本計算器的分步指南。
步驟1:導入PyQt6模塊
首先,你需要從 PyQt6 導入必要的模塊。
from PyQt6.QtWidgets import QApplication, QWidget, QPushButton, QVBoxLayout, QLineEdit
import sys步驟 2:創建計算器的 GUI
為計算器的 GUI 定義一個類。該類將創建計算器窗口、布局、顯示區域(用于顯示計算結果或輸入)以及用于數字和運算的按鈕。
class SimpleCalculator(QWidget):
def __init__(self):
super ().__init__()
self.setWindowTitle("Simple Calculator")
self.create_ui()
def create_ui(self):
# 創建垂直布局
self.layout = QVBoxLayout()
# 創建顯示行編輯
self.display = QLineEdit()
# 使顯示只讀
self.display.setReadOnly( True )
self.layout.addWidget(self.display)
self.create_buttons()
self.setLayout(self.layout)
def create_buttons(self):
# 計算器的按鈕
buttons = [
'7' , '8' , '9' , '/' ,
'4' , '5' , '6' , '*'
, ' 1' , '2' , ' 3' , '-' ,
'0' , '.' , '=' , '+'
]
# 創建按鈕并將其添加到布局
for button in buttons:
btn = QPushButton(button)
btn.clicked.connect(self.on_click)
self.layout.addWidget(btn)
def on_click(self):
# 獲取被點擊的按鈕
button = self.sender()
# 獲取按鈕的文本
text = button.text()
if text == "=" :
# 如果按下了等于按鈕,則評估表達式
try :
result = str(eval (self.display.text()))
self.display.setText(result)
except Exception as e:
self.display.setText("Error")
else :
# 如果按下了任何其他按鈕,則將其文本添加到顯示
self.display.setText(self.display.text() + text)步驟3:初始化并顯示計算器
定義SimpleCalculator類之后,你需要在啟動應用程序的主循環之前創建一個QApplication實例和計算器。
if __name__ == "__main__":
app = QApplication(sys.argv)
calculator = SimpleCalculator()
calculator.show()
sys.exit(app.exec())這個簡單的計算器允許用戶使用按鈕輸入基本的算術運算,并在點擊“=”按鈕時顯示結果。eval函數用于計算顯示中的字符串表達式,這是一種簡單但可能不安全的執行動態表達式的方法。對于實際應用,請考慮實現更安全的計算機制,以避免eval相關的風險。
此示例涵蓋了基本操作,并為構建更復雜的功能(例如處理更復雜的數學運算、改進錯誤處理和增強用戶界面)提供了基礎。
設計原則和最佳實踐
使用 Qt6 和 Python 進行開發時,請考慮以下最佳實踐:
- 模塊化設計:將代碼組織成模塊和類。
- 信號和槽機制:利用Qt的信號和槽機制進行對象之間的通信。
- 資源管理:注意資源管理,尤其是圖形和數據庫連接。
- 用戶體驗:關注用戶體驗,確保你的應用程序直觀且響應迅速。
真實世界的應用示例
VLC 媒體播放器、Calibre 和 Anki 是 Qt6 多功能性的典型代表。分析這些應用程序會發現一些共同的挑戰,例如處理多媒體內容、管理龐大的庫以及實現間隔重復算法。
寫在最后
Python 和 Qt6 為開發跨平臺桌面應用程序提供了強大的組合。利用 Python 的簡潔性和 Qt6 全面的 GUI 元素,開發人員可以相對輕松地創建復雜的應用程序。
Qt6 豐富的 GUI 元素,加上 Python 的簡潔易讀性,確保開發者能夠高效地設計出不僅視覺上賞心悅目,而且功能強大、響應迅速的界面。豐富的小部件、強大的事件處理以及信號和槽機制,助力創建出在當今軟件領域脫穎而出的交互式、用戶友好的應用程序。




































