PyQt5:使用QThread弹出进度条

2023-12-13

我怎样才能实现进度条 in a 弹出窗口它通过所谓的 Worker 类(即消耗时间/CPU 的任务)监视正在运行的函数的进度QThread?

我已经检查了无数的示例和教程,但进度条显示在弹出窗口中的事实似乎让一切变得更加困难。我相信我想要的是一件相当简单的事情,但我一直失败,而且我没有想法。

我有一个我想要实现的目标的例子,它基于这个答案:

import sys
import time
from PyQt5.QtCore import QThread, pyqtSignal, QObject, pyqtSlot
from PyQt5.QtWidgets import QApplication, QPushButton, QWidget, QHBoxLayout, QProgressBar, QVBoxLayout


class MainWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Widget")
        self.h_box = QHBoxLayout(self)
        self.main_window_button = QPushButton("Start")
        self.main_window_button.clicked.connect(PopUpProgressB)
        self.h_box.addWidget(self.main_window_button)
        self.setLayout(self.h_box)
        self.show()


class Worker(QObject):
    finished = pyqtSignal()
    intReady = pyqtSignal(int)

    @pyqtSlot()
    def proc_counter(self):  # A slot takes no params
        for i in range(1, 100):
            time.sleep(1)
            self.intReady.emit(i)

        self.finished.emit()


class PopUpProgressB(QWidget):

    def __init__(self):
        super().__init__()
        self.pbar = QProgressBar(self)
        self.pbar.setGeometry(30, 40, 500, 75)
        self.layout = QVBoxLayout()
        self.layout.addWidget(self.pbar)
        self.setLayout(self.layout)
        self.setGeometry(300, 300, 550, 100)
        self.setWindowTitle('Progress Bar')
        self.show()

        self.obj = Worker()
        self.thread = QThread()
        self.obj.intReady.connect(self.on_count_changed)
        self.obj.moveToThread(self.thread)
        self.obj.finished.connect(self.thread.quit)
        self.thread.started.connect(self.obj.proc_counter)
        self.thread.start()

    def on_count_changed(self, value):
        self.pbar.setValue(value)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    main_window = MainWindow()
    sys.exit(app.exec_())

当我运行后者时(例如在 PyCharm Community 2019.3 中),程序崩溃,并且我没有收到任何明确的错误消息。

When I debug it though, it looks like it works, as I am able to see what I intended to achieve: App working during debugging

我有一系列的问题:

  1. 为什么会崩溃?
  2. 为什么在调试过程中会起作用?
  3. 我是否应该放弃并实施进度条(锚定) 应用程序的主窗口?
  4. 我过去已经实现了类似的事情,但没有线程:在工作函数(即 CPU 消耗函数)的循环中,我必须添加QApplication.processEvents()这样在每次迭代时进度条都会有效更新。以这种方式做事显然不是最理想的。与我现在想要实现的目标相比,它仍然是更好的选择吗?

如果我遗漏了一些明显的东西,或者如果这个问题已经在某个地方得到了回答(重复),请原谅:我无法找到这个问题的答案。预先非常感谢您。


解释:

要理解该问题,您必须了解以下内容:

self.main_window_button.clicked.connect(PopUpProgressB)

相当于:

self.main_window_button.clicked.connect(foo)
# ...
def foo():
    PopUpProgressB()

可以观察到,当按下按钮时,会创建一个 PopUpProgressB 对象,该对象没有生命周期,就像“foo”函数的执行一样,几乎是瞬时的,因此弹出窗口将在很短的时间内显示和隐藏。

解决方案:

这个想法是,弹出窗口有一个范围,允许它有一个足够大的生命周期,以显示它应该对类属性弹出对象进行的进度。

# ...
self.main_window_button = QPushButton("Start")
self.popup = PopUpProgressB()
self.main_window_button.clicked.connect(self.popup.show)
self.h_box.addWidget(self.main_window_button)
# ...

这样就不会显示您必须删除对 PopUpProgressB 的 show() 方法的调用:

class PopUpProgressB(QWidget):
    def __init__(self):
        super().__init__()
        # ...
        self.setWindowTitle('Progress Bar')
        # self.show() # <--- remove this line
        self.obj = Worker()
        # ...

