包阅导读总结
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())
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)
更复杂的功能可以参考官方文档 ,这里就不细说了 👉👉👉
2.4 功能点二 : 更复杂的界面样式
- 方式一 : 直接通过代码实现界面的编排
- 方式二 : 通过
QT Design
帮助我们实现界面的编排
毕竟还是新手 ,方式二对我而言上手过于困难 ,功能不复杂,我这里直接用代码画界面。
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 注意格式 ,否则也会打包失败
- 最后文件如下图所示 ,运行即可
三. 实现一个简单的爬虫客户端
下面开始实现一个简单的爬虫客户端 ,作用就是从掘金抓取文章标题和链接,并且保存在本地 :
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 基础效果展示
- 这个插件仅仅进行了简单的优化 ,
总的来说可视化效果还不错
卡顿较为明显
,主要是在互联网调用延迟
上面- 初始化布局未自适应 ,体验感一般 ,
需要花时间优化样式
针对这些问题 ,我们下一篇着重优化一下展示的效果
3.4 源码已上传 gitee
gitee.com/antblack/Py…
- 后续的 Python 代码都会陆续提交上去,欢迎 star❤️❤️
总结
文章内容不复杂, 只是把 PyQT6 学习过程中的核心关键点和内容梳理了出来 ,便于后续业务中开箱即用。
关于这个系列后续还会有计划 ,但是作为子分支 ,更新时间不定 ,欢迎关注。
总结一下 :
- 入门难度 : 上手不难 , Python 本地人半天足够 ,外地人1-2天。复杂场景要花一些时间。
- 用法 : 和 Java 或者其他后端语言写前端界面的方式类似, 样式和前端的 CSS 类似
- 场景 : 能覆盖绝大多数场景