label Inhalt in einer Funktion abfragen...

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
linuxer7
User
Beiträge: 14
Registriert: Mittwoch 12. Mai 2021, 18:24

Hallo Leute,

wie frage ich den Inhalt eines Labels in einer Funktion ab ?
Ich suche mir den Wolf, aber finde für meinen Fall keine Passende Lösung.
Momentan versuche ich das ganze Klassenprinzip zu verstehen, was noch ziemliches Neuland für mich ist.

Problem:
Ich habe einen "label1" definiert und schreibe in diesen label1 den Text "test".
In einer Funktion versuche ich den Inhalt des label1 wieder auszulesen, bekomme aber immer einen Fehler.
Was mache ich falsch ??

Danke für eure Hilfe.

Gruß
Thomas

Code: Alles auswählen

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


class fenster(QWidget):
    def __init__(self):
        super().__init__()
        self.initialisieren()
    
    def initialisieren(self)
        label=QLabel(self)
        label.setGeometry(20,500,120,30)
        label.setText("Bestätige Daten :")
        
        label1 = QLabel(self)
        label1.setGeometry(200,500,570,30)
        label1.setFrameShape(QFrame.Panel)
        label1.setFrameShadow(QFrame.Sunken)
        label1.setText("Test")
        
        start_btn=QPushButton(self)
        start_btn.setGeometry(300,650,200,30)
        start_btn.setText("Button 1")
        start_btn.clicked.connect(self.funktion1)
        
        beenden_btn=QPushButton(self)
        beenden_btn.setGeometry(500,650,150,30)
        beenden_btn.setText("Beenden")
        beenden_btn.clicked.connect(self.beenden)            
        
        self.setGeometry(50,50,793,690)
        self.setWindowTitle("RPI-Control")
        self.show()
               
        
    def beenden(self):
        window.close()        
        
   
    def funktion1(self):
        print("Daten werden zusammengestellt")
        print(self.label1.Text())

       
app = QApplication(sys.argv)
window = fenster()
sys.exit(app.exec_())
Benutzeravatar
sparrow
User
Beiträge: 4183
Registriert: Freitag 17. April 2009, 10:28

Schau mal in die Dokumentation von Qt.
Es heißt .setText("New Text") zum setzen und .text() zum lesen.
linuxer7
User
Beiträge: 14
Registriert: Mittwoch 12. Mai 2021, 18:24

Hallo Sparrow,

ja das habe ich auch durch.
Wenn ich " .text" klein schreibe funktioniert das auch nicht.

Daten werden zusammengestellt
Traceback (most recent call last):
File "/home/thomas/entwicklung/programmierung/python/test/test_2.py", line 49, in funktion1
print(self.label1.text())
AttributeError: 'fenster' object has no attribute 'label1'