既然我已经解释了你的问题的失败,我将回答你的问题:

  1. 为什么会崩溃?当弹出对象被删除时,创建的 QThread 也会被删除,但 Qt 访问不再分配的内存(核心转储),导致应用程序关闭而不抛出任何异常。

  2. 为什么在调试过程中会起作用?许多 IDE(例如 PyCharm)不处理 Qt 错误,因此恕我直言,建议当它们出现此类错误时,在终端/CMD 中执行代码,例如当我执行我获得的代码时:

    QThread: Destroyed while thread is still running
    Aborted (core dumped)
    
  3. 我是否应该放弃并在应用程序的主窗口中实现进度条(锚定)? No.

  4. 我过去已经实现了类似的事情,但没有线程:在工作函数(即 CPU 消耗函数)的循环中,我必须添加 QApplication.processEvents() ,以便在每次迭代时进度条都能有效更新。以这种方式做事显然不是最理想的。与我现在想要实现的目标相比,它仍然是更好的选择吗?如果有更好的替代方案,请不要使用 QApplication::processEvents(),在这种情况下,线程是最好的,因为它使主线程不那么繁忙。


Finally, many of the errors that beginners report in Qt refer to the scope of the variables so I recommend you analyze how much it should be for each variable, for example if you want an object to live the same as the class then make that variable is an attribute of the class, if instead you only use it in a method then it is only a local variable, etc.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

PyQt5:使用QThread弹出进度条 的相关文章

  • 与 iexact 一起使用时,Django get_or_create 无法设置字段

    我想用name iexact with get or create尽可能避免用户输入字段的重复 我的提供者模型有一个名称字段 我在其中使用get or create 查找工作正常 但在第一次创建实例时 如下面的 p1 Timber 示例 名
  • Pandas apply 与 np.vectorize 从现有列创建新列的性能

    我正在使用 Pandas 数据框 并希望创建一个新列作为现有列的函数 我还没有看到关于之间速度差异的很好的讨论df apply and np vectorize 所以我想我会在这里问 熊猫apply 功能很慢 根据我的测量 在一些实验中如下
  • Spark MLlib - 训练隐式警告

    我在使用时不断看到这些警告trainImplicit WARN TaskSetManager Stage 246 contains a task of very large size 208 KB The maximum recommend
  • KFold 和 ShuffleSplit CV 有什么区别?

    看起来 KFold 每次迭代对象时都会生成相同的值 而 Shuffle Split 每次都会生成不同的索引 它是否正确 如果是这样 其中一个相对于另一个有什么用处 cv cross validation KFold 10 n folds 2
  • Python:记录垃圾收集器

    我有一个 python 应用程序 有一些性能问题 我想将垃圾收集器的事件 特别是何时调用 添加到我的日志中 是否可以 thanks http docs python org library gc html gc set debug http
  • 为什么 tkinter / window.update 在我的程序中随着时间的推移变得更慢?

    我发现当我调用 window update 时 当向窗口写入的内容较少时 它的运行速度会更快 但后来 当我向窗口写入更多元素时 window update 需要更长的时间 请参阅下面的我的代码 您可以看到它在更新窗口之前一次向屏幕 100
  • Python + PostgreSQL + 奇怪的ascii = UTF8编码错误

    我有包含字符的 ascii 字符串 x80 代表欧元符号 gt gt gt print x80 当将包含该字符的字符串数据插入数据库时 我得到 psycopg2 DataError invalid byte sequence for enc
  • Python,将迭代函数变成递归函数

    我创建了一个输出 4 3 2 1 0 1 2 3 4 的迭代函数 def bounce2 n s n for i in range n print n n n 1 if n lt 0 for i in range s 1 print n n
  • 将 API 数据存储到 DataFrame 中

    我正在运行 Python 脚本来从 Interactive Brokers API 收集金融市场数据 连接到API后 终端打印出请求的历史数据 如何将数据保存到数据帧中而不是在终端中流式传输 from ibapi wrapper impor
  • Python sqlite3游标没有属性commit

    当我运行这段代码时 path Scripts wallpapers single png conn sqlite3 connect Users Heaven Library Application Support Dock desktopp
  • Django 的 URL 覆盖率测试为 0%,为什么?

    使用姜戈鼻子 我对 URL 进行了测试 但 URL 覆盖率仍然为 0 为什么 python manage py 测试配置文件 这是我的报道 Name Stmts Miss Cover Missing profiles 0 0 100 pro
  • 如何使用循环将十进制转换为二进制?

    我想编写一个程序 将十进制数 0 到 9 转换为二进制数 我可以编写如何使用重复除法将十进制数转换为二进制数的代码 但是 我在创建一个以二进制格式打印十进制数字 0 到 9 的循环时遇到了麻烦 这是我的代码 number 0 remaind
  • 如何从 Python 中指定运行程序的输入文件?

    我正在编写一个外部脚本 以通过笔记本电脑上的 Python mrjob 模块 而不是在 Amazon Elastic Compute Cloud 或任何大型集群上 运行 mapreduce 作业 我读自mrjob文档 http packag
  • 在 matplotlib 中使用 yscale('log') 时缺少误差线

    在某些情况下 当使用对数刻度时 matplotlib 会错误地显示带有误差条的图 假设这些数据 例如在 pylab 内 s 19 0 20 0 21 0 22 0 24 0 v 36 5 66 814250000000001 130 177
  • pip 安装软件包两次

    不幸的是我无法重现它 但我们已经见过几次了 pip 将一个软件包安装两次 如果卸载第一个 第二个就会可见并且也可以被卸载 我的问题 如果一个包安装了两次 如何用 python 检查 背景 我想编写一个测试来检查这一点 devOp Updat
  • 求解不等式系统时“多项式错误:仅允许使用单变量多项式”

    我想找到以下两个常数的区间cons1 and cons2我写了下面的代码 from sympy import Poly from sympy import Abs from sympy solvers inequalities import
  • smooth_idf 是多余的吗?

    The scikit learn 文档 http scikit learn org stable modules generated sklearn feature extraction text TfidfTransformer html
  • 为什么 bot.get_channel() 会产生 NoneType?

    我正在制作一个 Discord 机器人来处理公告命令 当使用该命令时 我希望机器人在特定通道中发送一条消息 并向用户发送一条消息以表明该命令已发送 但是 我无法将消息发送到频道 我尝试了这段代码 import discord import
  • PyQt:在运行时向滚动区域添加小部件

    我试图在运行时通过按下按钮来添加新的小部件 在下面的示例中我使用标签 这里是例子 import sys from PyQt4 QtCore import from PyQt4 QtGui import class Widget QWidge
  • 在 Python 的 Textmate 中突出显示尾随空格?

    我想做类似的事情this http remysharp com 2008 03 30 trailing white space in textmate Textmate 提示 这样当我在 Python 中编写代码时 尾随空白总是以某种方式突

