QLabel aus eingebundenem .ui file animieren

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
Antworten
sev
User
Beiträge: 16
Registriert: Freitag 19. Juli 2019, 22:01

Hallo zusammen,

ich bin ziemlich neu was Python betrifft und verwende aktuell den Qt Designer um mein GUI zu erstellen.

Ich binde es dann als .ui ein und connecte meine Buttons mit Funktionen.

Letztendlich möchte ich nun ein Label animieren (grün aufblinken), wenn z.B. von externer Quelle ein Trigger kommt.

Ich habe mir das eigentlich so vorgestellt, dass ich erstmal eine Funktion schreibe, die mein Label grundsätzlich aufblinken lässt. Kommt dann ein Trigger, rufe ich diese Funktion einfach auf.

Ich hab den Code mal darauf reduziert, dass lediglich das UI geöffnet wird.

Könnte mir bitte jemand bitte dabei helfen das Label-Objekt "label", bei einem Click auf den PushButton "button_sql", grün aufblinken zu lassen?

Vielen Dank und Grüße!





Python Code:

Code: Alles auswählen

import sys, pyodbc, socket
from PyQt5 import QtCore, QtGui, QtWidgets, uic
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *

		
class MyApp(QMainWindow):
	
	def __init__(self):
		super(MyApp, self).__init__()
		self.ui = uic.loadUi('AGSync.ui', self)	
		

if __name__ == '__main__':
	app = QApplication(sys.argv)
	window = MyApp()
	window.showMaximized()
	sys.exit(app.exec_())

GUI Datei

Code: Alles auswählen

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="windowModality">
   <enum>Qt::NonModal</enum>
  </property>
  <property name="enabled">
   <bool>true</bool>
  </property>
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>1130</width>
    <height>911</height>
   </rect>
  </property>
  <property name="contextMenuPolicy">
   <enum>Qt::DefaultContextMenu</enum>
  </property>
  <property name="windowTitle">
   <string>AGSync</string>
  </property>
  <property name="windowOpacity">
   <double>1.000000000000000</double>
  </property>
  <property name="styleSheet">
   <string notr="true">background-color: rgb(23, 32, 39);

</string>
  </property>
  <property name="tabShape">
   <enum>QTabWidget::Rounded</enum>
  </property>
  <widget class="QWidget" name="centralwidget">
   <layout class="QVBoxLayout" name="verticalLayout">
    <item>
     <widget class="QWidget" name="widget_2" native="true">
      <property name="sizePolicy">
       <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
        <horstretch>0</horstretch>
        <verstretch>0</verstretch>
       </sizepolicy>
      </property>
      <property name="minimumSize">
       <size>
        <width>0</width>
        <height>0</height>
       </size>
      </property>
      <property name="maximumSize">
       <size>
        <width>16777215</width>
        <height>60</height>
       </size>
      </property>
      <property name="styleSheet">
       <string notr="true"/>
      </property>
      <layout class="QHBoxLayout" name="horizontalLayout_2">
       <item>
        <widget class="QWidget" name="widget_3" native="true">
         <layout class="QHBoxLayout" name="horizontalLayout_5">
          <property name="spacing">
           <number>30</number>
          </property>
          <property name="topMargin">
           <number>0</number>
          </property>
          <property name="bottomMargin">
           <number>0</number>
          </property>
          <item>
           <widget class="QPushButton" name="button_sql">
            <property name="sizePolicy">
             <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
              <horstretch>0</horstretch>
              <verstretch>0</verstretch>
             </sizepolicy>
            </property>
            <property name="minimumSize">
             <size>
              <width>0</width>
              <height>40</height>
             </size>
            </property>
            <property name="font">
             <font>
              <family>Calibri</family>
              <pointsize>20</pointsize>
              <weight>75</weight>
              <italic>true</italic>
              <bold>true</bold>
             </font>
            </property>
            <property name="styleSheet">
             <string notr="true">QPushButton{
color: rgb(79, 81, 86);
}

QPushButton:hover{
	color: rgb(232, 232, 232);
}

