文章目录
- 一.前言
- 二.开发环境
- 三.坑
- 1.程序没有详细报错就退出了
- 2.qrc资源文件的使用
- 3.QLabel文字自动换行
- 4.图片自适应大小
- 5.checkbox自定义样式后✓不见了
- 6.多线程
- 四.记录
一.前言
本篇博客整理了一些初学者容易犯的错,将会持续更新解决PyQt5开发过程中的一些坑,对新手比较友好,大佬请绕道 /笑哭
二.开发环境
笔者是在Windows11上使用Pycharm配合Python3.8进行开发的,详细开发环境信息如下:
- 处理器:AMD Ryzen 7 7735H with Radeon Graphics 3.20 GHz
- 系统版本:Windows 11 家庭中文版
- 开发工具:PyCharm 2021.3
- Python版本:Python3.8
- PyQt5版本:PyQt5==5.15.10
三.坑
1.程序没有详细报错就退出了
代码执行时,直接报错Process finished with exit code - 1073740791 (Oxc0000409)然后就退出了。
按照下图指引打开“Emulate terminal in output console”
勾选后点击确定或应用
最新版本
然后再执行代码,就能够看到详细报错信息了
2.qrc资源文件的使用
我们在设计师或者代码里使用的资源文件都统一地使用qrc管理,qrc是什么呢?
.qrc是一个XML文件,它允许开发者将应用程序所需的图像、样式表、声音文件等各种资源集中管理。
通过将资源文件.qrc加载到PyQt5应用程序中,开发者可以轻松地访问和使用这些资源。
.qrc文件使用XML格式编写,包含一个或多个元素。
每个元素内可以包含多个元素,每个元素指定一个资源的路径和名称。
我们这里有个例子,比如当前项目根目录有个名为logo.png的图片文件,我们想让QLabel显示这张图片,那么我们可以这么操作:
- 生成.qrc资源文件
- 将qrc通过rcc工具转为.py文件
- 在代码里使用资源
resources.qrc
demo.py
虽然第一步引入代码是灰色,但是不影响使用
有的同学可能会问,我直接写成**self.setPixmap(QPixmap(“logo.png”))**不也能使用资源么?我们这么写的目的是为了打包方便,当资源用多了就能体现得到。
3.QLabel文字自动换行
这个很好解决,一行代码
label.setWordWrap(True)
4.图片自适应大小
让我们的QLabel随着父控件的大小变化
这个很好解决,一行代码
label.setScaledContents(True)
5.checkbox自定义样式后✓不见了
当我们自定义了QCheckBox之后,发现左侧勾选区域的对号不见了,这通常是我们重写了QCheckBox::indicator::unchecked这很影响我们的ui,其实一张图片即可解决,在此我给出定义样式的qss:
#QCheckBox{color:rgb(44,206,162);font-size:11pt;font-weight:520;}
#QCheckBox::indicator::unchecked{ width: 12px; height: 12px; border: 1px solid rgb(44,206,162);background-color:rgb(44,206,162)}
#QCheckBox::indicator::checked{ width: 12px; height: 12px;image:url(:res/tick.png);border: 1px solid rgb(44,206,162);background-color:rgb(44,206,162)}
这里我们需要一张:res/tick.png图片作为勾选后的样式,图片是用qrc转的。
tick.png下载地址:https://wwt.lanzoul.com/iwu9u1zxiehe
大致效果如下图:
6.多线程
这个问题对于新手来说可能不会涉及到,但是随着代码量和需求的叠加,难免会遇到这个问题:主线程(UI线程)耗时太久导致整个界面卡顿甚至卡死,在此我提供一种方案,就是多线程,但是多次的重写QThread会徒增代码量,我给出一种方案解决:
class WorkerThread(QThread):calc_finished = pyqtSignal(dict)def __init__(self, task, *arg, **args):super(WorkerThread, self).__init__()self.arg = argself.args = argsself.task = taskdef run(self):result = self.task(self, *self.arg, **self.args)def do_calc(self, **args):data=dict()try:data=xxx()except:traceback.print_exc()self.calc_finished .emit(data)
代码大致思路是创建一个线程类,里面通过定义不同的函数执行耗时操作,当耗时操作执行完毕后,使用“发射信号”的方式,将数据传递回主线程。
四.记录
本文会持续更新,大家点赞不迷路哈~
2024年5月27日更新1-6