Pyqt5中子线程调用progress_dialog.close()卡死

        写一个class Worker(QtCore.QRunnable):,用它调用函数并传入参数运行,运行时显示一个进度条窗口,函数运行结束后进度条关闭。一开始在run方法中创建进度条窗口,窗口无法显示。应当在__init__中创建窗口,确保在实例化时就创建了窗口:

from PyQt5 import QtCore, QtWidgets

class Worker(QtCore.QRunnable):
    result_signal = QtCore.pyqtSignal(object)  # 定义一个信号,用于发送结果

    def __init__(self, function, *args, **kwargs):
        super(Worker, self).__init__()
        self.function = function
        self.args = args
        self.kwargs = kwargs
        # 在init中创建进度条窗口,确保在 Worker 实例化时就创建了进度条窗口
        self.progress_dialog = QtWidgets.QProgressDialog()
        self.progress_dialog.setRange(0, 0)
        self.progress_dialog.setLabelText("Running...")
        self.progress_dialog.show()

    def run(self):
        # 调用函数并获取结果
        result = self.function(*self.args, **self.kwargs)

        # 发射结果信号
        self.result_signal.emit(result)

        self.progress_dialog.close()

# 示例带参数的函数
def example_function_with_args(arg1, arg2):
    import time
    time.sleep(5)
    return f"Function completed with args: {arg1}, {arg2}"  # 返回一个带参数的示例结果

# 在主函数中使用Worker类来调用带参数的函数并处理结果
if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)

    worker = Worker(example_function_with_args, "arg1_value", "arg2_value")
    worker.result_signal.connect(lambda result: print(f"Result: {result}"))  # 连接信号到处理函数
    QtCore.QThreadPool.globalInstance().start(worker)

    sys.exit(app.exec_())

        然而,这样的写法在具有主窗口的GUI界面有可能会导致进度条窗口卡死。通过断点设置,查到是在self.progress_dialog.close()处卡死,这可能是因为在非主线程中尝试操作 GUI 元素导致的问题。在 PyQt 中,GUI 元素应该只能在主线程中进行操作,否则会导致程序出现不可预测的行为。为了解决这个问题,可以使用信号与槽机制来在工作线程中发出信号,然后在主线程中接收信号并关闭进度条窗口。这样就可以避免在非主线程中操作 GUI 元素导致的问题。

        以下是一个使用信号与槽机制来关闭进度条窗口的示例代码:

from PyQt5 import QtCore, QtWidgets

class Worker(QtCore.QRunnable):
    result_signal = QtCore.pyqtSignal(object)  # 定义一个信号,用于发送结果
    close_signal = QtCore.pyqtSignal()  # 定义一个信号,用于关闭进度条窗口

    def __init__(self, function, *args, **kwargs):
        super(Worker, self).__init__()
        self.function = function
        self.args = args
        self.kwargs = kwargs
        self.progress_dialog = QtWidgets.QProgressDialog()
        self.progress_dialog.setRange(0, 0)
        self.progress_dialog.setLabelText("Running...")
        self.progress_dialog.show()


    def run(self):
        # 调用函数并获取结果
        result = self.function(*self.args, **self.kwargs)

        # 发射结果信号
        self.result_signal.emit(result)

        # 发射关闭信号
        self.close_signal.emit()

# 示例带参数的函数
def example_function_with_args(arg1, arg2):
    return f"Function completed with args: {arg1}, {arg2}"  # 返回一个带参数的示例结果

# 在主函数中使用Worker类来调用带参数的函数并处理结果
if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)

    worker = Worker(example_function_with_args, "arg1_value", "arg2_value")
    worker.result_signal.connect(lambda result: print(f"Result: {result}"))  # 连接结果信号到处理函数
    worker.close_signal.connect(worker.progress_dialog.close)  # 连接关闭信号到关闭进度条窗口函数
    QtCore.QThreadPool.globalInstance().start(worker)

    sys.exit(app.exec_())

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值