PyQt5入门教程:从零开始打造Python图形界面应用

Python pyqt5库的使用

文章目录

  • 前言
  • 一、PyQt5简介
  • **PyQt5的优势:**
  • 环境搭建:
  • 二、PyQt5 基础概念和主要模块的使用
  • 2.1 主要模块
  • 2.2 基础组件
  • 2.3 常用控件
  • 1. QPushButton (按钮)
  • 2. QLabel (标签)
  • 3. QLineEdit (单行文本框)
  • 4. QComboBox (下拉框)
  • 5. QCheckBox (复选框)
  • 6. 布局管理:
  • QVBoxLayout (垂直布局)
  • QHBoxLayout (水平布局)
  • QGridLayout (网格布局)
  • 7. 对话框
  • QMessageBox (消息框)
  • QFileDialog (文件对话框)
  • 8.事件处理
  • 9.综合实例:简单的计算器
  • 总结

  • 前言

    作为初学者学习 PyQt5 是一个很好的选择,它是 Python 中最流行的GUI 框架之一,可以帮助你创建专业的桌面应用程序。下面我将记录PyQt5中最常用的函数、类和参数,以及它们的用法。


    一、PyQt5简介

    PyQt5 是 Qt 框架的 Python 绑定,它允许你使用 Python 语言创建图形用户界面 (GUI) 应用程序。Qt 是一个功能强大的跨平台应用程序开发框架,而 PyQt5 让 Python 开发者能够轻松访问这些功能。

  • Qt框架:由C++编写,提供强大的GUI组件和工具。
  • PyQt5:将Qt的C++接口转换为Python API,简化开发流程。
  • 与PySide2的区别:PyQt5由Riverbank Computing维护,采用GPL协议;PySide2由Qt官方维护,采用LGPL协议,两者API高度相似。
  • PyQt5的优势:

  • 跨平台:Windows、Linux、macOS一键部署。
  • 组件丰富:按钮、文本框、表格、对话框等一应俱全。
  • 信号与槽机制:用于组件间通信,处理事件响应(如按钮点击)。
  • Qt Designer支持:拖拽式设计界面,提升开发效率。
  • 支持 2D/3D 图形、多媒体、网络等
  • 环境搭建:

    首先,你需要安装 PyQt5:
    可在vscode、pycharm等IDE的终端创建虚拟环境,运行以下命令安装

    pip install PyQt5
    

    如果你需要 Qt Designer(可视化设计工具):

    pip install pyqt5-tools
    

    二、PyQt5 基础概念和主要模块的使用

    2.1 主要模块

  • QtWidgets :包含 GUI 组件
  • QtCore :包含核心的非 GUI 功能
  • QtGui :包含窗口系统、事件处理、2D 图形等
  • QtMultimedia :处理多媒体内容
  • QtNetwork :网络编程
  • QtSql :数据库集成

  • 2.2 基础组件

    QApplication :

  • 这是PyQt5应用程序的基础类,每个PyQt5应用程序都必须创建一个QApplication实例
  • QWidget:

  • QWidget是所有用户界面对象的基类,可以作为独立窗口或嵌入到其他窗口中。
  • 创建一个窗口示例:

    import sys
    from PyQt5.QtWidgets import QApplication, QWidget
    
    app = QApplication(sys.argv)  # 创建应用程序对象
    window = QWidget()  # 创建窗口
    window.setWindowTitle('我的第一个PyQt5应用')  # 设置窗口标题
    window.setGeometry(100, 100, 400, 300)  # 设置窗口位置和大小(x, y, width, height)
    window.show()  # 显示窗口
    sys.exit(app.exec_())  # 进入应用程序的主循环
    

    运行结果:


    2.3 常用控件

    1. QPushButton (按钮)

    import sys
    from PyQt5.QtWidgets import QApplication, QWidget, QPushButton
    
    app = QApplication(sys.argv)
    window = QWidget()
    window.setWindowTitle('按钮示例')
    window.setGeometry(100, 100, 300, 200)
    
    # 创建按钮
    button = QPushButton('点击我', window)
    button.setGeometry(100, 80, 100, 30)  # 设置按钮位置和大小
    button.setToolTip('这是一个按钮')  # 设置提示文本
    button.clicked.connect(lambda: print('按钮被点击了!'))  # 连接点击信号到槽函数
    
    window.show()
    sys.exit(app.exec_())
    

    运行结果:点击按钮会有响应

    2. QLabel (标签)

    import sys
    from PyQt5.QtWidgets import QApplication, QWidget, QLabel
    from PyQt5.QtGui import QPixmap
    from PyQt5.QtCore import Qt
    
    app = QApplication(sys.argv)
    window = QWidget()
    window.setWindowTitle('标签示例')
    window.setGeometry(100, 100, 400, 300)
    
    # 文本标签
    text_label = QLabel('这是一个文本标签', window)
    text_label.setGeometry(50, 50, 200, 30)
    
    # 设置对齐方式
    text_label.setAlignment(Qt.AlignCenter)
    
    # 图片标签
    image_label = QLabel(window)
    image_label.setGeometry(50, 100, 200, 150)
    # 加载图片(需要有图片文件)
    # pixmap = QPixmap('image.jpg')
    # image_label.setPixmap(pixmap)
    # image_label.setScaledContents(True)  # 图片自适应标签大小
    
    window.show()
    sys.exit(app.exec_())
    

    3. QLineEdit (单行文本框)

    import sys
    from PyQt5.QtWidgets import QApplication, QWidget, QLineEdit, QLabel, QVBoxLayout
    
    app = QApplication(sys.argv)
    window = QWidget()
    window.setWindowTitle('文本框示例')
    window.setGeometry(100, 100, 300, 150)
    
    # 创建布局
    layout = QVBoxLayout()
    
    # 创建标签和文本框
    label = QLabel('请输入文本:')
    text_input = QLineEdit()
    text_input.setPlaceholderText('在此输入...')  # 设置占位文本
    text_input.textChanged.connect(lambda text: print(f'文本已更改: {text}'))  # 文本变化信号
    text_input.returnPressed.connect(lambda: print(f'已按回车键: {text_input.text()}'))  # 回车键信号
    
    # 添加到布局
    layout.addWidget(label)
    layout.addWidget(text_input)
    window.setLayout(layout)
    
    window.show()
    sys.exit(app.exec_())
    

    4. QComboBox (下拉框)

    import sys
    from PyQt5.QtWidgets import QApplication, QWidget, QComboBox, QLabel, QVBoxLayout
    
    app = QApplication(sys.argv)
    window = QWidget()
    window.setWindowTitle('下拉框示例')
    window.setGeometry(100, 100, 300, 150)
    
    # 创建布局
    layout = QVBoxLayout()
    
    # 创建标签和下拉框
    label = QLabel('请选择一个选项:')
    combo = QComboBox()
    combo.addItem('选项1')
    combo.addItem('选项2')
    combo.addItem('选项3')
    combo.addItems(['选项4', '选项5'])  # 添加多个选项
    
    # 连接信号
    combo.currentIndexChanged.connect(lambda index: print(f'选择了索引 {index}: {combo.currentText()}'))
    
    # 添加到布局
    layout.addWidget(label)
    layout.addWidget(combo)
    window.setLayout(layout)
    
    window.show()
    sys.exit(app.exec_())
    

    5. QCheckBox (复选框)

    import sys
    from PyQt5.QtWidgets import QApplication, QWidget, QCheckBox, QVBoxLayout
    
    app = QApplication(sys.argv)
    window = QWidget()
    window.setWindowTitle('复选框示例')
    window.setGeometry(100, 100, 300, 150)
    
    # 创建布局
    layout = QVBoxLayout()
    
    # 创建复选框
    checkbox1 = QCheckBox('选项1')
    checkbox2 = QCheckBox('选项2')
    checkbox2.setChecked(True)  # 默认选中
    
    # 连接信号
    checkbox1.stateChanged.connect(lambda state: print(f'选项1状态: {state}'))  # 0=未选中, 2=选中
    checkbox2.stateChanged.connect(lambda state: print(f'选项2状态: {state}'))
    
    # 添加到布局
    layout.addWidget(checkbox1)
    layout.addWidget(checkbox2)
    window.setLayout(layout)
    
    window.show()
    sys.exit(app.exec_())
    

    6. 布局管理:

    QVBoxLayout (垂直布局)
    import sys
    from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QVBoxLayout
    
    app = QApplication(sys.argv)
    window = QWidget()
    window.setWindowTitle('垂直布局示例')
    window.setGeometry(100, 100, 300, 200)
    
    # 创建垂直布局
    layout = QVBoxLayout()
    
    # 添加按钮到布局
    button1 = QPushButton('按钮1')
    button2 = QPushButton('按钮2')
    button3 = QPushButton('按钮3')
    
    layout.addWidget(button1)
    layout.addWidget(button2)
    layout.addWidget(button3)
    
    # 设置布局
    window.setLayout(layout)
    
    window.show()
    sys.exit(app.exec_())
    

    QHBoxLayout (水平布局)
    import sys
    from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QHBoxLayout
    
    app = QApplication(sys.argv)
    window = QWidget()
    window.setWindowTitle('水平布局示例')
    window.setGeometry(100, 100, 400, 100)
    
    # 创建水平布局
    layout = QHBoxLayout()
    
    # 添加按钮到布局
    button1 = QPushButton('按钮1')
    button2 = QPushButton('按钮2')
    button3 = QPushButton('按钮3')
    
    layout.addWidget(button1)
    layout.addWidget(button2)
    layout.addWidget(button3)
    
    # 设置布局
    window.setLayout(layout)
    
    window.show()
    sys.exit(app.exec_())
    

    QGridLayout (网格布局)
    import sys
    from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QGridLayout
    
    app = QApplication(sys.argv)
    window = QWidget()
    window.setWindowTitle('网格布局示例')
    window.setGeometry(100, 100, 300, 200)
    
    # 创建网格布局
    layout = QGridLayout()
    
    # 添加按钮到布局 (行, 列, 行跨度, 列跨度)
    layout.addWidget(QPushButton('按钮1'), 0, 0)  # 第0行,第0列
    layout.addWidget(QPushButton('按钮2'), 0, 1)  # 第0行,第1列
    layout.addWidget(QPushButton('按钮3'), 1, 0, 1, 2)  # 第1行,第0列,跨1行2列
    
    # 设置布局
    window.setLayout(layout)
    
    window.show()
    sys.exit(app.exec_())
    

    7. 对话框

    QMessageBox (消息框)
    import sys
    from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QVBoxLayout, QMessageBox
    
    class MessageBoxDemo(QWidget):
        def __init__(self):
            super().__init__()
            self.initUI()
            
        def initUI(self):
            self.setWindowTitle('消息框示例')
            self.setGeometry(100, 100, 300, 200)
            
            layout = QVBoxLayout()
            
            # 创建不同类型的消息框按钮
            info_button = QPushButton('信息消息框')
            info_button.clicked.connect(self.show_info_dialog)
            
            warning_button = QPushButton('警告消息框')
            warning_button.clicked.connect(self.show_warning_dialog)
            
            question_button = QPushButton('问题消息框')
            question_button.clicked.connect(self.show_question_dialog)
            
            # 添加按钮到布局
            layout.addWidget(info_button)
            layout.addWidget(warning_button)
            layout.addWidget(question_button)
            
            self.setLayout(layout)
        
        def show_info_dialog(self):
            QMessageBox.information(self, '信息', '这是一个信息消息框', QMessageBox.Ok)
        
        def show_warning_dialog(self):
            QMessageBox.warning(self, '警告', '这是一个警告消息框', QMessageBox.Ok)
        
        def show_question_dialog(self):
            reply = QMessageBox.question(self, '问题', '你确定要继续吗?', 
                                        QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
            if reply == QMessageBox.Yes:
                print('用户选择了是')
            else:
                print('用户选择了否')
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        demo = MessageBoxDemo()
        demo.show()
        sys.exit(app.exec_())
    

    QFileDialog (文件对话框)
    import sys
    from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QVBoxLayout, QFileDialog, QLabel
    
    class FileDialogDemo(QWidget):
        def __init__(self):
            super().__init__()
            self.initUI()
            
        def initUI(self):
            self.setWindowTitle('文件对话框示例')
            self.setGeometry(100, 100, 400, 200)
            
            layout = QVBoxLayout()
            
            # 创建标签显示选择的文件
            self.file_label = QLabel('未选择文件')
            
            # 创建打开文件按钮
            open_button = QPushButton('打开文件')
            open_button.clicked.connect(self.open_file_dialog)
            
            # 创建保存文件按钮
            save_button = QPushButton('保存文件')
            save_button.clicked.connect(self.save_file_dialog)
            
            # 添加控件到布局
            layout.addWidget(self.file_label)
            layout.addWidget(open_button)
            layout.addWidget(save_button)
            
            self.setLayout(layout)
        
        def open_file_dialog(self):
            options = QFileDialog.Options()
            file_name, _ = QFileDialog.getOpenFileName(
                self, "打开文件", "", "所有文件 (*);;文本文件 (*.txt)", options=options
            )
            if file_name:
                self.file_label.setText(f'选择的文件: {file_name}')
        
        def save_file_dialog(self):
            options = QFileDialog.Options()
            file_name, _ = QFileDialog.getSaveFileName(
                self, "保存文件", "", "所有文件 (*);;文本文件 (*.txt)", options=options
            )
            if file_name:
                self.file_label.setText(f'文件将保存为: {file_name}')
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        demo = FileDialogDemo()
        demo.show()
        sys.exit(app.exec_())
    

    8.事件处理

    import sys
    from PyQt5.QtWidgets import QApplication, QWidget, QLabel
    from PyQt5.QtCore import Qt
    
    class EventHandlingDemo(QWidget):
        def __init__(self):
            super().__init__()
            self.initUI()
            
        def initUI(self):
            self.setWindowTitle('事件处理示例')
            self.setGeometry(100, 100, 400, 300)
            
            self.label = QLabel('在窗口中移动鼠标或按键', self)
            self.label.setGeometry(10, 10, 380, 30)
            
            self.setMouseTracking(True)  # 启用鼠标跟踪
        
        def mouseMoveEvent(self, event):
            # 鼠标移动事件
            self.label.setText(f'鼠标位置: {event.x()}, {event.y()}')
        
        def mousePressEvent(self, event):
            # 鼠标按下事件
            if event.button() == Qt.LeftButton:
                self.label.setText('鼠标左键按下')
            elif event.button() == Qt.RightButton:
                self.label.setText('鼠标右键按下')
        
        def keyPressEvent(self, event):
            # 键盘按下事件
            self.label.setText(f'按键按下: {event.text()}')
        
        def resizeEvent(self, event):
            # 窗口大小改变事件
            self.label.setText(f'窗口大小改变: {event.size().width()} x {event.size().height()}')
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        demo = EventHandlingDemo()
        demo.show()
        sys.exit(app.exec_())
    

    9.综合实例:简单的计算器

    import sys
    from PyQt5.QtWidgets import (QApplication, QWidget, QVBoxLayout, QHBoxLayout, 
                                QPushButton, QLineEdit, QGridLayout)
    
    class Calculator(QWidget):
        def __init__(self):
            super().__init__()
            self.initUI()
            
        def initUI(self):
            self.setWindowTitle('简单计算器')
            self.setGeometry(100, 100, 300, 300)
            
            # 创建显示结果的文本框
            self.display = QLineEdit()
            self.display.setReadOnly(True)  # 设置为只读
            self.display.setAlignment(Qt.AlignRight)  # 右对齐
            self.display.setText('0')
            
            # 创建数字和操作按钮
            grid = QGridLayout()
            buttons = [
                '7', '8', '9', '/',
                '4', '5', '6', '*',
                '1', '2', '3', '-',
                '0', '.', '=', '+'
            ]
            
            positions = [(i, j) for i in range(4) for j in range(4)]
            
            for position, button_text in zip(positions, buttons):
                button = QPushButton(button_text)
                button.clicked.connect(self.on_button_click)
                grid.addWidget(button, *position)
            
            # 创建清除按钮
            clear_button = QPushButton('C')
            clear_button.clicked.connect(self.clear_display)
            
            # 创建主布局
            main_layout = QVBoxLayout()
            main_layout.addWidget(self.display)
            main_layout.addLayout(grid)
            main_layout.addWidget(clear_button)
            
            self.setLayout(main_layout)
            
            # 存储计算状态
            self.reset_state()
        
        def reset_state(self):
            self.first_num = None
            self.operator = None
            self.is_typing = False
        
        def clear_display(self):
            self.display.setText('0')
            self.reset_state()
        
        def on_button_click(self):
            sender = self.sender()
            button_text = sender.text()
            
            if button_text.isdigit() or button_text == '.':
                self.handle_number(button_text)
            elif button_text in ['+', '-', '*', '/']:
                self.handle_operator(button_text)
            elif button_text == '=':
                self.calculate_result()
        
        def handle_number(self, digit):
            if not self.is_typing:
                # 开始输入新数字
                if digit == '.':
                    self.display.setText('0.')
                else:
                    self.display.setText(digit)
                self.is_typing = True
            else:
                # 继续输入数字
                current = self.display.text()
                if digit == '.' and '.' in current:
                    # 已经有小数点了
                    return
                self.display.setText(current + digit)
        
        def handle_operator(self, op):
            # 保存当前显示的数字和操作符
            self.first_num = float(self.display.text())
            self.operator = op
            self.is_typing = False
        
        def calculate_result(self):
            if self.first_num is None or not self.operator:
                return
            
            second_num = float(self.display.text())
            result = 0
            
            if self.operator == '+':
                result = self.first_num + second_num
            elif self.operator == '-':
                result = self.first_num - second_num
            elif self.operator == '*':
                result = self.first_num * second_num
            elif self.operator == '/':
                if second_num == 0:
                    self.display.setText('错误')
                    self.reset_state()
                    return
                result = self.first_num / second_num
            
            # 显示结果
            if result.is_integer():
                self.display.setText(str(int(result)))
            else:
                self.display.setText(str(result))
            
            self.reset_state()
            
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        calc = Calculator()
        calc.show()
        sys.exit(app.exec_())
    


    总结

    以上是PyQt5中最常用的组件和功能,包括:

    1. 基础应用程序结构 (QApplication, QWidget)
    2. 常用控件 (QPushButton, QLabel, QLineEdit, QComboBox, QCheckBox)
    3. 布局管理 (QVBoxLayout, QHBoxLayout, QGridLayout)
    4. 对话框 (QMessageBox, QFileDialog)
    5. 事件处理
    6. 一个综合实例 (简单计算器)

    这些示例涵盖了PyQt5开发中的基础知识,可以根据需要进一步学习更高级的功能,如自定义控件、多线程、数据库连接等。

    下一篇将对更高级功能进行介绍。

    作者:m0_74751715

    物联沃分享整理
    物联沃-IOTWORD物联网 » PyQt5入门教程:从零开始打造Python图形界面应用

    发表回复