我正在尝试编写一个可以包装在所有可迭代对象上的类,并且该类在进行迭代时显示一个QT进度条,指示程序在循环中走了多远。
为了不阻塞主线程(应该是主线程,因为这是用户在包装类上进行迭代的地方),所以我在辅助线程中运行QApplication,尽管一切正常基本上像预期的那样,我收到了一些我不太了解的神秘警告。
任何人都知道出了什么问题吗?
我在其中放置了一些打印语句,以突出显示警告的确切位置。我收到2个'QObject :: setParent:无法设置父级,新父级处于不同线程中”警告,在调用QApplication.show()之后立即得到,然后在每次调用QProgressBar.setValue( )。
我对此一无所知。
from __future__ import annotations
import time
from typing import Any
from PyQt5 import QtWidgets as Qwidgets
from PyQt5 import QtCore as Qcore
class ProgressBar(Qcore.QObject):
signal_tick, signal_done = Qcore.pyqtSignal(), Qcore.pyqtSignal()
def __init__(self, iterable, name: str = None, text: str = None) -> None:
super().__init__()
self.iterable, self.thread = iterable, Qcore.QThread()
self.app = ProgressBarApp(length=len(iterable))
self.app.moveToThread(self.thread)
self.signal_tick.connect(self.app.on_progress_tick)
self.signal_done.connect(self.app.end_loop)
self.thread.started.connect(self.app.start_loop)
def __iter__(self) -> ProgressBar:
self.__iter = iter(self.iterable)
self.thread.start()
time.sleep(1)
return self
def __next__(self) -> Any:
self.signal_tick.emit()
try:
return next(self.__iter)
except StopIteration:
self.signal_done.emit()
self.thread.quit()
self.thread.wait()
raise StopIteration
class ProgressBarApp(Qwidgets.QApplication):
def __init__(self, length: int) -> None:
super().__init__([])
self.window, self.count = Qwidgets.QMainWindow(), 0
self.bar = Qwidgets.QProgressBar(parent=self.window)
self.bar.setRange(0, length)
self.window.setCentralWidget(self.bar)
@Qcore.pyqtSlot()
def on_progress_tick(self) -> None:
print("Before updating the progressbar.")
self.bar.setValue(self.count)
print("After updating the progressbar.")
self.count += 1
@Qcore.pyqtSlot()
def start_loop(self) -> None:
print("Before showing the main window.")
self.window.show()
print("After showing the main window.")
self.exec()
@Qcore.pyqtSlot()
def end_loop(self) -> None:
self.window.hide()
self.quit()
if __name__ == '__main__':
for _ in ProgressBar(range(10)):
time.sleep(1)