Posted in

只需要十分钟 ,快速体验一把 PyQT6 好不好用一. 前言 一直在为 Python 寻求一个桌面端的框架 ,对于 Py_AI阅读总结 — 包阅AI

包阅导读总结

1. 关键词:PyQT6、Python、桌面端框架、快速上手、爬虫客户端

2. 总结:

本文主要介绍了作者对 PyQT6 的体验,包括基础入门代码、复杂功能如页面体系和界面样式,还讲述了应用部署。此外,实现了一个简单的从掘金抓取文章的爬虫客户端,展示了效果和存在的问题,总结了入门难度、用法和适用场景。

3. 主要内容:

– 前言

– 为 Python 寻求桌面端框架,体验 PyQT6

– PyQT6 使用案例

– 基础入门

– 安装依赖

– 引入对象依赖

– 创建应用对象

– 丰富布局和功能

– 稍微复杂的功能

– 页面体系

– 更复杂的界面样式

– 部署执行文件

– 实现一个简单的爬虫客户端

– 数据爬取

– 专栏列表抓取

– 文章列表抓取

– 关键操作节点

– 左边的侧边栏

– 右边的文章列表

– 最核心的入口函数

– 基础效果展示

– 源码已上传 gitee

– 总结

– 入门难度

– 用法

– 场景

思维导图:

文章地址:https://juejin.cn/post/7403910440608972863

文章来源:juejin.cn

作者:志字辈小蚂蚁

发布时间:2024/8/18 12:05

语言:中文

总字数:2463字

预计阅读时间:10分钟

评分:90分

标签:PyQt6,Python桌面应用开发,GUI框架,应用部署,爬虫客户端


以下为原文内容

本内容来源于用户推荐转载,旨在分享知识与观点,如有侵权请联系删除 联系邮箱 media@ilingban.com

一. 前言

一直在为 Python 寻求一个桌面端的框架 ,对于 PyQT5 之前也有一定的研究 ,但是不太符合期望。

最近发现 PyQT6 已经发布很长一段时间了 ,但是国内文档偏少, 所以决定自己体验一下效果。

本文目的 :

  • 记录 Python PyQT6 的快速上手流程 ,以及使用方式

二. PyQT6 使用案例

2.1 基础入门

入门代码是从 ChatGPT 上面抄的案例 ,我们很简单就能实现一个窗口功能 :

  • S1 : 安装 PyQT6 的依赖 — pip install PyQt6
  • S2 : 代码中引入 PyQT6 的相关对象依赖
  • S3 : 创建一个 QApplication 对象 ,用于承载整个应用
  • S4 : 丰富布局和功能
import sysfrom PyQt6.QtWidgets import QApplication, QWidget, QPushButton, QVBoxLayout, QMessageBoxclass MyApp(QWidget):    def __init__(self):        super().__init__()                self.setWindowTitle('PyQt6 Demo')                self.button = QPushButton('点击一下', self)        self.button.clicked.connect(self.show_message)                layout = QVBoxLayout()        layout.addWidget(self.button)        self.setLayout(layout)    def show_message(self):                QMessageBox.information(self, 'Message', 'Hello, PyQt6!')if __name__ == '__main__':    app = QApplication(sys.argv)        my_app = MyApp()    my_app.resize(300, 200)      my_app.show()      sys.exit(app.exec())

image.png

2.2 稍微复杂一下

入门很简单, 但是生产应用上不会有这么简单的功能 ,在这篇里面会简单演示以下功能 :

  • 更复杂的页面体系 ,包括 Tab 页 ,子项 ,控制台等各种功能组件
  • 更好看的界面样式 : 整体的风格,流程的切换 ,布局等
  • 应用发布 : 打包成可执行的应用进行发布

2.3 功能点一 : 页面体系

PyQT 中有着丰富的组件 ,可以帮助我们实现各种功能

