英文:
error while using QProgressbar PyQt5 python
问题
我有以下代码,在其中我实现了一个QProgressDialog,第一次按“开始”按钮运行create函数时它运行正常,但如果对话框完成并尝试再次运行它,它会显示一个不增加进度的空进度条。有任何想法吗?
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
import sys
import time
class Worker(QObject):
signal = pyqtSignal(int)
def __init__(self):
super().__init__()
@pyqtSlot()
def do_work(self) -> None:
for value in range(1, 101):
self.signal.emit(value)
time.sleep(0.01)
class Window(QMainWindow):
def __init__(self):
super().__init__()
self.layout = QVBoxLayout()
self.con = QWidget()
self.setCentralWidget(self.con)
self.con.setLayout(self.layout)
self.btn = QPushButton("开始", self)
self.layout.addWidget(self.btn)
self.thread = QThread()
self.thread.finished.connect(self.thread_finished)
self.btn.pressed.connect(self.create)
def create(self):
self.p = QProgressDialog("进度", "取消", 0, 100)
self.p.setValue(0)
self.p.setWindowModality(Qt.ApplicationModal)
self.p.canceled.connect(self.p.deleteLater)
self.p.show()
self.worker = Worker()
self.worker.signal.connect(self.p.setValue)
self.worker.moveToThread(self.thread)
self.thread.started.connect(self.worker.do_work)
self.thread.start()
def thread_finished(self):
self.thread.deleteLater()
app = QApplication(sys.argv)
window = Window()
window.show()
app.exec_()
我尝试将对话框设为局部变量,但也不起作用。
英文:
i have the following code in which I implemented a QprogressDialog it works fine the first time I press the Start button to run the create function but if the dialog finishes and I try to run it again it shows an empty bar that does not increases the progress. any ideas?
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
import sys
import time
class Worker(QObject):
signal = pyqtSignal(int)
def __init__(self):
super().__init__()
@pyqtSlot()
def do_work(self) -> None:
for value in range(1,101):
self.signal.emit(value)
time.sleep(0.01)
class Window(QMainWindow):
def __init__(self):
super().__init__()
self.layout = QVBoxLayout()
self.con = QWidget()
self.setCentralWidget(self.con)
self.con.setLayout(self.layout)
self.btn = QPushButton("Start",self)
self.layout.addWidget(self.btn)
self.thread = QThread()
self.thread.finished.connect(self.thread_finished)
self.btn.pressed.connect(self.create)
def create(self):
self.p = QProgressDialog("Names", "Cancel", 0, 100)
self.p.setValue(0)
self.p.setWindowModality(Qt.ApplicationModal)
self.p.canceled.connect(self.p.deleteLater)
self.p.show()
self.worker = Worker()
self.worker.signal.connect(self.p.setValue)
self.worker.moveToThread(self.thread)
self.thread.started.connect(self.worker.do_work)
self.thread.start()
def thread_finished(self):
self.thread.deletelater()
# self.thread = QThread()
# self.thread.finished.connect(self.thread_finished)
app = QApplication(sys.argv)
window = Window()
window.show()
app.exec_()
i tried making the dialog a local variable but it does not work either
答案1
得分: 2
当do_work
完成后,它只是返回,但线程仍然存活,因此当你再次调用start()
时,不会发生任何事情:
如果线程已经在运行,此函数什么也不做。
此外,删除和重新创建对话框或线程是没有意义的。最多,你需要重新创建工作线程(假设它具有一些实例属性,如果重新启动将不再使用),但最重要的部分是,你必须在函数结束时告诉线程使用工作线程对象中的一个信号来 quit()
。
class Worker(QObject):
signal = pyqtSignal(int)
finished = pyqtSignal()
@pyqtSlot()
def do_work(self) -> None:
self.keepRunning = True
for value in range(1, 101):
if not self.keepRunning:
break
self.signal.emit(value)
time.sleep(0.01)
self.finished.emit()
def stop(self):
self.keepRunning = False
class Window(QMainWindow):
def __init__(self):
# ...
self.p = QProgressDialog("Names", "Cancel", 0, 100)
self.p.setWindowModality(Qt.ApplicationModal)
def create(self):
self.p.show()
self.worker = Worker()
self.worker.signal.connect(self.p.setValue)
self.p.canceled.connect(self.worker.stop)
self.worker.moveToThread(self.thread)
self.worker.finished.connect(self.thread.quit)
self.thread.started.connect(self.worker.do_work)
self.thread.finished.connect(self.worker.deleteLater)
self.thread.start()
注意:你遇到的问题是一个问题,而不是一个错误。
英文:
When do_work
finishes, it just returns, but the thread is still alive, so nothing happens when you call again start()
:
> If the thread is already running, this function does nothing.
Besides, deleting and recreating the dialog or the thread is pointless. At most, you need to recreate the worker (assuming it has some instance attributes that will not be used again if restarted), but the most important part is that you have to tell the thread to quit()
when your function ends, using a signal in the worker object.
class Worker(QObject):
signal = pyqtSignal(int)
finished = pyqtSignal()
@pyqtSlot()
def do_work(self) -> None:
self.keepRunning = True
for value in range(1,101):
if not self.keepRunning:
break
self.signal.emit(value)
time.sleep(0.01)
self.finished.emit()
def stop(self):
self.keepRunning = False
class Window(QMainWindow):
def __init__(self):
# ...
self.p = QProgressDialog("Names", "Cancel", 0, 100)
self.p.setWindowModality(Qt.ApplicationModal)
def create(self):
self.p.show()
self.worker = Worker()
self.worker.signal.connect(self.p.setValue)
self.p.canceled.connect(self.worker.stop)
self.worker.moveToThread(self.thread)
self.worker.finished.connect(self.thread.quit)
self.thread.started.connect(self.worker.do_work)
self.thread.finished.connect(self.worker.deleteLater)
self.thread.start()
<sup>Note: what you had was a problem, not an error.</sup>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论