随机推荐

  • 执行包含“/”字符的 vim 替换命令

    我有一个 java 文件 其中写了 t 而不是 t 这是制表符转义函数的正确表示法 我想使用 vim 的替换功能 s 但是当我执行以下操作时 s t t g 我收到错误消息 E488 尾随字符 我怎样才能编写命令以便执行替换 谢谢 使用反斜
  • 找到两组矩阵之间最近的点对

    假设我有两组矩阵 A and B 每个矩阵内部都包含几个点坐标 我想找出其中的点B最近到A并输出元胞数组C相应地列出最近的点对坐标和一个元胞数组D注册未配对的位置 我该怎么做 更具体地说 这就是我想要的 两组矩阵包含点xy坐标 A 1 2
  • 数据框内的 Pandas 转置

    我现在有这个数据 animal age count dogs 1 49 2 134 3 147 4 154 cats 1 189 2 254 3 259 4 261 我想将每个年龄的年龄列转换为 4 个年龄列 animal age1 age
  • 在 Azure AD B2C 中使用状态参数容易遭受开放重定向漏洞吗?

    如果我使用State参数来控制RedirectURI如此处所述 为什么重定向 URL 在 Azure AD B2C 中是完全限定的 我不会容易受到打开重定向漏洞 我不是刚刚把问题从RedirectURI to the State范围 状态参
  • 将未初始化的变量传递给 srand 是个好主意吗?

    将未初始化的变量传递给是个好主意吗srand而不是结果time NULL 这是一个 include并减少一个函数调用 示例代码 include
  • mysqli_error() 需要 1 个参数,0 个给出[重复]

    这个问题在这里已经有答案了 我正在尝试了解 mysql 有人能告诉我为什么这个 mysql 查询不起作用吗 我收到以下错误 警告 mysqli error 需要 正好 1 个参数 0 给出 home freebet2 public html
  • SolrJ:禁用自动提交

    我们有一个 Solr 实例 我们发现在 solrconfig xml 中打开 autoCommit 实际上可以很好地满足我们的需求 但是 在某些实例和某些批处理操作中 我们希望暂时禁用自动提交 我找不到任何东西 但我想知道是否有人知道是否可
  • 如何将 Leaflet 地图嵌入到 Reveal.js 演示文稿中?

    我正在尝试创建一个在 Reveal js 之上运行的演示文稿 其中一张幻灯片中包含一个 Leaflet js 地图 我已将所有必需的 Javascript 和 CSS 文件包含到我的 Reveal js 演示文稿中 并且可以使地图显示在幻灯
  • React-native,动态渲染按钮点击

    我想动态生成一个按钮单击TouchableOpacity在反应本机中 我没有找到任何相关内容 我想要的只是从函数中调用 TouchableOpacity onPress 或查看其对按钮的效果 在钛合金中 我们正在做 button click
  • 无法在 docker 上执行 nvidia 运行时

    我正在尝试让 nvidia docker 在我的 centos7 系统上运行 cat etc systemd system docker service d override conf Service ExecStart ExecStart
  • 将通知链接到闪亮仪表板中的选项卡

    我想将通知链接到 内部 选项卡 为此 我遇到了这个 如何在闪亮的notificationItem中使用href 这似乎在加载应用程序后立即起作用 但在侧边栏中进行一些导航后 链接不再起作用 ui R library shiny librar
  • 如何在java中安全地存储加密密钥? [关闭]

    Closed 这个问题需要多问focused 目前不接受答案 我有一个 java 属性对象 其中包含 Web 服务的身份验证信息 我需要加密该数据 但我不知道需要在哪里存储加密密钥才能保证其安全 加密这些数据并以安全的方式检索它的最佳实践是
  • 从 AngularJS 指令访问属性

    我的 AngularJS 模板包含一些自定义 HTML 语法 例如
  • 如何在 Django REST 框架的可浏览 API 中编辑图标?

    我需要编辑可浏览 API 的图标 是否可以通过覆盖模板中的 api html 来做到这一点 这可以通过在 api html 中添加以下块来实现 block style block super endblock
  • Swift 3 尝试呈现谁的视图不在窗口层次结构中

    这个问题已被问过很多次 但即使在尝试了大多数可能的事情之后 我仍然无法找到适合我的解决方案 这是错误消息 警告 尝试在 上显示其视图不在窗口层次结构中的内容 注意 我没有使用任何导航控制器 我只是以模态方式呈现一个视图控制器我上面有一个用于
  • C 和 C++ 中的标准头文件列表

    在哪里可以找到 C 和 C 中所有头文件的列表 当我构建库时 我收到类似 tree h not found 我想这是 C 和 C 中的标准头文件 这引起了我想了解所有头文件及其贡献的好奇心 有地方可以找吗 我正在 Solaris Unix
  • 完成后将变量保存在 .awk 文件中以供下次运行

    因此 我有一个 awk 文件 它将一个订单文件拆分为多个订单文件 文件名从orders xml 包含100个订单的主文件 到递增的文件 如order 1 xml order 2 xml order 3 xml等 当 awk文件完成文件分割后
  • 用于添加到收藏夹的精灵或类似效果

    我有一个 iPhone 应用程序 其中包含 全部 和 收藏夹 选项卡 其中包含标准主细节布局 在 全部 选项卡上 用户可以选择 添加到收藏夹 我正在寻找一个好的视觉队列来向用户表明这样做后可以从 收藏夹 选项卡访问该项目 是否存在类似 精灵
  • Asp.net WebApi 中的自定义授权 - 一团糟?

    我正在阅读有关 Web Api 授权的多个资源 书籍和一些答案 假设我想添加仅允许某些用户访问的自定义属性 Case 1 我见过这种方法压倒性的 OnAuthorization 如果出现问题 它会设置响应 public class Allo
  • PyQt5:使用QThread弹出进度条

    我怎样才能实现进度条 in a 弹出窗口它通过所谓的 Worker 类 即消耗时间 CPU 的任务 监视正在运行的函数的进度QThread 我已经检查了无数的示例和教程 但进度条显示在弹出窗口中的事实似乎让一切变得更加困难 我相信我想要的是