Label aktualisieren...

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
Antworten
linuxer7
User
Beiträge: 14
Registriert: Mittwoch 12. Mai 2021, 18:24

Hallo Leute,

ich kann mir vorstellen das einige jetzt aufschreien und sagen:" Oh Man, nicht schon wieder!" Ja leider schon wieder. :(
Seit mehreren Stunden durchforste ich das Internet, ja auch die Forensuche habe ich bemüht und 175 Einträge gefunden, nur leider kann mit den Ergebnissen nichts anfangen, sorry :(

Ich habe hier ein kleines "Progrämmchen", For-Schleife, (Siehe unten) macht nix anderes als per Knopfdruck eine For-schleife zu starten das auf 5 zählt.

Ich habe 2 Probleme und hoffe jemand kann mir auf die Sprünge helfen.
Zum einen wird der Eintrag des Labels nicht aktualisiert beim durchlaufen der Schleife.
Das habe ich mittlerweile verstanden das es erst nach durchlauf der Funktion aktualisiert wird.
Und ja ich weis, time.Sleep(irgendwas) ist schlecht.

Anscheinend gibt es keine einfache Lösung so ala "window.label.update()"
Es kann mit Threads gelöst werden, nur weis ich in meinem Fall leider nicht wie genau ich da vorgehen muss.

Python ist relativ neu für mich und ich bin da wirklich gerade am Anfang und am Lernen, also bitte habt Nachsicht.

Das andere Problem, wenn ich den ganzen Block...

app = widgets.QApplication(sys.argv)
window = uic.loadUi("test_for.ui")

window.start_btn.clicked.connect(start_schleife)

window.show()
sys.exit(app.exec_())

... in eine "Main" Funktion packe ala "def main():" und mit ...

if __name__ == '__main__':
main()

... Aufrufe wird, soviel ich verstanden habe die variable window in der Funktion "def start_schleife():" nicht erkannt.
Liegt vermutlich daran weil sie nur lokal in der Funktion existiert in der sie Definiert wurde.
Was/Wie muss ich es machen dass das Funktioniert ?

Wie gesagt Leute Python ist Neuland für mich und ich bin gerade dabei es zu lernen.
Gesucht im Internet habe ich lange und viel gefunden, aber bezogen auf mein Bespiel nix gefunden und verstanden :(

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import time
import sys
import PyQt5.QtWidgets as widgets
import PyQt5.uic as uic


def start_schleife():
for x in range(1, int(5)+1):
window.label.setText(str(x))
print(x)
time.sleep(1)

app = widgets.QApplication(sys.argv)
window = uic.loadUi("test_for.ui")

window.start_btn.clicked.connect(start_schleife)

window.show()
sys.exit(app.exec_())

Bitte helft mir auf die Sprünge.
Danke .

Gruß
Thomas
Benutzeravatar
sparrow
User
Beiträge: 4164
Registriert: Freitag 17. April 2009, 10:28

Wie du festgestellt hast, ist das ein oft gefragtes Thema.
Eine GUI hat eine eigene Hauptschleife. Diese Hauptschleife darf nie blockieren, weil sie für das "Zeichnen" der Oberfläche, etc. verhanden ist.
GUI-Programmierung ist etwas ganz anderes als das normale, squentielle Abarbeiten eines Programms.

Speziell für Qt musst du dich mit Signalen beschäftigten und Timern, soweit ich weiß.
linuxer7
User
Beiträge: 14
Registriert: Mittwoch 12. Mai 2021, 18:24

Hallo Sparrow,

danke. Ich mach mich schlau.

Gruß
Thomas
Ernie1412
User
Beiträge: 160
Registriert: Freitag 10. Januar 2020, 20:38

Anscheinend gibt es keine einfache Lösung so ala "window.label.update()"

doch gibts !

hier:

Code: Alles auswählen

QtWidgets.QApplication.processEvents()
Hilfe von Anfänger für Anfänger :D :D
Benutzeravatar
__blackjack__
User
Beiträge: 13003
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Ernie1412: Was allerdings die ”Lösung” ist die verhindert das man lernt wie man es richtig/sauber löst, weil man sich da an eine lineare Abarbeitung von Code klammert, die bei GUIs nicht verwendet wird, weil die eben ereignisbasiert funktionieren.

Die Methode kann man aufrufen wenn der Code tatsächlich etwas *tut*. Das Beispiel in der Dokumentation ist kopieren einer Datei. Es ist die falsche Wahl wenn der Code einfach nur schläft, und man *damit* alles blockiert.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Benutzeravatar
DeaD_EyE
User
Beiträge: 1012
Registriert: Sonntag 19. September 2010, 13:45
Wohnort: Hagen
Kontaktdaten:

Minimales Beispiel orientiert an dem, was die Community für "besser" befindet:

Code: Alles auswählen

import time
import sys

import PyQt5.QtWidgets as widgets
import PyQt5.uic as uic
from PyQt5.QtCore import QObject, QThread, pyqtSignal


class MySchleife(QObject):
    finished = pyqtSignal()
    progress = pyqtSignal(str)

    def run(self):
        for x in range(1, 6):
            self.progress.emit(str(x))
            time.sleep(1)
        self.finished.emit()


app = widgets.QApplication(sys.argv)
window = uic.loadUi("test_for.ui")

thread = QThread()

schleife = MySchleife()
schleife.moveToThread(thread)
schleife.progress.connect(window.label.setText)
schleife.finished.connect(thread.quit)

thread.started.connect(schleife.run)

window.start_btn.clicked.connect(thread.start)
window.show()

sys.exit(app.exec_())

Hier ein Artikel: https://realpython.com/python-pyqt-qthr ... th-qthread
Den Thread kann man nach dem Ablauf durch erneutes klicken starten.

Getestet mit diesem UI-Code:

Code: Alles auswählen

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Form</class>
 <widget class="QWidget" name="Form">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>375</width>
    <height>248</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Form</string>
  </property>
  <layout class="QVBoxLayout" name="verticalLayout_2">
   <item>
    <layout class="QVBoxLayout" name="verticalLayout">
     <item>
      <widget class="QLabel" name="label">
       <property name="text">
        <string>TextLabel</string>
       </property>
      </widget>
     </item>
     <item>
      <widget class="QPushButton" name="start_btn">
       <property name="text">
        <string>PushButton</string>
       </property>
      </widget>
     </item>
    </layout>
   </item>
  </layout>
 </widget>
 <resources/>
 <connections/>
</ui>
sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
Benutzeravatar
__blackjack__
User
Beiträge: 13003
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Wobei ich für so einen Countdown keinen Thread bemühen würde — regelmässig etwas aufrufen geht auch mit einem `QTimer` und dessen `timeout()`-Signal.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Antworten