QPushButton:pressed{
	border-style: none;
}


</string>
            </property>
            <property name="text">
             <string>Import SAP</string>
            </property>
            <property name="flat">
             <bool>true</bool>
            </property>
           </widget>
          </item>
          <item>
           <widget class="QPushButton" name="button_checkdata">
            <property name="font">
             <font>
              <family>Calibri</family>
              <pointsize>22</pointsize>
              <weight>75</weight>
              <italic>true</italic>
              <bold>true</bold>
             </font>
            </property>
            <property name="styleSheet">
             <string notr="true">QPushButton{
color: rgb(79, 81, 86);
}

QPushButton:hover{
	color: rgb(232, 232, 232);
}

QPushButton:pressed{
	border-style: none;
}


</string>
            </property>
            <property name="text">
             <string>Check Data</string>
            </property>
            <property name="flat">
             <bool>true</bool>
            </property>
           </widget>
          </item>
         </layout>
        </widget>
       </item>
       <item>
        <widget class="QWidget" name="widget_5" native="true">
         <layout class="QHBoxLayout" name="horizontalLayout_3">
          <property name="topMargin">
           <number>0</number>
          </property>
          <property name="bottomMargin">
           <number>0</number>
          </property>
          <item>
           <spacer name="horizontalSpacer">
            <property name="orientation">
             <enum>Qt::Horizontal</enum>
            </property>
            <property name="sizeType">
             <enum>QSizePolicy::MinimumExpanding</enum>
            </property>
            <property name="sizeHint" stdset="0">
             <size>
              <width>40</width>
              <height>20</height>
             </size>
            </property>
           </spacer>
          </item>
         </layout>
        </widget>
       </item>
      </layout>
     </widget>
    </item>
    <item>
     <widget class="QLabel" name="label">
      <property name="sizePolicy">
       <sizepolicy hsizetype="Minimum" vsizetype="Maximum">
        <horstretch>0</horstretch>
        <verstretch>0</verstretch>
       </sizepolicy>
      </property>
      <property name="styleSheet">
       <string notr="true">color: rgb(255, 255, 255);</string>
      </property>
      <property name="text">
       <string>NEW ENTRY</string>
      </property>
      <property name="alignment">
       <set>Qt::AlignCenter</set>
      </property>
     </widget>
    </item>
    <item>
     <widget class="QWidget" name="widget_6" native="true">
      <property name="sizePolicy">
       <sizepolicy hsizetype="Minimum" vsizetype="Maximum">
        <horstretch>0</horstretch>
        <verstretch>0</verstretch>
       </sizepolicy>
      </property>
      <property name="minimumSize">
       <size>
        <width>0</width>
        <height>10</height>
       </size>
      </property>
     </widget>
    </item>
    <item>
     <widget class="QWidget" name="widget_4" native="true">
      <property name="maximumSize">
       <size>
        <width>16777215</width>
        <height>50</height>
       </size>
      </property>
      <layout class="QHBoxLayout" name="horizontalLayout_4">
       <property name="spacing">
        <number>9</number>
       </property>
       <property name="topMargin">
        <number>15</number>
       </property>
       <property name="bottomMargin">
        <number>0</number>
       </property>
       <item>
        <spacer name="horizontalSpacer_3">
         <property name="orientation">
          <enum>Qt::Horizontal</enum>
         </property>
         <property name="sizeType">
          <enum>QSizePolicy::MinimumExpanding</enum>
         </property>
         <property name="sizeHint" stdset="0">
          <size>
           <width>0</width>
           <height>0</height>
          </size>
         </property>
        </spacer>
       </item>
       <item>
        <spacer name="horizontalSpacer_5">
         <property name="orientation">
          <enum>Qt::Horizontal</enum>
         </property>
         <property name="sizeType">
          <enum>QSizePolicy::MinimumExpanding</enum>
         </property>
         <property name="sizeHint" stdset="0">
          <size>
           <width>40</width>
           <height>20</height>
          </size>
         </property>
        </spacer>
       </item>
       <item>
        <spacer name="horizontalSpacer_4">
         <property name="enabled">
          <bool>true</bool>
         </property>
         <property name="contextMenuPolicy">
          <enum>Qt::DefaultContextMenu</enum>
         </property>
         <property name="orientation">
          <enum>Qt::Horizontal</enum>
         </property>
         <property name="sizeType">
          <enum>QSizePolicy::MinimumExpanding</enum>
         </property>
         <property name="sizeHint" stdset="0">
          <size>
           <width>0</width>
           <height>0</height>
          </size>
         </property>
        </spacer>
       </item>
       <item>
        <spacer name="horizontalSpacer_2">
         <property name="orientation">
          <enum>Qt::Horizontal</enum>
         </property>
         <property name="sizeType">
          <enum>QSizePolicy::MinimumExpanding</enum>
         </property>
         <property name="sizeHint" stdset="0">
          <size>
           <width>0</width>
           <height>0</height>
          </size>
         </property>
        </spacer>
       </item>
      </layout>
     </widget>
    </item>
    <item>
     <widget class="QWidget" name="widget" native="true">
      <property name="sizePolicy">
       <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
        <horstretch>0</horstretch>
        <verstretch>0</verstretch>
       </sizepolicy>
      </property>
      <layout class="QHBoxLayout" name="horizontalLayout">
       <item>
        <widget class="QTableWidget" name="AG_List">
         <property name="sizePolicy">
          <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
           <horstretch>0</horstretch>
           <verstretch>0</verstretch>
          </sizepolicy>
         </property>
         <property name="maximumSize">
          <size>
           <width>16777215</width>
           <height>16777215</height>
          </size>
         </property>
         <property name="font">
          <font>
           <family>Calibri</family>
           <pointsize>12</pointsize>
           <weight>50</weight>
           <italic>false</italic>
           <bold>false</bold>
          </font>
         </property>
         <property name="styleSheet">
          <string notr="true">QTableWidget {
    gridline-color: rgb(79, 81, 86);
    font: 12pt &quot;Calibri&quot;;
	border: 1px solid;
	border-color: rgb(0, 79, 150);
}
QHeaderView::section {
    background-color: rgb(0, 79, 150);
    padding: 4px;
    font: 12pt &quot;Calibri&quot;;
    border-style: none;
	color: rgb(232, 232, 232);
}
QTableWidget QTableCornerButton::section {
	background-color: rgb(48, 57, 66);
}
QTableView::item:hover{
    background-color: rgb(79, 81, 86);
}
QTableView::item:selected{
    background-color: rgb(0, 79, 150);
}
QTableWidget QTableCornerButton::section {
	background-color: rgb(0, 79, 150);
}
</string>
         </property>
         <property name="verticalScrollBarPolicy">
          <enum>Qt::ScrollBarAlwaysOff</enum>
         </property>
         <property name="horizontalScrollBarPolicy">
          <enum>Qt::ScrollBarAsNeeded</enum>
         </property>
         <property name="editTriggers">
          <set>QAbstractItemView::NoEditTriggers</set>
         </property>
         <property name="columnCount">
          <number>5</number>
         </property>
         <attribute name="horizontalHeaderVisible">
          <bool>true</bool>
         </attribute>
         <attribute name="horizontalHeaderDefaultSectionSize">
          <number>150</number>
         </attribute>
         <attribute name="horizontalHeaderHighlightSections">
          <bool>true</bool>
         </attribute>
         <attribute name="horizontalHeaderMinimumSectionSize">
          <number>50</number>
         </attribute>
         <attribute name="horizontalHeaderShowSortIndicator" stdset="0">
          <bool>false</bool>
         </attribute>
         <attribute name="horizontalHeaderStretchLastSection">
          <bool>true</bool>
         </attribute>
         <attribute name="verticalHeaderCascadingSectionResizes">
          <bool>false</bool>
         </attribute>
         <attribute name="verticalHeaderDefaultSectionSize">
          <number>30</number>
         </attribute>
         <attribute name="verticalHeaderHighlightSections">
          <bool>true</bool>
         </attribute>
         <attribute name="verticalHeaderMinimumSectionSize">
          <number>30</number>
         </attribute>
         <attribute name="verticalHeaderStretchLastSection">
          <bool>false</bool>
         </attribute>
         <row>
          <property name="text">
           <string>asdasd</string>
          </property>
         </row>
         <column>
          <property name="text">
           <string>ID</string>
          </property>
          <property name="font">
           <font>
            <family>MS Shell Dlg 2</family>
            <pointsize>12</pointsize>
           </font>
          </property>
         </column>
         <column>
          <property name="text">
           <string>GatePosition</string>
          </property>
          <property name="font">
           <font>
            <family>MS Shell Dlg 2</family>
            <pointsize>12</pointsize>
           </font>
          </property>
         </column>
         <column>
          <property name="text">
           <string>Time</string>
          </property>
          <property name="font">
           <font>
            <family>MS Shell Dlg 2</family>
            <pointsize>12</pointsize>
            <weight>50</weight>
            <bold>false</bold>
           </font>
          </property>
         </column>
         <column>
          <property name="text">
           <string>EPC</string>
          </property>
          <property name="font">
           <font>
            <family>MS Shell Dlg 2</family>
            <pointsize>12</pointsize>
           </font>
          </property>
         </column>
         <column>
          <property name="text">
           <string>Direction</string>
          </property>
          <property name="font">
           <font>
            <pointsize>12</pointsize>
           </font>
          </property>
         </column>
        </widget>
       </item>
       <item>
        <widget class="QScrollBar" name="verticalScrollBar">
         <property name="sizePolicy">
          <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
           <horstretch>0</horstretch>
           <verstretch>0</verstretch>
          </sizepolicy>
         </property>
         <property name="minimumSize">
          <size>
           <width>20</width>
           <height>0</height>
          </size>
         </property>
         <property name="styleSheet">
          <string notr="true">background-color: rgb(212, 212, 212);