组件 描述
QApplication 应用程序的入口点,处理事件循环和初始化。
QWidget 所有用户界面对象的基类,是空白的 GUI 容器。
QMainWindow 一个主窗口控件,支持菜单栏、工具栏、状态栏等标准窗口功能。
QDialog 对话框窗口,用于短期任务或用户输入。
QPushButton 按钮控件,用户可以点击它来触发动作。
QLabel 文本或图像标签,用于显示只读信息。
QLineEdit 单行文本输入控件,用户可以输入和编辑文本。
QTextEdit 多行文本编辑器,支持富文本格式。
QComboBox 下拉列表控件,允许用户从多个选项中选择。
QCheckBox 复选框控件,允许用户选择或取消选择一个选项。
QRadioButton 单选按钮控件,用户可以从一组互斥的选项中选择一个。
QListView 列表视图控件,用于显示和操作项目列表。
QTreeView 树形视图控件,用于显示和操作层次结构数据。
QTableView 表格视图控件,用于显示二维数据。
QVBoxLayout 垂直布局管理器,用于垂直排列控件。
QHBoxLayout 水平布局管理器,用于水平排列控件。
QGridLayout 网格布局管理器,用于创建行和列的控件布局。
QFormLayout 表单布局管理器,用于以标签-控件对的形式排列控件。
QMessageBox 消息框控件,用于显示信息、警告或错误对话框。
QFileDialog 文件对话框,用于打开、保存文件或选择目录。
QColorDialog 颜色对话框,用于选择颜色。
QFontDialog 字体对话框,用于选择字体。
QProgressBar 进度条控件,用于显示任务的进度。
QSlider 滑动条控件,用于选择范围内的数值。
QSpinBox 旋转框控件,用于选择数值(带步进按钮)。
QTimer 定时器对象,用于触发定时事件。
QCanvas 绘图区域,用于自定义图形的绘制。
QMenuBar 菜单栏控件,用于创建和管理应用程序菜单。
QStatusBar 状态栏控件,用于显示应用程序的状态信息。

@ QtWidgets — PyQt Documentation v6.7.1 (riverbankcomputing.com)

更复杂的功能可以参考官方文档 ,这里就不细说了 👉👉👉

image.png

2.4 功能点二 : 更复杂的界面样式

  • 方式一 : 直接通过代码实现界面的编排
  • 方式二 : 通过 QT Design 帮助我们实现界面的编排

毕竟还是新手 ,方式二对我而言上手过于困难 ,功能不复杂,我这里直接用代码画界面。

image.png

2.5 功能点三 : 部署执行文件

  • S1 : 安装依赖 – pip install pyinstaller
  • S2 : 执行打包命令 – pyinstaller –onefile –windowed –name MyApp main.py
  • S3 : 修改后执行 – pyinstaller MyApp.spec
# -*- mode: python ; coding: utf-8 -*-a = Analysis( ['main.py','data_menu.py','layout_sidebar.py','layout_table.py','data_table.py','data_menu.py'],    pathex=['D:\\code\python\\PythonDemoGit\\pythonDemoGit\\gui_pyqt6'],    binaries=[],    datas=[('styles.qss','.')],    hiddenimports=[],    hookspath=[],    hooksconfig={},    runtime_hooks=[],    excludes=[],    noarchive=False,    optimize=0,)
  • 暂时还不知道有没有不改 spec 文件 , 一次性打包成功的方式
  • datas 注意格式 ,否则也会打包失败
  • 最后文件如下图所示 ,运行即可

image.png

三. 实现一个简单的爬虫客户端

下面开始实现一个简单的爬虫客户端 ,作用就是从掘金抓取文章标题和链接,并且保存在本地 :

3.1 数据爬取

  • S1 : 安装依赖 – pip install requests beautifulsoup4
  • S2 : 先抓取专栏列表 ,再抓起专栏下的文章列表

专栏列表抓取

import requestsfrom bs4 import BeautifulSoupdef search_list(url):    # 发送 HTTP 请求获取页面内容    response = requests.get(url)    # 检查请求是否成功    if response.status_code != 200:        print(f"调用接口异常:")        return []    # 解析页面内容    soup = BeautifulSoup(response.text, 'html.parser')    # 假设详情项在 <a> 标签内,并且包含标题和链接    details = []    # 通过 CSS 选择器抓取数据    for a_tag in soup.select('.column-link'):        # 获取 title        title = "默认名称"        for element in a_tag:            for title_item in element.select(".title"):                title = title_item.get_text().strip()        # 获取地址        link = a_tag['href']        # 如果链接是相对路径,转换为绝对路径        if not link.startswith('http'):            link = requests.compat.urljoin(url, link)        details.append({'title': title, 'link': link})    return details

文章列表抓起

import requestsfrom bs4 import BeautifulSoupdef generate_data(url):    # 发送 HTTP 请求获取页面内容    response = requests.get(url)    # 检查请求是否成功    if response.status_code != 200:        print(f"调用接口异常:")        return []    # 解析页面内容    soup = BeautifulSoup(response.text, 'html.parser')    # 假设详情项在 <a> 标签内,并且包含标题和链接    details = []    # 通过 CSS 选择器抓取数据    for content_list in soup.select('.content-main'):        # 获取 title        title = "默认名称"        link = ""        for title_item in content_list.select(".title"):            title = title_item.get_text().strip()            link = title_item['href']        if not link.startswith('http'):            link = requests.compat.urljoin(url, link)        details.append({'title': title, 'link': link})    return details