Der scheint das innerhalb einer Funktion nicht zu kennen. :(
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

Du bindest `label1` in `initialisieren` ja auch nicht an self. `initialisieren` ist übrigens überflüssig, weil das alles auch direkt in __init__ stehen kann, wo zur Zeit fast nichts drin steht.
In de Methode `beenden` ist es falsch, dass Du auf `window` zugreifst und nicht auf `self`.
linuxer7
User
Beiträge: 14
Registriert: Mittwoch 12. Mai 2021, 18:24

Hallo Sirius3.

Ja macht Sinn alles in __init__ zu setzten. "initialisieren" wird dort ja auch nur aufgerufen.
Das und self.close habe ich geändert. Das passiert wenn ich mehrere Videos/Tutorials austeste.
Am Ende habe ich dann alles durcheinander und blicke nix mehr :(

Aber das mit dem label habe ich immer noch nicht gerafft. Wie kann ich den Wert des labels aufrufen.
print(label1.text()) funktioniert ja auch nicht. Wie muss ich das machen ?
Benutzeravatar
sparrow
User
Beiträge: 4183
Registriert: Freitag 17. April 2009, 10:28

"funktioniert auch nicht" ist immer schwierig, weil wir weder den Code kennen, den du ausführst, noch die Fehlermeldung.
Hast du label1 denn an jetzt an self gebunden? Dann musst du das natürlich auch über self. ansprechen.
"label1" taucht ja nicht magisch in der Funktion auf.
JoeBlack
User
Beiträge: 4
Registriert: Dienstag 25. Mai 2021, 20:34

Wenn du beim Aufsetzen von lable1 ein self.lable1schreibst funktioniert es, zumindest bei mir.
Wo ich persönlich jetzt eine Frage habe, warum wird das lable1 zwar angezeigt aber kann nicht abgerufen werden. Dieses 'self' hab ich noch nicht entgültig verstanden.
Ist nicht akut, aber falls jemand Muse hat zu Antworten bzw. ne kurze Erklärung hat..... :)
Benutzeravatar
sparrow
User
Beiträge: 4183
Registriert: Freitag 17. April 2009, 10:28

@JoeBlack: 'self' ist die Instanz der Klasse.

Was eine Instanz ist, ist klar?

Code: Alles auswählen

auto = Auto()
Eine Instanz der Klasse Auto wird erstellt und an den Namen Auto gebunden.

Wenn du in __init__ etwas an label1 bindest, dann ist das nicht mehr erreichbar, nachdem __init__ verlassen wurde. Dass kann sinnvoll sein, wenn es sich zum Beispiel um den Zwischenschritt einer Berechnung handelt.

Bindest du es aber an self.label1, dann ist es überall in der in der Instanz ebenso erreichbar und außerdem von außen.
linuxer7
User
Beiträge: 14
Registriert: Mittwoch 12. Mai 2021, 18:24

Morgen Leute,

sorry, mein letzter Beitrag gestern Abend wurde wohl ins Nirwana geschickt.
Wenn du beim Aufsetzen von lable1 ein self.lable1schreibst funktioniert es, zumindest bei mir.
Wo ich persönlich jetzt eine Frage habe, warum wird das lable1 zwar angezeigt aber kann nicht abgerufen werden. Dieses 'self' hab ich noch nicht entgültig verstanden.
Ist nicht akut, aber falls jemand Muse hat zu Antworten bzw. ne kurze Erklärung hat..... :)
....Wenn du in __init__ etwas an label1 bindest, dann ist das nicht mehr erreichbar, nachdem __init__ verlassen wurde. Dass kann sinnvoll sein, wenn es sich zum Beispiel um den Zwischenschritt einer Berechnung handelt.