</string>
         </property>
         <property name="orientation">
          <enum>Qt::Vertical</enum>
         </property>
        </widget>
       </item>
       <item>
        <widget class="QTableWidget" name="SAP_List">
         <property name="sizePolicy">
          <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
           <horstretch>0</horstretch>
           <verstretch>0</verstretch>
          </sizepolicy>
         </property>
         <property name="maximumSize">
          <size>
           <width>16777215</width>
           <height>16777215</height>
          </size>
         </property>
         <property name="font">
          <font>
           <family>Calibri</family>
           <pointsize>12</pointsize>
           <weight>50</weight>
           <italic>false</italic>
           <bold>false</bold>
          </font>
         </property>
         <property name="styleSheet">
          <string notr="true">QTableWidget {
    gridline-color: rgb(79, 81, 86);
    font: 12pt &quot;Calibri&quot;;
	border: 1px solid;
	border-color: rgb(0, 79, 150);
}
QHeaderView::section {
    background-color: rgb(0, 79, 150);
    padding: 4px;
    font: 12pt &quot;Calibri&quot;;
    border-style: none;
	color: rgb(232, 232, 232);
}
QTableWidget QTableCornerButton::section {
	background-color: rgb(48, 57, 66);
}
QTableView::item:hover{
    background-color: rgb(79, 81, 86);
}
QTableView::item:selected{
    background-color: rgb(0, 79, 150);
}
QTableWidget QTableCornerButton::section {
	background-color: rgb(0, 79, 150);
}

