我最多可以更改按钮背景多少次?

时间:2019-06-26 13:32:05

标签: python python-3.x pyside2

所以,我试图用我经过的颜色和白色之间闪烁按钮。在该代码崩溃之后,它似乎只闪烁了很多次。 我已经尝试过以不同的眨眼率实现眨眼,它 还是会在某个时候破裂。

  • 在“ a”中,我有类似“背景颜色:rgb(255,0,0)”的字符串。
  • 在“时间”中,我有一个像[208,280]的列表,也可能是[48,32,48,32,100,280],这表示打开和关闭的时间,“零索引”表示打开,“索引1”表示关闭时间并遵循模式。
while True:
    i = 0
    while i < len(timings):
        if self.p[2] == 1:
            self.b.setStyleSheet("{}".format(a))
            self.b.update()
            time.sleep(timings[i]/1000)
            self.b.setStyleSheet("Background-color: rgb(255,255,255)")
            self.b.update()
            time.sleep(timings[i+1]/1000)
            i = i + 2

self.head1,self.head2,self.head3都有类似这样的内容的列表[“背景色:rgb(255,0,0)”,开和关模式列表,头号#] < / p>

现在,我正在处理三个问题。

def flash(self):
    obj1 = threads(self.head1, self.head1_pb)
    obj2 = threads(self.head2, self.head2_pb)
    obj3 = threads(self.head3, self.head3_pb)
    obj1.start()
    time.sleep(.02)
    obj2.start()
    time.sleep(.02)
    obj3.start()

class threads(Thread):

    def __init__(self, a, pb):
         Thread.__init__(self)
         self.p = a
         self.b = pb

    def run(self):

       a = self.p[0]
       timings = self.p[1]
       print(timings[0])
       while True:
           i = 0
           while i < len(timings):
                if self.p[2] == 1:
                   self.b.setStyleSheet("{}".format(a))
                   self.b.update()
                   time.sleep(timings[i]/1000)
                   self.b.setStyleSheet("Background-color: rgb(255,255,255)")
                   self.b.update()
                   time.sleep(timings[i+1]/1000)
                   i = i + 2
               elif self.p[2] == 2:
                   self.b.setStyleSheet("{}".format(a))
                   self.b.update()
                   time.sleep(timings[i]/1000)
                   self.b.setStyleSheet("Background-color: rgb(255,255,255)")
                   self.b.update()
                   time.sleep(timings[i+1]/1000)
                   i = i + 2
              else:
                   self.b.setStyleSheet("{}".format(a))
                   self.b.update()
                   time.sleep(timings[i]/1000)
                   self.b.setStyleSheet("Background-color: rgb(255,255,255)")
                   self.b.update()
                   time.sleep(timings[i+1]/1000)
                   i = i + 2

1 个答案:

答案 0 :(得分:0)

您可以根据需要多次更改颜色,问题是您不应该使用耗时的循环或使用time.sleep(),因为它们会阻塞生成GUI冻结的eventloop。而是使用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_())

加号:

正如您所注意到的,您有很多数据,最好创建一个迭代器以节省内存。考虑到上述情况,我创建了一个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_())