Bindest du es aber an self.label1, dann ist es überall in der in der Instanz ebenso erreichbar und außerdem von außen.
Jep, danke das war gut.
Es liegt also an der Definition in Init.
Wie gesagt bin gerade dabei die Klassen und Instanzen zu verstehen. Dauert halt :(

Gruß
Thomas
Benutzeravatar
__blackjack__
User
Beiträge: 13063
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@linuxer7: So ganz allgemein: Es ist in der Regel sinnvoll Code zu zeigen der auch lauffähig ist und das Problem zeigt. Der Code im ersten Beitrag passt nicht zu einem `AttributeError` weil der nicht am Compiler vorbei kommt, den hast Du also so nicht ausgeführt um zum beschriebenen Fehler zu kommen. Das war in diesem Fall nicht so schlimm, weil helfende den Fehler recht leicht nur durch's anschauen des Quelltextes finden konnten, aber das ist ja nicht immer der Fall.

Bei dem `beenden()`/`close()` kann man noch sagen, dass `beenden()` nicht wirklich was sinnvolles macht, denn man könnte das Signal statt mit `self.beenden` auch gleich mit `self.close` verbinden.

Sternchen-Importe sind Böse™. Man sieht dann nicht mehr was eigentlich von wo importiert wird, es wird in vielen Fällen mehr importiert als in dem jeweiligen Modul definiert wird — nämlich auch alles was das Modul seinerseits von woanders importiert hat. Und es besteht die Gefahr von Namenskollisionen.

Aus `QtCore` und `QtCore` wird alles importiert, aber gar nichts verwendet.

Klassennamen werden per Konvention in PascalCase geschrieben, also `Fenster`.

Namen sollten keine kryptischen Abkürzungen enthalten und/oder durchnummeriert werden.

Der `show()`-Aufruf gehört nicht in die `__init__()`. Kein bereits vorhandenes Widget zeigt sich dort selbst an, das nimmt dem Aufrufer unnötig Flexibilität beim Einsatz des Widgets.

Es werden viele `set*()`-Aufrufe gemacht direkt nach dem Objekte erstellt wurden, wo man die Werte die da gesetzt werden auch schon beim Erstellen übergeben kann.

`setGeometry()` macht nur sehr selten Sinn und in vielen Fällen funktioniert das platzieren und die Grössenvorgabe mit absoluten Pixelwerten nicht wirklich. Man verwendet Layouts um Widgets relativ zueinander anzuordnen und die Grösse bestimt der jeweilige Inhalt.

Die `exec_()`-Methode mit Unterstrich gibt es in PyQt6 nicht mehr, da sollte man jetzt schon mit aufhören die zu verwenden.

Code: Alles auswählen

#!/usr/bin/env python3
import sys

from PyQt5.QtWidgets import (
    QApplication,
    QFrame,
    QHBoxLayout,
    QLabel,
    QPushButton,
    QVBoxLayout,
    QWidget,
)


class Fenster(QWidget):
    def __init__(self):
        super().__init__(windowTitle="RPI-Control")
        main_layout = QVBoxLayout()

        layout = QHBoxLayout()
        layout.addWidget(QLabel("Bestätige Daten:"))
        self.label = QLabel(
            "Test", frameShape=QFrame.Panel, frameShadow=QFrame.Sunken
        )
        layout.addWidget(self.label)
        main_layout.addLayout(layout)

        layout = QHBoxLayout()
        layout.addWidget(QPushButton("Button 1", clicked=self.on_start))
        layout.addWidget(QPushButton("Beenden", clicked=self.close))
        main_layout.addLayout(layout)

        self.setLayout(main_layout)

    def on_start(self):
        print("Daten werden zusammengestellt")
        print(self.label.text())


def main():
    app = QApplication(sys.argv)
    window = Fenster()
    window.show()
    sys.exit(app.exec_())


if __name__ == "__main__":
    main()
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
linuxer7
User
Beiträge: 14
Registriert: Mittwoch 12. Mai 2021, 18:24

Hallo Blackjack,
So ganz allgemein: Es ist in der Regel sinnvoll Code zu zeigen der auch lauffähig ist und das Problem zeigt. Der Code im ersten Beitrag passt nicht zu einem `AttributeError` weil der nicht am Compiler vorbei kommt, den hast Du also so nicht ausgeführt um zum beschriebenen Fehler zu kommen.
Da muss ich leider widersprechen. Der Code wurde so von mir in Spyder3 unter Linux (oder war es mittlerweile Spyder5) ausgeführt. Ich werde sicher keinen Code Posten den Ihr nicht nachvollziehen könnt. Damit ist mir nämlich nicht geholfen.

Danke trotzdem für dein Erklärungen.
Ich muss den Code momentan noch so "Primitiv" schreiben weil ich es so noch lesen kann. Wie gesagt Python ist absolutes Neuland für mich.
Sicher ist es sinnvoll Anfänger auf Fehler aufmerksam zu machen, oder besser,- darauf hinzuweisen wie es besser geht einen Code zu schreiben allerdings sollte das an zweiter Stelle stehen.

Aber in diesem Fall konnte mir geholfen werden und ich habe auch wieder etwas gelernt. Man lernt eben nie aus ;)

Gruß
Thomas
Benutzeravatar
__blackjack__
User
Beiträge: 13063
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@linuxer7: Der Code hatte einen Syntaxfehler, der lief so sicher nicht.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Antworten