首页 > 解决方案 > 使用 PySide/PyQt 运行 QThread 时禁用元素

问题描述

这是我单击“确定”按钮时得到的。

但我想在run_action()仍在运行时禁用这两个按钮,最后将其重置bar为 0。

这是我当前的代码:

import sys
import time

from PySide6.QtCore import QThread, Signal
from PySide6.QtWidgets import (
    QApplication,
    QHBoxLayout,
    QProgressBar,
    QPushButton,
    QWidget,
)


class External(QThread):
    progressChanged = Signal(int)

    def run(self):
        progress = 0
        while progress < 100:
            progress += 10
            time.sleep(1)
            self.progressChanged.emit(progress)


class Window(QWidget):
    """The main application Window."""

    def __init__(self):
        super().__init__()
        self.setWindowTitle("Example")

        self.layout = QHBoxLayout()
        self.layout.setContentsMargins(6, 6, 6, 6)

        self.bar = QProgressBar()
        self.bar.setTextVisible(False)
        self.bar.setValue(0)
        self.layout.addWidget(self.bar)

        self.cancel_btn = QPushButton("Cancel")
        self.cancel_btn.clicked.connect(self.close)
        self.layout.addWidget(self.cancel_btn)

        self.ok_btn = QPushButton("OK")
        self.ok_btn.clicked.connect(self.run_action)
        self.layout.addWidget(self.ok_btn)

        self.setLayout(self.layout)

    def run_action(self):
        self.ok_btn.setEnabled(False)
        self.cancel_btn.setEnabled(False)

        self.calc = External()
        self.calc.progressChanged.connect(self.onProgressChanged)
        self.calc.start()

        self.cancel_btn.setEnabled(True)
        self.ok_btn.setEnabled(True)
        self.bar.setValue(0)

    def onProgressChanged(self, value):
        self.bar.setValue(value)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = Window()
    window.show()
    sys.exit(app.exec_())

标签: pythonqthreadpyside6

解决方案


无效 QThread:: finished()

该信号在完成执行之前从关联线程发出。

当这个信号发出时,事件循环已经停止运行。除了延迟删除事件外,线程中不会再处理任何事件。该信号可以连接到 QObject::deleteLater(),以释放该线程中的对象。

import sys
#import time

#from PySide6.QtCore import QThread, Signal
from PyQt5.QtCore import QThread, pyqtSignal

#from PySide6.QtWidgets import (
from PyQt5.QtWidgets import (
    QApplication,
    QHBoxLayout,
    QProgressBar,
    QPushButton,
    QWidget,
)


class External(QThread):
#    progressChanged = Signal(int)
    progressChanged = pyqtSignal(int)

    def run(self):
        progress = 0
        while progress <= 100:
            self.progressChanged.emit(progress)
            self.msleep(500)
            progress += 10


class Window(QWidget):
    """The main application Window."""

    def __init__(self):
        super().__init__()
        self.setWindowTitle("Example")

        self.layout = QHBoxLayout()
        self.layout.setContentsMargins(6, 6, 6, 6)

        self.bar = QProgressBar()
        self.bar.setTextVisible(False)
        self.bar.setValue(0)
        self.layout.addWidget(self.bar)

        self.cancel_btn = QPushButton("Cancel")
        self.cancel_btn.clicked.connect(self.close)
        self.layout.addWidget(self.cancel_btn)

        self.ok_btn = QPushButton("OK")
        self.ok_btn.clicked.connect(self.run_action)
        self.layout.addWidget(self.ok_btn)

        self.setLayout(self.layout)

    def run_action(self):
        self.ok_btn.setEnabled(False)        
        self.cancel_btn.setEnabled(False)        

        self.calc = External()
        self.calc.progressChanged.connect(self.onProgressChanged)
        self.calc.finished.connect(self.onFinished)                     # +++
        self.calc.start()

#        self.cancel_btn.setEnabled(True)
#        self.ok_btn.setEnabled(True)
#        self.bar.setValue(0)

    def onProgressChanged(self, value):
        self.bar.setValue(value)

    def onFinished(self):                                               # +++
        self.cancel_btn.setEnabled(True)
        self.ok_btn.setEnabled(True)
        self.bar.setValue(0)        

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = Window()
    window.show()
    sys.exit(app.exec_())

在此处输入图像描述


推荐阅读