Seite 1 von 1

QPushButton QPropertyAnimation QThread

Verfasst: Dienstag 22. Dezember 2020, 09:18
von Omm
Hallo zusammen
Meine Kernfrage ist:
Wie kann ich eine Animation von einem Pushbutton über einen Thread starten?

Mein Endziel ist es. dass z.b. jeden Tag um 12:00Uhr dieser Butten(Mittag) mit Blinken anfängt. Sobald ein Button angeklickt wird, soll die Animation beendet werden.

Leider habe ich keine Plan wo ich anfangen soll. Die Animation über einen anderen Button konnte ich im Netz finden.
Ich stelle mir das so vor: Thread schaut ob es 12:00 Uhr ist. Dieser startet dann das Blinke. Das Blinken wird erste beendet nach einem Click auf einen Button oder nach 10min.

Mit einem normalen Blinken konnte ich schon lösen, jedoch möchte ich es animiert haben und wenn möglich mit Qt.

Code: Alles auswählen

class WindowProjektEintragen(QWidget):
    ADDDELTATIME_AB_ALARLTIME = datetime.timedelta(hours=0, minutes=10).total_seconds()  # Dauer des blinken.
    STATUS_BLINKI = True

    def __init__(self, *args, **kwargs):
        super(WindowProjektEintragen, self).__init__(*args, **kwargs)
    
        # create schedule
        self.stopBlinking = threading.Event()
        self.quitThread = threading.Event()
        schedule_thread = threading.Thread(name='Scheduling-Thread', target=self.run_schedule_thread)
        schedule_thread.start()

    def run_schedule_thread(self):
        """ run in a separate thread. """
        start_blinkten = settings.getStrValue('START_BLINKZEIT')     # z.b. START_BLINKZEIT = 12:00 aus der settings.ini Datei
        schedule.every().day.at(start_blinkten).do(self.popupmeldung_mittag)
        while not self.quitThread.isSet():
            schedule.run_pending()
            time.sleep(2)

    def popupmeldung_mittag(self):
        color_button = self.palette().color(QPalette.Midlight).getRgb()
        color_highlight = self.palette().color(QPalette.Highlight).getRgb()
        end_time = (time.time() + self.ADDDELTATIME_AB_ALARLTIME)
        while (time.time() < end_time and self.get_status_blinki()) and not self.quitThread.isSet():
            time.sleep(0.5)
            self.b_Mittag.setStyleSheet("background-color: rgb({0}, {1}, {2});".format(color_highlight[0], color_highlight[1], color_highlight[2]))
            time.sleep(0.5)
            self.b_Mittag.setStyleSheet("background-color: rgb({0}, {1}, {2});".format(color_button[0], color_button[1], color_button[2]))
        self.stopBlinking.clear()

    def get_status_blinki(self):
        return self.STATUS_BLINKI

Ich hoffe ich konnte als Anfänger, einigermassen erläutern was mein Endziel ist.

Re: QPushButton QPropertyAnimation QThread

Verfasst: Dienstag 22. Dezember 2020, 09:39
von Sirius3
Threads und GUIs vertragen sich nicht. Wenn Qt und Threads, dann benutzt man QThreads und nicht threading. Hier würde ich aber mit einem QTimer arbeiten.

Re: QPushButton QPropertyAnimation QThread

Verfasst: Dienstag 22. Dezember 2020, 10:18
von __deets__
Ich würde gleich zu dem Animations-Framework greifen, das mit Qt mitkommt. https://doc.qt.io/qt-5/animation-overview.html

Re: QPushButton QPropertyAnimation QThread

Verfasst: Dienstag 22. Dezember 2020, 11:56
von Omm
__deets__ hat geschrieben: Dienstag 22. Dezember 2020, 10:18 Ich würde gleich zu dem Animations-Framework greifen, das mit Qt mitkommt. https://doc.qt.io/qt-5/animation-overview.html
Danke für deine Antwort.
ich denke mir fehlt eine Schlüsselinfo.
als Beispiel:

Code: Alles auswählen

class BlinkButton(QPushButton):
    def __init__(self, *args, **kwargs):
        super(BlinkButton, self).__init__(*args, **kwargs)
        effect = QGraphicsColorizeEffect(self)
        self.setGraphicsEffect(effect)
        self.animation = QtCore.QPropertyAnimation(effect, b"color")
        self.animation.setLoopCount(5)
        self.animation.setDuration(900)
        self.animation.setStartValue(QColor(QtCore.Qt.red))
        self.animation.setEndValue(QColor(QtCore.Qt.darkGreen))
        self.animation.start()
wie kann ich den BlinkButton, aus einem QThread, ausstarten und stoppen . Ein loop mit time.sleep oder ein QThread das permanent läuft führt dazu, dass die Animation gestoppt wird.
Irgendwie fehlt mir die Struktur(das Basis wissen), wie sowas gemacht werden kann.

Re: QPushButton QPropertyAnimation QThread

Verfasst: Dienstag 22. Dezember 2020, 12:18
von Sirius3
@Omm: wie ich schon schrieb, würde ich hierfür keinen Thread benutzen, sondern einen QTimer.

Re: QPushButton QPropertyAnimation QThread

Verfasst: Dienstag 22. Dezember 2020, 13:24
von __deets__
Wenn du etwas in Qt aktivieren willst, dann ist dazu der signal/slot-Mechanismus gedacht. Du kannst in deinem BlinkButton die Slots blinkStart und blinkStop anlegen, und aus anderen Objekten heraus aufrufen, zB von einem von Sirius benannten QTimer.

QThreads wuerde ich an deiner Stelle vergessen, denn Programmierung mit Threads ist *schwer*, und hat viele dem Anfaenger unbekannte Nebenwirkungen.

Re: QPushButton QPropertyAnimation QThread

Verfasst: Dienstag 22. Dezember 2020, 14:37
von Omm
Hallo zusammen

vielen Dank für eure Hilfe.
QTimer scheint wirklich die Zauberloesung zu sein.
zu Testzwecken habe ich dies mal so geloest:

Code: Alles auswählen

class BlinkButton(QPushButton):
    def __init__(self, *args, **kwargs):
        super(BlinkButton, self).__init__(*args, **kwargs)
        QPushButton.__init__(self, *args, **kwargs)

        self.timer = QTimer()

        effect = QGraphicsColorizeEffect(self)
        self.setGraphicsEffect(effect)
        self.animation = QtCore.QPropertyAnimation(effect, b"color")
        self.animation.setLoopCount(1)
        self.animation.setDuration(900)
        self.animation.setStartValue(QColor(QtCore.Qt.red))
        self.animation.setEndValue(QColor(QtCore.Qt.darkGreen))
        print('a')

    def blinkStart(self):
        self.timer.start(1000)
        self.timer.timeout.connect(self.animation.start)
        print('b')

    def blinkStop(self):
        self.timer.stop()
        print('c')


class Widget(QWidget):
    def __init__(self):
        super(Widget, self).__init__()
        self.resize(300,200)
        layout = QVBoxLayout(self)

        self.button_Mittag = BlinkButton("Mittag")
        layout.addWidget(self.button_Mittag)
        self.button_Mittag.clicked.connect(self.stop)

        self.button_Mittag.blinkStart()

    def stop(self):
        self.button_Mittag.blinkStop()


if __name__ == "__main__":
    app = QApplication([])
    w = Widget()
    w.show()
    app.exec_()

so kann ich nun den timer starten oder stoppen. :D
nochmals Vielen herzlichen Dank euch beiden für die Hilfe.