使用间隔计时器进行迭代
Iterate with an interval timer
我正在尝试创建一个函数,它接受项目列表并以指定的时间间隔(使用 Qt 框架中的 QTimer)迭代它们,而不中断程序流的其余部分。
我已经设法使用以下使用内部函数的代码来实现这一点,但我很好奇这是否可以在不使用 self.index
实例变量的情况下以更优雅的方式完成。理想情况下,此计数器应封装在 iterate_with_interval
方法中,但我找不到不使用 global
.
来递增它的方法
我想这可以通过专门的 class 来完成,但我想知道如果没有它是否可以完成。
from PySide6.QtCore import QTimer
from PySide6.QtWidgets import QWidget, QApplication
class MainWindow(QWidget):
def __init__(self):
super().__init__()
self.index = 0
self.iterate_with_interval(['a', 'b', 'c', 'd', 'e'], 200)
print('Execution continues')
def iterate_with_interval(self, items, interval):
timer = QTimer()
timer.setInterval(interval)
def iterate(items, timer):
if self.index < len(items):
print(items[self.index])
self.index += 1
else:
timer.stop()
timer.timeout.connect(lambda: iterate(items, timer))
timer.start()
if __name__ == '__main__':
app = QApplication()
window = MainWindow()
window.show()
app.exec()
你总是需要一个获取列表值的中间函数,所以最优雅的解决方案是创建一个 class 通过迭代器处理逻辑。
from PySide6.QtCore import QTimer, Signal
from PySide6.QtWidgets import QWidget, QApplication
class TimerIterator(QTimer):
value_changed = Signal(object)
def __init__(self, values=None, parent=None):
super().__init__(parent)
self._values = []
self.timeout.connect(self.handle_timeout)
self.values = values or []
@property
def values(self):
return self._values
@values.setter
def values(self, values):
self._values = values
self.setProperty("iterator", iter(self.values))
def handle_timeout(self):
try:
value = next(self.property("iterator"))
except StopIteration:
self.stop()
else:
self.value_changed.emit(value)
class MainWindow(QWidget):
def __init__(self):
super().__init__()
self.timer_iterator = TimerIterator()
self.timer_iterator.values = ["a", "b", "c", "d", "e"]
self.timer_iterator.setInterval(200)
self.timer_iterator.value_changed.connect(print)
self.timer_iterator.start()
if __name__ == "__main__":
app = QApplication()
window = MainWindow()
window.show()
app.exec()
我正在尝试创建一个函数,它接受项目列表并以指定的时间间隔(使用 Qt 框架中的 QTimer)迭代它们,而不中断程序流的其余部分。
我已经设法使用以下使用内部函数的代码来实现这一点,但我很好奇这是否可以在不使用 self.index
实例变量的情况下以更优雅的方式完成。理想情况下,此计数器应封装在 iterate_with_interval
方法中,但我找不到不使用 global
.
我想这可以通过专门的 class 来完成,但我想知道如果没有它是否可以完成。
from PySide6.QtCore import QTimer
from PySide6.QtWidgets import QWidget, QApplication
class MainWindow(QWidget):
def __init__(self):
super().__init__()
self.index = 0
self.iterate_with_interval(['a', 'b', 'c', 'd', 'e'], 200)
print('Execution continues')
def iterate_with_interval(self, items, interval):
timer = QTimer()
timer.setInterval(interval)
def iterate(items, timer):
if self.index < len(items):
print(items[self.index])
self.index += 1
else:
timer.stop()
timer.timeout.connect(lambda: iterate(items, timer))
timer.start()
if __name__ == '__main__':
app = QApplication()
window = MainWindow()
window.show()
app.exec()
你总是需要一个获取列表值的中间函数,所以最优雅的解决方案是创建一个 class 通过迭代器处理逻辑。
from PySide6.QtCore import QTimer, Signal
from PySide6.QtWidgets import QWidget, QApplication
class TimerIterator(QTimer):
value_changed = Signal(object)
def __init__(self, values=None, parent=None):
super().__init__(parent)
self._values = []
self.timeout.connect(self.handle_timeout)
self.values = values or []
@property
def values(self):
return self._values
@values.setter
def values(self, values):
self._values = values
self.setProperty("iterator", iter(self.values))
def handle_timeout(self):
try:
value = next(self.property("iterator"))
except StopIteration:
self.stop()
else:
self.value_changed.emit(value)
class MainWindow(QWidget):
def __init__(self):
super().__init__()
self.timer_iterator = TimerIterator()
self.timer_iterator.values = ["a", "b", "c", "d", "e"]
self.timer_iterator.setInterval(200)
self.timer_iterator.value_changed.connect(print)
self.timer_iterator.start()
if __name__ == "__main__":
app = QApplication()
window = MainWindow()
window.show()
app.exec()