</string>
         </property>
         <property name="verticalScrollBarPolicy">
          <enum>Qt::ScrollBarAlwaysOff</enum>
         </property>
         <property name="horizontalScrollBarPolicy">
          <enum>Qt::ScrollBarAsNeeded</enum>
         </property>
         <property name="editTriggers">
          <set>QAbstractItemView::NoEditTriggers</set>
         </property>
         <property name="columnCount">
          <number>5</number>
         </property>
         <attribute name="horizontalHeaderVisible">
          <bool>true</bool>
         </attribute>
         <attribute name="horizontalHeaderDefaultSectionSize">
          <number>150</number>
         </attribute>
         <attribute name="horizontalHeaderHighlightSections">
          <bool>true</bool>
         </attribute>
         <attribute name="horizontalHeaderMinimumSectionSize">
          <number>50</number>
         </attribute>
         <attribute name="horizontalHeaderShowSortIndicator" stdset="0">
          <bool>false</bool>
         </attribute>
         <attribute name="horizontalHeaderStretchLastSection">
          <bool>true</bool>
         </attribute>
         <attribute name="verticalHeaderCascadingSectionResizes">
          <bool>false</bool>
         </attribute>
         <attribute name="verticalHeaderDefaultSectionSize">
          <number>30</number>
         </attribute>
         <attribute name="verticalHeaderHighlightSections">
          <bool>true</bool>
         </attribute>
         <attribute name="verticalHeaderMinimumSectionSize">
          <number>30</number>
         </attribute>
         <attribute name="verticalHeaderStretchLastSection">
          <bool>false</bool>
         </attribute>
         <row>
          <property name="text">
           <string>asdasd</string>
          </property>
         </row>
         <column>
          <property name="text">
           <string>ID</string>
          </property>
          <property name="font">
           <font>
            <family>MS Shell Dlg 2</family>
            <pointsize>12</pointsize>
           </font>
          </property>
         </column>
         <column>
          <property name="text">
           <string>GatePosition</string>
          </property>
          <property name="font">
           <font>
            <family>MS Shell Dlg 2</family>
            <pointsize>12</pointsize>
           </font>
          </property>
         </column>
         <column>
          <property name="text">
           <string>Time</string>
          </property>
          <property name="font">
           <font>
            <family>MS Shell Dlg 2</family>
            <pointsize>12</pointsize>
            <weight>50</weight>
            <bold>false</bold>
           </font>
          </property>
         </column>
         <column>
          <property name="text">
           <string>EPC</string>
          </property>
          <property name="font">
           <font>
            <family>MS Shell Dlg 2</family>
            <pointsize>12</pointsize>
           </font>
          </property>
         </column>
         <column>
          <property name="text">
           <string>Direction</string>
          </property>
          <property name="font">
           <font>
            <pointsize>12</pointsize>
           </font>
          </property>
         </column>
        </widget>
       </item>
      </layout>
     </widget>
    </item>
   </layout>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
 </widget>
 <resources/>
 <connections/>
