您可以根据需要多次更改颜色,问题是您不应该使用耗时的循环或使用 time.sleep(),因为它们会阻止生成 GUI 冻结的事件循环。相反,使用 QTimer 来调用经常改变颜色的任务。
在以下示例中,创建一个实现您想要的功能的自定义按钮:
from PySide2 import QtCore, QtGui, QtWidgets
class PushButton(QtWidgets.QPushButton):
def __init__(self, *args, **kwargs):
super(PushButton, self).__init__(*args, **kwargs)
self._color = QtGui.QColor("white")
timer_on = QtCore.QTimer(singleShot=True, timeout=self.on_timeout)
timer_off = QtCore.QTimer(singleShot=True, timeout=self.on_timeout)
self._timers = (timer_on, timer_off)
for timer, function in zip(self._timers, (self.on, self.off)):
timer.timeout.connect(function)
def setTime(self, on_time, off_time):
for t, timer in zip((on_time, off_time), self._timers):
timer.setInterval(t)
@QtCore.Slot()
def on_timeout(self):
timer = self.sender()
if timer not in self._timers:
return
timer_on, timer_off = self._timers
another_timer = timer_off if timer is timer_on else timer_on
another_timer.start()
def start(self):
timer_on, _ = self._timers
timer_on.start()
def stop(self):
for timer in self._timers:
timer.stop()
self.off()
def color(self):
return self._color
def setColor(self, color):
if self.color() == color:
return
self._color = color
def on(self):
self.setStyleSheet(
"""PushButton{ background-color: %s}""" % (self.color().name(),)
)
def off(self):
self.setStyleSheet(
"""PushButton{ background-color: rgb(255,255,255)}"""
)
class Widget(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Widget, self).__init__(parent)
button = PushButton()
button.setColor(QtGui.QColor("salmon"))
button.setTime(208, 280)
button.start()
# stop blink in 30 seconds
# QtCore.QTimer.singleShot(30 * 1000, button.stop)
lay = QtWidgets.QVBoxLayout(self)
lay.addWidget(button)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
app.setStyle("fusion")
w = Widget()
w.show()
sys.exit(app.exec_())
Plus:
当您注意到您有大量数据时,最好创建一个迭代器以节省内存。考虑到上述情况,我创建了一个 QPushButton,它从迭代器获取数据。
import random
from functools import partial
from PySide2 import QtCore, QtGui, QtWidgets
def generate_data():
i = 0
while i < 1000000:
color_on = random.randint(10, 500)
color_off = random.randint(10, 500)
color = QtGui.QColor(*random.sample(range(255), 3))
yield color_on, color_off, color
i += 1
class PushButton(QtWidgets.QPushButton):
def __init__(self, *args, **kwargs):
super(PushButton, self).__init__(*args, **kwargs)
self._color = QtGui.QColor("white")
self._generator = None
self.m_timer = QtCore.QTimer(
self, timeout=self.on_timeout, singleShot=True
)
def setGenerator(self, generator):
self._generator = generator
def start(self):
self.on_timeout()
@QtCore.Slot()
def on_timeout(self):
try:
time_on, time_off, color = next(self._generator)
self.setColor(color)
self.m_timer.start(time_on + time_off)
QtCore.QTimer.singleShot(
time_on, partial(self.setColor, QtGui.QColor("white"))
)
except StopIteration:
self.m_timer.stop()
def setColor(self, color):
self.setStyleSheet(
"""PushButton{ background-color: %s}""" % (color.name(),)
)
class Widget(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Widget, self).__init__(parent)
lay = QtWidgets.QVBoxLayout(self)
for _ in range(6):
button = PushButton()
button.setGenerator(generate_data())
button.start()
lay.addWidget(button)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
app.setStyle("fusion")
w = Widget()
w.resize(320, 240)
w.show()
sys.exit(app.exec_())