云计算百科
云计算领域专业知识百科平台

Python编程之PyQt5 从入门到精通:全面进阶指南_附代码

Python编程之PyQt5 从入门到精通:全面进阶指南_附代码

目录

  • PyQt5简介与环境搭建
  • 第一个PyQt5程序
  • 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_())

    代码解析:

  • QApplication:管理GUI应用程序的控制流和主设置
  • QWidget:所有用户界面对象的基类
  • QLabel:用于显示文本或图像
  • 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:设置应用名称

    注意事项:

  • 打包时可能需要添加资源文件路径
  • 图标文件需要转换为.ico格式
  • 打包后的文件体积较大,因为包含了Python解释器和所有依赖

  • 划重点!!!!

    本教程从PyQt5的基础到进阶内容进行了全面讲解,涵盖了界面设计、信号槽机制、多线程、数据库操作等核心知识点。通过实际案例演示了PyQt5的强大功能。希望这篇文章能帮助你掌握PyQt5开发。

    如需进一步学习,可以参考:

    • 官方文档:https://www.riverbankcomputing.com/static/Docs/PyQt5/
    • Qt官方文档:https://doc.qt.io/
    • PyQt5示例代码库

    祝你编程愉快!

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » Python编程之PyQt5 从入门到精通:全面进阶指南_附代码
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!