</ui>
__deets__
User
Beiträge: 14542
Registriert: Mittwoch 14. Oktober 2015, 14:29

Was fehlt ist die Beschreibung des triggers. Ruft der Mann im Mond an? Kippt der Reissack in China um? Davon hängt ab, wie man das umsetzt.
sev
User
Beiträge: 16
Registriert: Freitag 19. Juli 2019, 22:01

Trigger soll als Beispiel mal ein Klick auf den Button „button_sql“ sein.
__deets__
User
Beiträge: 14542
Registriert: Mittwoch 14. Oktober 2015, 14:29

Dann musst du das button clicked Signal mit deiner Aktion verbinden. Wie das geht steht in der Signal Slot Dokumentation. Oder zb hier: https://pythonspot.com/pyqt5-signals-and-slots/
Benutzeravatar
__blackjack__
User
Beiträge: 13111
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Zum Grün aufblinken lassen müsste man dann die Textfarbe auf Grün und später dann wieder auf die ursprüngliche Farbe zurück setzen.

Farbe ändern sollte auf zwei Wegen möglich sein: „style sheets“ (siehe `QWidget.setStyleSheet()`) oder in dem ”Richtext”, also eine Untermenge von HTML4, als Beschriftung gesetzt wird, und dort die Schriftfarbe festgelegt wird.

Das wieder zurücksetzen macht man wohl am einfachsten über einen `QTimer.singleShot()`-Aufruf.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
sev
User
Beiträge: 16
Registriert: Freitag 19. Juli 2019, 22:01

__blackjack__ hat geschrieben: Samstag 20. Juli 2019, 11:14 Zum Grün aufblinken lassen müsste man dann die Textfarbe auf Grün und später dann wieder auf die ursprüngliche Farbe zurück setzen.

