我已经为此苦苦挣扎了一段时间。我会尽力解释我想做什么,也许你们可以帮助我。
假设我有带有状态标签的 GUI,并且 两个循环如下所示:
for _a in range(3000):
self.changeLabel('_a= '+ str(_a))
for _b in range(5000):
self.changeLabel('_b=' + str(_b))
def changeLabel(self,_text):
self.ui.STATUS.setText(_text) <---ui is a GUI where label is placed.
APP.processEvents()
我希望在按下“开始”(完成)后用结果更新标签(状态),并且我想在按下“停止”按钮时取消循环。
如何使用线程、QEventloop 或任何其他方式(如果存在)来实现此目的。我几乎是 PyQT 的初学者,所以如果有人有任何想法 - 请分享。
谢谢。
最佳答案
实现这一目标的最简单方法是使用生成器和“空闲计时器”。
这个想法是使用 yield
关键字将循环转变为生成器,以便您可以使用 next()
从外部触发每次迭代。然后使用 Qt 的低级计时器(startTimer()
、killTimer()
和 timerEvent()
)创建一个间隔为零的计时器,每次没有更多事件要处理时调用,以运行下一个循环迭代。这使您有机会在循环期间对 GUI 事件使用react,例如处理停止按钮 clicked()
信号。
class MyWidget(QWidget): # Or whatever kind of widget you are creating
def __init__(self, parent, **kwargs):
super(MyWidget, self).__init__(parent, **kwargs)
# ... Create your widgets, connect signals and slots, etc.
self._generator = None
self._timerId = None
def loopGenerator(self):
# Put the code of your loop here
for a in range(3000):
self.ui.STATUS.setText("a=" + a)
# No processEvents() needed, just "pause" the loop using yield
yield
def start(self): # Connect to Start-button clicked()
self.stop() # Stop any existing timer
self._generator = self.loopGenerator() # Start the loop
self._timerId = self.startTimer(0) # This is the idle timer
def stop(self): # Connect to Stop-button clicked()
if self._timerId is not None:
self.killTimer(self._timerId)
self._generator = None
self._timerId = None
def timerEvent(self, event):
# This is called every time the GUI is idle.
if self._generator is None:
return
try:
next(self._generator) # Run the next iteration
except StopIteration:
self.stop() # Iteration has finshed, kill the timer
关于python - PYQT - 如何使用取消按钮取消 GUI 中的循环?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7216087/