Python编程之PyQt5 从入门到精通:全面进阶指南_附代码
目录
1. PyQt5简介与环境搭建
PyQt是Qt框架的Python绑定,Qt是一个跨平台的C++图形用户界面应用程序开发框架。PyQt5支持Python3.x版本。
安装方法:
pip install PyQt5
pip install PyQt5-tools # 可选,包含Qt Designer等工具
验证安装:
import PyQt5
print(PyQt5.__version__) # 打印PyQt5版本
2. 第一个PyQt5程序
# 十一剑的CS_DN.博客 – PyQt5第一个示例程序
import sys
from PyQt5.QtWidgets import QApplication, QLabel, QWidget
# 创建应用对象,sys.argv是命令行参数列表
app = QApplication(sys.argv)
# 创建一个窗口
window = QWidget()
window.setWindowTitle('十一剑的第一个PyQt5程序') # 设置窗口标题
window.setGeometry(100, 100, 280, 80) # 设置窗口位置和大小(x,y,width,height)
# 创建一个标签控件
label = QLabel('欢迎来到十一剑的CS_DN.博客学习PyQt5!', parent=window)
label.move(60, 30) # 移动标签位置
# 显示窗口
window.show()
# 进入应用的主事件循环,等待用户操作
sys.exit(app.exec_())
代码解析:
3. PyQt5基础组件
按钮(QPushButton)示例
# 十一剑的CS_DN.博客 – PyQt5按钮示例
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QVBoxLayout
import sys
class MyWindow(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
# 设置窗口标题和大小
self.setWindowTitle('十一剑的按钮示例')
self.setGeometry(100, 100, 300, 200)
# 创建一个垂直布局
layout = QVBoxLayout()
# 创建按钮1
btn1 = QPushButton('按钮1', self)
btn1.clicked.connect(self.on_btn1_click) # 连接点击信号到槽函数
# 创建按钮2
btn2 = QPushButton('按钮2', self)
btn2.clicked.connect(self.on_btn2_click)
# 将按钮添加到布局中
layout.addWidget(btn1)
layout.addWidget(btn2)
# 设置窗口的布局
self.setLayout(layout)
def on_btn1_click(self):
print('按钮1被点击了 – 十一剑的CS_DN.博客')
def on_btn2_click(self):
print('按钮2被点击了 – 十一剑的CS_DN.博客')
if __name__ == '__main__':
app = QApplication(sys.argv)
window = MyWindow()
window.show()
sys.exit(app.exec_())
4. 布局管理
PyQt5提供多种布局管理器:
- QVBoxLayout:垂直布局
- QHBoxLayout:水平布局
- QGridLayout:网格布局
- QFormLayout:表单布局
网格布局示例:
# 十一剑的CS_DN.博客 – 网格布局示例
from PyQt5.QtWidgets import (QApplication, QWidget, QPushButton,
QGridLayout, QLabel)
import sys
class GridLayoutExample(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
# 设置窗口标题
self.setWindowTitle('十一剑的网格布局示例')
# 创建网格布局
grid = QGridLayout()
self.setLayout(grid)
# 创建按钮并添加到网格中
names = ['1', '2', '3', '4', '5', '6', '7', '8', '9']
positions = [(i, j) for i in range(3) for j in range(3)]
for position, name in zip(positions, names):
button = QPushButton(name)
grid.addWidget(button, *position)
# 添加一个跨越多列的标签
label = QLabel('十一剑的CS_DN.博客 – 3×3网格布局')
grid.addWidget(label, 3, 0, 1, 3) # 第4行,跨越3列
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = GridLayoutExample()
ex.show()
sys.exit(app.exec_())
5. 信号与槽机制
信号(Signal)和槽(Slot)是Qt的核心机制,用于对象间的通信。
自定义信号示例:
# 十一剑的CS_DN.博客 – 自定义信号示例
from PyQt5.QtCore import pyqtSignal, QObject
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton
import sys
# 创建一个包含信号的类
class Communicate(QObject):
closeApp = pyqtSignal() # 定义一个信号
class MyWindow(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
# 设置窗口标题和大小
self.setWindowTitle('十一剑的自定义信号示例')
self.setGeometry(100, 100, 300, 200)
# 创建通信对象
self.c = Communicate()
self.c.closeApp.connect(self.close) # 连接信号到槽
# 创建按钮
btn = QPushButton('关闭窗口', self)
btn.move(100, 80)
btn.clicked.connect(self.emit_signal) # 按钮点击触发信号
def emit_signal(self):
print('发射关闭信号 – 十一剑的CS_DN.博客')
self.c.closeApp.emit() # 发射信号
if __name__ == '__main__':
app = QApplication(sys.argv)
window = MyWindow()
window.show()
sys.exit(app.exec_())
6. 常用控件详解
文本框(QLineEdit)示例
# 十一剑的CS_DN.博客 – 文本框示例
from PyQt5.QtWidgets import (QApplication, QWidget, QLabel,
QLineEdit, QPushButton, QVBoxLayout)
import sys
class LineEditExample(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
# 设置窗口标题
self.setWindowTitle('十一剑的文本框示例')
# 创建布局
layout = QVBoxLayout()
# 创建标签
self.label = QLabel('输入内容将显示在这里')
# 创建文本框
self.textbox = QLineEdit(self)
self.textbox.setPlaceholderText('请输入文本…')
# 创建按钮
btn = QPushButton('显示文本', self)
btn.clicked.connect(self.on_click)
# 将控件添加到布局中
layout.addWidget(self.label)
layout.addWidget(self.textbox)
layout.addWidget(btn)
# 设置窗口布局
self.setLayout(layout)
def on_click(self):
text = self.textbox.text()
self.label.setText(f'你输入了: {text} – 十一剑的CS_DN.博客')
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = LineEditExample()
ex.show()
sys.exit(app.exec_())
7. 对话框与消息框
PyQt5提供多种对话框:
- QMessageBox:消息对话框
- QInputDialog:输入对话框
- QFileDialog:文件对话框
- QColorDialog:颜色对话框
消息框示例:
# 十一剑的CS_DN.博客 – 消息框示例
from PyQt5.QtWidgets import (QApplication, QWidget, QPushButton,
QVBoxLayout, QMessageBox)
import sys
class MessageBoxExample(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
# 设置窗口标题
self.setWindowTitle('十一剑的消息框示例')
# 创建布局
layout = QVBoxLayout()
# 创建按钮
btn_info = QPushButton('显示信息框', self)
btn_info.clicked.connect(self.show_info)
btn_warn = QPushButton('显示警告框', self)
btn_warn.clicked.connect(self.show_warning)
btn_question = QPushButton('显示问题框', self)
btn_question.clicked.connect(self.show_question)
# 将按钮添加到布局中
layout.addWidget(btn_info)
layout.addWidget(btn_warn)
layout.addWidget(btn_question)
# 设置窗口布局
self.setLayout(layout)
def show_info(self):
QMessageBox.information(self, '信息',
'这是一个信息框 – 十一剑的CS_DN.博客')
def show_warning(self):
QMessageBox.warning(self, '警告',
'这是一个警告框 – 十一剑的CS_DN.博客')
def show_question(self):
reply = QMessageBox.question(self, '问题',
'你确定要继续吗? – 十一剑的CS_DN.博客',
QMessageBox.Yes | QMessageBox.No,
QMessageBox.No)
if reply == QMessageBox.Yes:
print('用户选择了"是"')
else:
print('用户选择了"否"')
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = MessageBoxExample()
ex.show()
sys.exit(app.exec_())
8. 主窗口与菜单栏
# 十一剑的CS_DN.博客 – 主窗口与菜单栏示例
from PyQt5.QtWidgets import (QApplication, QMainWindow, QAction,
QTextEdit, QFileDialog, QMessageBox)
from PyQt5.QtGui import QIcon
import sys
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
# 设置窗口标题和大小
self.setWindowTitle('十一剑的主窗口示例')
self.setGeometry(100, 100, 800, 600)
# 创建文本编辑区
self.textEdit = QTextEdit()
self.setCentralWidget(self.textEdit)
# 创建状态栏
self.statusBar().showMessage('就绪 – 十一剑的CS_DN.博客')
# 创建菜单栏
self.createMenus()
# 创建工具栏
self.createToolBar()
def createMenus(self):
# 创建文件菜单
menubar = self.menuBar()
fileMenu = menubar.addMenu('文件')
# 新建动作
newAct = QAction(QIcon('new.png'), '新建', self)
newAct.setShortcut('Ctrl+N')
newAct.setStatusTip('新建文件')
newAct.triggered.connect(self.newFile)
# 打开动作
openAct = QAction(QIcon('open.png'), '打开', self)
openAct.setShortcut('Ctrl+O')
openAct.setStatusTip('打开文件')
openAct.triggered.connect(self.openFile)
# 退出动作
exitAct = QAction(QIcon('exit.png'), '退出', self)
exitAct.setShortcut('Ctrl+Q')
exitAct.setStatusTip('退出应用')
exitAct.triggered.connect(self.close)
# 将动作添加到文件菜单
fileMenu.addAction(newAct)
fileMenu.addAction(openAct)
fileMenu.addSeparator()
fileMenu.addAction(exitAct)
# 创建帮助菜单
helpMenu = menubar.addMenu('帮助')
aboutAct = QAction('关于', self)
aboutAct.triggered.connect(self.about)
helpMenu.addAction(aboutAct)
def createToolBar(self):
# 创建工具栏
toolbar = self.addToolBar('工具栏')
# 添加工具按钮
newAct = QAction(QIcon('new.png'), '新建', self)
newAct.triggered.connect(self.newFile)
toolbar.addAction(newAct)
openAct = QAction(QIcon('open.png'), '打开', self)
openAct.triggered.connect(self.openFile)
toolbar.addAction(openAct)
def newFile(self):
self.textEdit.clear()
self.statusBar().showMessage('新建文件 – 十一剑的CS_DN.博客')
def openFile(self):
fname = QFileDialog.getOpenFileName(self, '打开文件', '.')
if fname[0]:
with open(fname[0], 'r', encoding='utf-8') as f:
data = f.read()
self.textEdit.setText(data)
self.statusBar().showMessage(f'已打开: {fname[0]} – 十一剑的CS_DN.博客')
def about(self):
QMessageBox.about(self, '关于',
'这是一个PyQt5主窗口示例\\n十一剑的CS_DN.博客')
if __name__ == '__main__':
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
9. 绘图与图形视图
PyQt5提供了强大的绘图功能,主要通过QPainter类实现。
绘图示例:
# 十一剑的CS_DN.博客 – 绘图示例
from PyQt5.QtWidgets import QApplication, QWidget
from PyQt5.QtGui import QPainter, QColor, QPen
from PyQt5.QtCore import Qt
import sys
class DrawingExample(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
# 设置窗口标题和大小
self.setWindowTitle('十一剑的绘图示例')
self.setGeometry(100, 100, 600, 400)
def paintEvent(self, event):
# 创建QPainter对象
painter = QPainter(self)
# 设置画笔
pen = QPen(Qt.black, 2, Qt.SolidLine)
painter.setPen(pen)
# 绘制直线
painter.drawLine(20, 40, 250, 40)
# 绘制矩形
painter.drawRect(20, 80, 120, 80)
# 绘制圆角矩形
painter.drawRoundedRect(180, 80, 120, 80, 20, 20)
# 绘制椭圆
painter.drawEllipse(20, 200, 120, 80)
# 绘制弧线
painter.drawArc(180, 200, 120, 80, 0, 180 * 16)
# 绘制文本
painter.drawText(20, 320, 'PyQt5绘图示例 – 十一剑的CS_DN.博客')
# 设置不同颜色
pen.setColor(Qt.blue)
painter.setPen(pen)
# 绘制点
for i in range(100):
painter.drawPoint(400 + i, 50 + i)
# 填充矩形
painter.fillRect(400, 150, 100, 100, QColor(255, 0, 0))
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = DrawingExample()
ex.show()
sys.exit(app.exec_())
10. 多线程编程
在GUI程序中使用多线程可以避免界面冻结。
QThread示例:
# 十一剑的CS_DN.博客 – 多线程示例
from PyQt5.QtCore import QThread, pyqtSignal
from PyQt5.QtWidgets import (QApplication, QWidget, QPushButton,
QVBoxLayout, QLabel)
import time
import sys
# 工作线程类
class WorkerThread(QThread):
# 定义信号
update_signal = pyqtSignal(int)
finished_signal = pyqtSignal(str)
def run(self):
for i in range(1, 101):
time.sleep(0.05) # 模拟耗时操作
self.update_signal.emit(i) # 发射进度更新信号
self.finished_signal.emit('任务完成 – 十一剑的CS_DN.博客')
class ThreadExample(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
# 设置窗口标题
self.setWindowTitle('十一剑的多线程示例')
# 创建布局
layout = QVBoxLayout()
# 创建标签显示进度
self.progress_label = QLabel('准备开始', self)
# 创建按钮
self.start_btn = QPushButton('开始任务', self)
self.start_btn.clicked.connect(self.start_task)
# 将控件添加到布局中
layout.addWidget(self.progress_label)
layout.addWidget(self.start_btn)
# 设置窗口布局
self.setLayout(layout)
# 创建工作线程
self.worker = WorkerThread()
self.worker.update_signal.connect(self.update_progress)
self.worker.finished_signal.connect(self.task_finished)
def start_task(self):
self.start_btn.setEnabled(False)
self.progress_label.setText('任务开始…')
self.worker.start() # 启动线程
def update_progress(self, value):
self.progress_label.setText(f'进度: {value}%')
def task_finished(self, message):
self.progress_label.setText(message)
self.start_btn.setEnabled(True)
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = ThreadExample()
ex.show()
sys.exit(app.exec_())
11. 数据库连接
PyQt5通过QtSql模块提供数据库支持。
SQLite数据库示例:
# 十一剑的CS_DN.博客 – 数据库连接示例
from PyQt5.QtWidgets import (QApplication, QWidget, QVBoxLayout,
QPushButton, QLabel, QLineEdit, QTextEdit)
from PyQt5.QtSql import QSqlDatabase, QSqlQuery
import sys
class DatabaseExample(QWidget):
def __init__(self):
super().__init__()
self.initUI()
self.initDB()
def initUI(self):
# 设置窗口标题
self.setWindowTitle('十一剑的数据库示例')
# 创建布局
layout = QVBoxLayout()
# 创建输入控件
self.name_input = QLineEdit(self)
self.name_input.setPlaceholderText('输入姓名')
self.age_input = QLineEdit(self)
self.age_input.setPlaceholderText('输入年龄')
# 创建按钮
self.add_btn = QPushButton('添加记录', self)
self.add_btn.clicked.connect(self.add_record)
self.show_btn = QPushButton('显示记录', self)
self.show_btn.clicked.connect(self.show_records)
# 创建文本显示区
self.text_output = QTextEdit(self)
self.text_output.setReadOnly(True)
# 将控件添加到布局中
layout.addWidget(QLabel('姓名:'))
layout.addWidget(self.name_input)
layout.addWidget(QLabel('年龄:'))
layout.addWidget(self.age_input)
layout.addWidget(self.add_btn)
layout.addWidget(self.show_btn)
layout.addWidget(self.text_output)
# 设置窗口布局
self.setLayout(layout)
def initDB(self):
# 创建SQLite数据库连接
self.db = QSqlDatabase.addDatabase('QSQLITE')
self.db.setDatabaseName('test.db')
if not self.db.open():
self.text_output.setText('无法连接数据库')
return False
# 创建表
query = QSqlQuery()
query.exec_("""
CREATE TABLE IF NOT EXISTS people (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name VARCHAR(40) NOT NULL,
age INTEGER
)
""")
return True
def add_record(self):
name = self.name_input.text()
age = self.age_input.text()
if not name or not age:
self.text_output.setText('请输入姓名和年龄')
return
query = QSqlQuery()
query.prepare("INSERT INTO people (name, age) VALUES (?, ?)")
query.addBindValue(name)
query.addBindValue(age)
if query.exec_():
self.text_output.setText('记录添加成功 – 十一剑的CS_DN.博客')
self.name_input.clear()
self.age_input.clear()
else:
self.text_output.setText('添加记录失败')
def show_records(self):
query = QSqlQuery("SELECT id, name, age FROM people")
records = []
while query.next():
id = query.value(0)
name = query.value(1)
age = query.value(2)
records.append(f"ID: {id}, 姓名: {name}, 年龄: {age}")
if records:
self.text_output.setText("\\n".join(records))
else:
self.text_output.setText('没有记录 – 十一剑的CS_DN.博客')
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = DatabaseExample()
ex.show()
sys.exit(app.exec_())
12. 样式表与主题定制
PyQt5支持使用QSS(Qt样式表)来自定义控件外观。
样式表示例:
# 十一剑的CS_DN.博客 – 样式表示例
from PyQt5.QtWidgets import (QApplication, QWidget, QPushButton,
QVBoxLayout, QLabel)
import sys
class StyleSheetExample(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
# 设置窗口标题
self.setWindowTitle('十一剑的样式表示例')
# 创建布局
layout = QVBoxLayout()
# 创建控件
label = QLabel('PyQt5样式表示例 – 十一剑的CS_DN.博客')
btn1 = QPushButton('普通按钮')
btn2 = QPushButton('特殊按钮')
# 将控件添加到布局中
layout.addWidget(label)
layout.addWidget(btn1)
layout.addWidget(btn2)
# 设置窗口布局
self.setLayout(layout)
# 设置样式表
self.setStyleSheet("""
QWidget {
background-color: #f0f0f0;
font-family: Arial;
}
QLabel {
color: #333;
font-size: 16px;
font-weight: bold;
padding: 10px;
border: 1px solid #ccc;
border-radius: 5px;
background-color: white;
}
QPushButton {
background-color: #4CAF50;
border: none;
color: white;
padding: 10px 20px;
text-align: center;
text-decoration: none;
font-size: 14px;
margin: 4px 2px;
border-radius: 5px;
}
QPushButton:hover {
background-color: #45a049;
}
QPushButton:pressed {
background-color: #3e8e41;
}
#特殊按钮 {
background-color: #f44336;
}
#特殊按钮:hover {
background-color: #d32f2f;
}
""")
# 为按钮2设置对象名称以便特殊样式
btn2.setObjectName("特殊按钮")
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = StyleSheetExample()
ex.show()
sys.exit(app.exec_())
13. 打包与发布
使用PyInstaller可以将PyQt5程序打包为可执行文件。
安装PyInstaller:
pip install pyinstaller
打包命令:
pyinstaller –onefile –windowed your_script.py
常用参数:
- –onefile:打包为单个可执行文件
- –windowed:不显示控制台窗口(适用于GUI程序)
- –icon=app.ico:设置应用图标
- –name=AppName:设置应用名称
注意事项:
划重点!!!!
本教程从PyQt5的基础到进阶内容进行了全面讲解,涵盖了界面设计、信号槽机制、多线程、数据库操作等核心知识点。通过实际案例演示了PyQt5的强大功能。希望这篇文章能帮助你掌握PyQt5开发。
如需进一步学习,可以参考:
- 官方文档:https://www.riverbankcomputing.com/static/Docs/PyQt5/
- Qt官方文档:https://doc.qt.io/
- PyQt5示例代码库
祝你编程愉快!
评论前必须登录!
注册