Farbe ändern sollte auf zwei Wegen möglich sein: „style sheets“ (siehe `QWidget.setStyleSheet()`) oder in dem ”Richtext”, also eine Untermenge von HTML4, als Beschriftung gesetzt wird, und dort die Schriftfarbe festgelegt wird.

Das wieder zurücksetzen macht man wohl am einfachsten über einen `QTimer.singleShot()`-Aufruf.
Super, das hat schon mal funktioniert, vielen Dank.
Ich würde die Animation nun gerne verschönern.
Momentan ändere ich die Farbe von grau auf grün und dann nach einer gewissen Zeit wieder auf grau.
Könnte ich nun auch ein Pulsieren animieren? Also einen kontinuierlichen Übergang von grau auf grün erreichen?

Grüße und vielen Dank!
__deets__
User
Beiträge: 14542
Registriert: Mittwoch 14. Oktober 2015, 14:29

Prinzipiell auf die gleiche Weise. Dem Computer ist es egal, ob du 2 oder 2000 Farben per Timer setzt. Nur wirst du damit denke ich nicht glücklich werden: für solche Art der Animation sind klassische GUI toolkits wie Qt oder tkinter schlicht nicht gemacht. Sowas muss optimiert werden, und dazu gibt es dann zb bei Qt die neuere QML Technik die mit OpenGL als backend sowas deutlich besser macht.
sev
User
Beiträge: 16
Registriert: Freitag 19. Juli 2019, 22:01

Ich habe dazu folgendes Beispiel gefunden.
So wie ich das verstehe, haben die Widgets QButton und QLabel keine Eigenschaft "color", deshalb wird über die Klasse "BlinkButton" ein Button erstellt und die Eigenschaft color durch "=pyqtProperty(QColor, getColor, setColor)" gesetzt.
Dann wird über die QPropertyAnimation eine Schleife erstellt, die zwischen der default_color und dem KeyValue hin und her schwingt.

Könnte ich diese Vorgehensweise auch auf ein bereits bestehendes Label aus meiner .ui-Datei anwenden?

Code: Alles auswählen

from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *

class BlinkButton(QPushButton):
    def __init__(self, *args, **kwargs):
        QPushButton.__init__(self, *args, **kwargs)
        self.default_color = self.getColor()

    def getColor(self):
        return self.palette().color(QPalette.Button)

    def setColor(self, value):
        if value == self.getColor():
            return
        palette = self.palette()
        palette.setColor(self.backgroundRole(), value)
        self.setAutoFillBackground(True)
        self.setPalette(palette)

    def reset_color(self):
        self.setColor(self.default_color)

    color = pyqtProperty(QColor, getColor, setColor)


class Widget(QWidget):

    def __init__(self):
        super(Widget, self).__init__()

        self.resize(300,200)
        layout = QVBoxLayout(self)

        self.button_stop = BlinkButton("Stop")
        layout.addWidget(self.button_stop)

        self.button_start = QPushButton("Start", self)
        layout.addWidget(self.button_start)

        self.animation = QPropertyAnimation(self.button_stop, b"color", self)
        self.animation.setDuration(1000)
        self.animation.setLoopCount(100)
        self.animation.setStartValue(self.button_stop.default_color)
        self.animation.setEndValue(self.button_stop.default_color)
        self.animation.setKeyValueAt(0.1, QColor(0,255,0))

        self.button_start.clicked.connect(self.animation.start)
        self.button_stop.clicked.connect(self.stop)

    def stop(self):
        self.animation.stop()
        self.button_stop.reset_color()

if __name__ == "__main__":
    app = QApplication([])
    w = Widget()
    w.show()
    app.exec_()
__deets__
User
Beiträge: 14542
Registriert: Mittwoch 14. Oktober 2015, 14:29

Wenn das funktioniert, dann gut. Wobei da bei QML noch mehr passiert, durch einen in OpenGL implementierten scene graph. Das sollte dann smoother und/oder effizienter werden.
Antworten