3.2 关键操作节点

包括3个节点 :

左边的侧边栏

from PyQt6.QtWidgets import QWidget, QVBoxLayout, QPushButtonfrom data_menu import search_listfrom PyQt6.QtCore import pyqtSignalclass Sidebar(QWidget):    # 定义一个信号,将生成的数据传递出去    data_generated = pyqtSignal(str)    def __init__(self,  parent=None):        super().__init__(parent)        detail_list = search_list(            "https://juejin.cn/user/3790771822007822/columns")        sidebar_layout = QVBoxLayout()        self.setLayout(sidebar_layout)        for detail in detail_list:            button = QPushButton(detail['title'])            button.setProperty("url", detail['link'])            # 为 button 绑定事件            button.clicked.connect(self.on_button_clicked)            sidebar_layout.addWidget(button)                 sidebar_layout.addStretch()     def on_button_clicked(self):        button = self.sender()  # 获取发送信号的按钮        url = button.property("url")        self.data_generated.emit(url)

右边的文章列表

from PyQt6.QtWidgets import QWidget, QVBoxLayout, QTableWidget, QTableWidgetItemfrom data_table import generate_dataclass TableWithPagination(QWidget):    def __init__(self, data, rows_per_page=10, parent=None):        super().__init__(parent)        self.table = QTableWidget()        self.table.setRowCount(rows_per_page)        self.table.setColumnCount(3)        self.table.setHorizontalHeaderLabels(["文章名称", "文章路径"])        self.current_page = 0        self.rows_per_page = rows_per_page        self.total_data = data        # 右侧布局        right_layout = QVBoxLayout()        right_layout.addWidget(self.table)        self.setLayout(right_layout)    def update_table(self, url):        print("拿到url地址:", url)        self.table.clearContents()        data_list = generate_data(url)        for row, data_detail in enumerate(data_list):            print("查询到对象", row, data_detail)            self.table.setItem(row, 0, QTableWidgetItem(data_detail['title']))            self.table.setItem(row, 1, QTableWidgetItem(data_detail['link']))

以及最核心的入口函数

import sysimport osfrom PyQt6.QtWidgets import QApplication, QMainWindow, QWidget, QHBoxLayoutfrom layout_sidebar import Sidebarfrom layout_table import TableWithPaginationclass MainWindow(QMainWindow):    def __init__(self):        super().__init__()        self.setWindowTitle("PyQt Modular Example")        self.resize(800, 600)                data = []        self.table_info = TableWithPagination(data)                self.sidebar = Sidebar()                main_layout = QHBoxLayout()        main_layout.addWidget(self.sidebar)        main_layout.addWidget(self.table_info)                container = QWidget()        container.setLayout(main_layout)        self.setCentralWidget(container)                self.sidebar.data_generated.connect(self.table_info.update_table)                stylesheet_path = os.path.join(os.path.dirname(__file__), 'styles.qss')        self.load_stylesheet(stylesheet_path)    def load_stylesheet(self, filename):        """加载并应用样式表"""        with open(filename, "r", encoding="utf-8") as file:            self.setStyleSheet(file.read())if __name__ == '__main__':    app = QApplication(sys.argv)    window = MainWindow()    window.show()    sys.exit(app.exec())

3.3 基础效果展示

image.png

  • 这个插件仅仅进行了简单的优化 ,总的来说可视化效果还不错
  • 卡顿较为明显 ,主要是在互联网调用延迟上面
  • 初始化布局未自适应 ,体验感一般 ,需要花时间优化样式

针对这些问题 ,我们下一篇着重优化一下展示的效果

3.4 源码已上传 gitee

gitee.com/antblack/Py…

  • 后续的 Python 代码都会陆续提交上去,欢迎 star❤️❤️

image.png

总结

文章内容不复杂, 只是把 PyQT6 学习过程中的核心关键点和内容梳理了出来 ,便于后续业务中开箱即用。

关于这个系列后续还会有计划 ,但是作为子分支 ,更新时间不定 ,欢迎关注。

总结一下 :

  • 入门难度 : 上手不难 , Python 本地人半天足够 ,外地人1-2天。复杂场景要花一些时间。
  • 用法 : 和 Java 或者其他后端语言写前端界面的方式类似, 样式和前端的 CSS 类似
  • 场景 : 能覆盖绝大多数场景

最后的最后 ❤️❤️❤️👇👇👇