以下是一些打破的示例代码:
import sys
import time
from PyQt5.QtWidgets import (QApplication, QDialog,
QProgressBar)
class Actions(QDialog):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.progress = QProgressBar(self)
self.progress.setGeometry(0, 0, 300, 25)
self.show()
self.count = 0
while self.count < 100:
self.count += 1
time.sleep(1) # Example external function
self.progress.setValue(self.count)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = Actions()
sys.exit(app.exec_())
运行此操作会导致其冻结并变得无法响应,尤其是在Windows环境中。用任何非PyQt5函数替换time.sleep
函数将产生相同的结果。
据我所知,这与使用QThread的单独线程中未调用的函数有关。我使用this answer作为参考,并提出了部分解决方案。
import sys
import time
from PyQt5.QtCore import QThread
from PyQt5.QtWidgets import (QApplication, QDialog,
QProgressBar)
class External(QThread):
def run(self):
count = 0
while count < 100:
count += 1
print(count)
time.sleep(1)
class Actions(QDialog):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.progress = QProgressBar(self)
self.progress.setGeometry(0, 0, 300, 25)
self.show()
if __name__ == "__main__":
app = QApplication(sys.argv)
window = Actions()
calc = External()
calc.finished.connect(app.exit)
calc.start()
sys.exit(app.exec_())
这将在后台运行time.sleep
并保持主窗口响应。但是,我不知道如何使用self.progress.setValue
更新值,因为它无法在课程External
中访问。
到目前为止,据我所知,我必须使用信号来实现这一目标。 PyQt4的大部分文档都使得找到解决方案变得更加困难。
我面临的另一个问题是能够从班级External
内启动Actions
主题。
此问题的答案也将成为PyQt5的有价值的文档。 提前谢谢。
答案 0 :(得分:1)
您必须使用信号来更新值。
import sys
import time
from PyQt5.QtCore import QThread, pyqtSignal
from PyQt5.QtWidgets import (QApplication, QDialog,
QProgressBar)
class External(QThread):
countChanged = pyqtSignal(int)
def run(self):
count = 0
while count < 100:
count += 1
self.countChanged.emit(count)
print(count)
time.sleep(1)
class Actions(QDialog):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.progress = QProgressBar(self)
self.progress.setGeometry(0, 0, 300, 25)
self.show()
def onCountChanged(self, value):
self.progress.setValue(value)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = Actions()
calc = External()
calc.countChanged.connect(window.onCountChanged)
calc.start()
sys.exit(app.exec_())
答案 1 :(得分:0)
这是一个从类Actions
内部启动线程并使用按钮的版本:
import sys
import time
from PyQt5.QtCore import QThread, pyqtSignal
from PyQt5.QtWidgets import (QApplication, QDialog,
QProgressBar, QPushButton)
class External(QThread):
countChanged = pyqtSignal(int)
def run(self):
count = 0
while count < 100:
count += 1
time.sleep(1)
print(count)
self.countChanged.emit(count)
class Actions(QDialog):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.progress = QProgressBar(self)
self.progress.setGeometry(0, 0, 300, 25)
self.button = QPushButton('Start', self)
self.button.move(0, 30)
self.show()
self.button.clicked.connect(self.onButtonClick)
def onButtonClick(self):
self.calc = External()
self.calc.countChanged.connect(self.onCountChanged)
self.calc.start()
def onCountChanged(self, value):
self.progress.setValue(value)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = Actions()
sys.exit(app.exec_())