前言
这里是pyQt5的简单开发手册
总述:PyQt 框架架构与核心价值
PyQt 是 Python 语言的 Qt 框架绑定,结合了 Python 的简洁高效与 Qt 的强大功能,用于开发跨平台桌面应用和嵌入式界面。其技术核心建立在四大支柱之上:
- 信号与槽机制 - 事件驱动的通信系统
- 窗口部件体系 - 丰富的 GUI 组件库
- 模型/视图架构 - 数据与显示的分离
- 多线程支持 - QThread 与线程安全
核心优势:
- 跨平台性:Windows/macOS/Linux/嵌入式系统
- 商业友好:GPL 和商业双许可证
- Qt Designer:可视化界面设计工具
- 丰富组件:超过 600 个可直接使用的类
1 2 3 4 5 6 7
| graph TD A[PyQt核心] --> B[信号与槽] A --> C[窗口部件] A --> D[模型/视图] A --> E[多线程] A --> F[绘图系统] A --> G[数据库集成]
|
一、信号与槽机制(事件驱动核心)
1. 基本连接方式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| from PyQt5.QtCore import QObject, pyqtSignal
class Sender(QObject): signal_example = pyqtSignal(str) def trigger_signal(self): self.signal_example.emit("Hello PyQt!")
class Receiver(QObject): def handle_signal(self, message): print("Received:", message)
sender = Sender() receiver = Receiver()
sender.signal_example.connect(receiver.handle_signal) sender.trigger_signal()
|
2. 内置信号使用
1 2 3 4 5
| button = QPushButton("Click me") button.clicked.connect(lambda: print("Button clicked!"))
slider = QSlider(Qt.Horizontal) slider.valueChanged.connect(lambda value: print(f"Slider value: {value}"))
|
1. 基础窗口创建
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| import sys from PyQt5.QtWidgets import QApplication, QMainWindow, QLabel
app = QApplication(sys.argv)
window = QMainWindow() window.setWindowTitle("PyQt Demo") window.setGeometry(100, 100, 800, 600)
label = QLabel("Hello PyQt!", window) label.move(50, 50)
window.show() sys.exit(app.exec_())
|
2. 常用组件函数速查
| 组件类 |
关键函数 |
功能说明 |
| QPushButton |
setText(str) |
设置按钮文本 |
|
clicked.connect(func) |
点击事件连接 |
| QLabel |
setPixmap(QPixmap) |
设置图片显示 |
|
setAlignment(Qt.AlignCenter) |
设置文本对齐 |
| QLineEdit |
text() |
获取输入文本 |
|
setPlaceholderText(str) |
设置占位提示文本 |
| QComboBox |
addItem(str) |
添加下拉选项 |
|
currentText() |
获取当前选中项 |
| QCheckBox |
setChecked(bool) |
设置选中状态 |
|
stateChanged.connect(func) |
状态改变事件 |
| QProgressBar |
setRange(min, max) |
设置进度范围 |
|
setValue(int) |
设置当前进度值 |
三、布局管理系统
1. 基础布局使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| from PyQt5.QtWidgets import QVBoxLayout, QHBoxLayout, QGridLayout
v_layout = QVBoxLayout() v_layout.addWidget(QPushButton("Top")) v_layout.addWidget(QPushButton("Bottom"))
h_layout = QHBoxLayout() h_layout.addWidget(QPushButton("Left")) h_layout.addWidget(QPushButton("Right"))
grid = QGridLayout() grid.addWidget(QLabel("Name:"), 0, 0) grid.addWidget(QLineEdit(), 0, 1) grid.addWidget(QLabel("Age:"), 1, 0) grid.addWidget(QSpinBox(), 1, 1)
main_layout = QVBoxLayout() main_layout.addLayout(h_layout) main_layout.addLayout(grid)
|
2. 布局管理函数
| 函数 |
说明 |
addWidget(widget) |
添加控件 |
addLayout(layout) |
嵌套子布局 |
setSpacing(int) |
设置控件间距 |
setContentsMargins(l,t,r,b) |
设置布局边距 |
setStretchFactor(index, factor) |
设置拉伸因子 |
四、模型/视图架构
1. QListView 示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| from PyQt5.QtCore import QStringListModel
model = QStringListModel() model.setStringList(["Apple", "Banana", "Orange"])
list_view = QListView() list_view.setModel(model)
list_view.selectionModel().selectionChanged.connect( lambda selected: print(selected.indexes()[0].data()) )
|
2. 自定义模型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| from PyQt5.QtCore import QAbstractTableModel, Qt
class CustomModel(QAbstractTableModel): def __init__(self, data): super().__init__() self._data = data def rowCount(self, parent): return len(self._data) def columnCount(self, parent): return len(self._data[0]) def data(self, index, role=Qt.DisplayRole): if role == Qt.DisplayRole: return self._data[index.row()][index.column()]
data = [["John", 30], ["Alice", 25]] model = CustomModel(data) table_view = QTableView() table_view.setModel(model)
|
五、绘图与图形视图框架
1. QPainter 基础绘图
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| class CustomWidget(QWidget): def paintEvent(self, event): painter = QPainter(self) painter.setBrush(QColor(200, 0, 0)) painter.drawRect(10, 10, 100, 100) painter.setFont(QFont("Arial", 16)) painter.drawText(50, 150, "Hello PyQt") path = QPainterPath() path.moveTo(50, 200) path.cubicTo(100, 100, 200, 200, 250, 150) painter.drawPath(path)
|
2. QGraphicsScene 高级图形
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| scene = QGraphicsScene() scene.setSceneRect(0, 0, 400, 300)
rect = scene.addRect(50, 50, 100, 100, QPen(Qt.blue), QBrush(Qt.yellow)) ellipse = scene.addEllipse(200, 100, 80, 80, QPen(Qt.red))
text = scene.addText("Graphics View", QFont("Arial", 14)) text.setPos(100, 200)
view = QGraphicsView(scene) view.show()
|
六、多线程与并发
1. QThread 使用模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| class Worker(QObject): finished = pyqtSignal() progress = pyqtSignal(int) def run(self): for i in range(1, 101): time.sleep(0.1) self.progress.emit(i) self.finished.emit()
class MainWindow(QMainWindow): def __init__(self): super().__init__() self.thread = QThread() self.worker = Worker() self.worker.moveToThread(self.thread) self.thread.started.connect(self.worker.run) self.worker.finished.connect(self.thread.quit) self.worker.finished.connect(self.worker.deleteLater) self.thread.finished.connect(self.thread.deleteLater) btn_start = QPushButton("Start", self) btn_start.clicked.connect(self.thread.start)
|
2. 线程间通信
1 2 3 4 5 6
| self.worker.progress.connect(self.update_progress)
def update_progress(self, value): self.progress_bar.setValue(value)
|
七、数据库集成
1. SQL 数据库操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| from PyQt5.QtSql import QSqlDatabase, QSqlQuery
db = QSqlDatabase.addDatabase("QSQLITE") db.setDatabaseName("mydatabase.db") if not db.open(): print("Database error:", db.lastError().text())
query = QSqlQuery() query.exec("CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)") query.exec("INSERT INTO users (name) VALUES ('John')")
query.exec("SELECT * FROM users") while query.next(): print(query.value("id"), query.value("name"))
|
2. 模型视图集成
1 2 3 4 5 6 7 8
| model = QSqlTableModel() model.setTable("users") model.select()
table_view = QTableView() table_view.setModel(model) table_view.show()
|
高级特性与最佳实践
1. 样式表定制(QSS)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| app.setStyleSheet(""" QMainWindow { background-color: #2c3e50; } QPushButton { background-color: #3498db; color: white; border-radius: 5px; padding: 5px 10px; } QPushButton:hover { background-color: #2980b9; } """)
button.setStyleSheet(""" QPushButton { border: 2px solid #e74c3c; font-weight: bold; } """)
|
2. 国际化支持
1 2 3 4 5 6 7
| translator = QTranslator() translator.load("app_zh_CN.qm") app.installTranslator(translator)
button.setText(QCoreApplication.translate("Main", "Click Me"))
|
3. 插件系统
1 2 3 4 5 6 7 8 9 10 11 12
| class PluginInterface: def initialize(self) -> bool: ... def do_action(self): ...
plugin_dir = QDir("./plugins") for filename in plugin_dir.entryList(["*.so", "*.dll"]): loader = QPluginLoader(plugin_dir.filePath(filename)) plugin = loader.instance() if isinstance(plugin, PluginInterface): plugin.initialize()
|
总结:PyQt 应用架构与开发模式
PyQt 应用核心结构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| import sys from PyQt5.QtWidgets import QApplication, QMainWindow
class MainWindow(QMainWindow): def __init__(self): super().__init__() self.init_ui() def init_ui(self): self.setWindowTitle("PyQt App") self.show()
if __name__ == "__main__": app = QApplication(sys.argv) window = MainWindow() sys.exit(app.exec_())
|
开发工作流
- 界面设计:使用 Qt Designer 创建
.ui 文件
- 转换代码:
pyuic5 input.ui -o output.py
- 业务逻辑:继承生成类实现功能
- 资源管理:使用
pyrcc5 编译资源文件
- 打包分发:
pyinstaller --windowed app.py
性能优化技巧
延迟加载:大型组件按需初始化
1 2 3
| def show_tab(self, index): if index == 2 and not self.tab2_loaded: self.init_tab2()
|
列表优化:大数据集使用模型/视图
1
| self.list_view.setUniformItemSizes(True)
|
绘图优化:避免在 paintEvent 中创建对象
1 2 3
| def paintEvent(self, event):
|
内存管理:正确处理对象生命周期
1 2 3 4 5
| obj.deleteLater()
child_widget = QWidget(parent=self)
|
PyQt 与 PySide 对比
| 特性 |
PyQt |
PySide |
| 许可证 |
GPL/商业许可 |
LGPL |
| 开发商 |
Riverbank Computing |
Qt 官方 |
| API兼容 |
兼容 Qt4/Qt5 |
兼容 Qt4/Qt5/Qt6 |
| 信号语法 |
pyqtSignal |
Signal |
| 社区支持 |
成熟,文档丰富 |
官方支持,发展迅速 |
| 部署大小 |
稍大 |
稍小 |
版权声明: 此文章版权归曦曦所有,如有转载,请注明来自原作者