我一直在讨价还价。我会尝试解释我想做什么,也许你们可以帮助我。
所以我想说我的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()
我希望在START按下(完成)后用标签(STATUS)更新结果,并且我想在按下STOP按钮时取消循环。
如何使用Threads,QEventloop或任何其他方式(如果存在)实现此目的。我几乎是PyQT的初学者,所以如果有人有任何想法 - 请分享。
感谢。
答案 0 :(得分:1)
实现这一目标的最简单方法是使用生成器和“空闲计时器”。
我们的想法是使用yield
关键字将您的循环转换为生成器,以便您可以使用next()
从外部触发每次迭代。然后使用Qt的低级计时器(startTimer()
,killTimer()
和timerEvent()
)创建一个间隔为零的计时器,每次没有更多要处理的事件时调用该计时器,运行下一个循环迭代。这使您有机会在循环期间对GUI事件做出反应,例如,处理停止按钮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
答案 1 :(得分:1)
Ferdinand的答案很好,因为它避免使用processEvents()来创建自己的事件循环。但是,我认为有一个更简单的解决方案:为什么不在按下停止按钮时设置标志,如果设置了标志则退出循环?类似的东西:
def stopClicked(self):
self.stop = True
for _a in range(3000):
self.changeLabel('_a= '+ str(_a))
if self.stop:
self.stop = False
break
def changeLabel(self,_text):
self.ui.STATUS.setText(_text) <---ui is a GUI where label is placed.
APP.processEvents()
答案 2 :(得分:-1)
我想解决这个问题。
在创建使用PyQt从传感器拍摄实时照片的循环时,我遇到了类似的问题。
我发现使用QTimer对我来说是唯一可行的解决方案,尝试过yield 1并且检查self.stop是True 。
由于该主题非常过时,我将使用另一个与此处发布的非常类似的示例。
我们想要使用某种信号(在这种情况下是按键)初始化一个计数器,然后我们想用另一次击键来阻止它。
我们将使用QTimer
对象,在计时器发出的timeout()
信号期间升级计数器。
class MyExample(QObject):
timer = QTimer()
cont = 0
def __init__(self):
super(QObject, self).__init__()
# !!! IMPORTANT PART !!!
# Here we connect the timeout of the timer to the count
# function!
self.timer.timeout.connect(self.cont)
def keyEvent(self, e):
# Here we connect the keystroke to the event
# on the object!
if e.key() == Qt.Key_B:
self.start()
elif e.key() == Qt.Key_S:
self.stop()
def start(self):
# Number of milliseconds the timer waits until the timeout
self.timer.start(1000)
def stop(self):
self.timer.stop()
def count(self):
# Increase the counter on timeout
self.cont = self.cont + 1
print self.cont
这至少对我来说很有用! 希望这有助于某人!