Signal kann nicht ausgegeben werden - Signal has no attribute emit

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
Antworten
hölzeli
User
Beiträge: 5
Registriert: Donnerstag 10. Februar 2022, 13:53

Hi!

ich häng seit gestern an einem Fehler. Baue grad zum ersten mal in QT für Python eine GUI, hatte vorher von der Uni aus mal mit QT in C++ gearbeitet. Die Basics mit signals und slots und wieso man sie braucht habe ich (glaube ich) verstanden. Jetzt treten aber Fehler auf, die ich nicht ganz nachvollziehen kann:

Ich kann ein selbst erstelltes Signal nicht ausgeben (gui_controller.py, letzte Zeile). AttributeError: 'PySide6.QtCore.Signal' object has no attribute 'emit'
Hier ein kleiner Ausschnitt aus dem Code, mit dem sich der Fehler reproduzieren lassen sollte:

main.py:

Code: Alles auswählen

"""Init everything that is necessary to run the application."""

# pylint --extension-pkg-allow-list=PySide6

import sys

from gui_modules.gui_controller import GUIController
from PySide6 import QtWidgets

def main():
    """Init and run the application."""
    app = QtWidgets.QApplication([])
    gui_controller = GUIController()
    sys.exit(app.exec())


if __name__ == '__main__':
    main()
gui_controller.py:

Code: Alles auswählen

"""Save currently selected objects and button states."""

# pylint --extension-pkg-allow-list=PySide6

from PySide6 import QtWidgets
from PySide6.QtCore import Signal


class GUIController(QtWidgets.QWidget):
    """The GuiController class."""

    def __init__(self) -> None:
        """Populate the current instance."""
        super().__init__()
        self.sig_added_category_and_subcategory = Signal()
        self.sig_added_category_and_subcategory.emit()
mir sagt pylint auch, dass es 'Signal' in PySide6.QtCore nicht geben würde. Das liegt vermutlich daran, dass PySide6 in C vorliegt, oder? Oder kanns sein, dass mir da Sachen von PySide6 fehlen? hab das ganz normal über pip install installiert

Kann mir jemand sagen, was ich falsch mache? In der Dokumentation hab ich es eigentlich genau so gesehen wie ich es hier mache.

Und noch eine Frage zur Vererbung:
hier habe ich auch Probleme; hab einige Klassen, die von QtWidgets.QtGridLayout erben, diese kann ich dann nicht per self.addWidget einem anderen Objekt, das ebenfalls von QtWidgets.QtGridLayout erbt, hinzufügen (Falsche Signatur weils ja eine andere Klasse ist; sollte aber eig genauso hinzugefügt werden können, oder? Oder wie funktioniert subclassing sonst?).
Falls jemand da auch grad eine schnelle Lösung parat hat wäre ich sehr dankbar wenn ihr mir das erklären könntet. Ansonsten kann ich dafür auch ein eigenes Thema aufmachen/vllt klärt sich das auch wenn das erste Problem beantwortet wurde (auch wenn ich nicht wüsste wie das zusammenhängen könnte).

Viele Grüße und danke schonmal für eure Hilfe!
Jakob
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

signal wird kleingeschrieben.

Nachtrag: stimmt nicht, das ist PyQt. Aber es gab wohl eine Veränderung, es ist seit erst einiger Zeit Signal, davor war es SIGNAL.
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Kann man Signale überhaupt in einem Exemplar erstellen? Ich kenne das so, dass die auf Klassenebene erstellt werden und dann Metaklassenmagie dafür sorgt, das auf Exemplaren dann ein Attribut mit gleichem Namen und einer `emit()`-Methode entsteht. Weil irgendwo muss ja eine Verbindung vom Signal zur *Klasse* erstellt werden, oder sehe ich das falsch?
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ich denke da hat __blackjack__ recht, siehe https://wiki.qt.io/Qt_for_Python_Signals_and_Slots
hölzeli
User
Beiträge: 5
Registriert: Donnerstag 10. Februar 2022, 13:53

__deets__ hat geschrieben: Donnerstag 10. Februar 2022, 14:48 signal wird kleingeschrieben.

Nachtrag: stimmt nicht, das ist PyQt. Aber es gab wohl eine Veränderung, es ist seit erst einiger Zeit Signal, davor war es SIGNAL.
Ja, habs tdm mal mit signal kleingeschrieben probiert aber das importiert er mir nicht/ist nicht vorhanden. SIGNAL liefert mir auch nur nen string, finde zur Funktion nix in der Doku.
Danke trotzdem für die Antwort!
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Link auf Dokumentation habe ich gerade gepostet.
hölzeli
User
Beiträge: 5
Registriert: Donnerstag 10. Februar 2022, 13:53

__blackjack__ hat geschrieben: Donnerstag 10. Februar 2022, 15:33 Kann man Signale überhaupt in einem Exemplar erstellen? Ich kenne das so, dass die auf Klassenebene erstellt werden und dann Metaklassenmagie dafür sorgt, das auf Exemplaren dann ein Attribut mit gleichem Namen und einer `emit()`-Methode entsteht. Weil irgendwo muss ja eine Verbindung vom Signal zur *Klasse* erstellt werden, oder sehe ich das falsch?
Aaah das macht auf jeden Fall Sinn das nicht für jede Instanz neu zu definieren, stimmt. Ich schau gleich mal ob sich jetzt was ändert. Vielen Dank schonmal!
hölzeli
User
Beiträge: 5
Registriert: Donnerstag 10. Februar 2022, 13:53

__deets__ hat geschrieben: Donnerstag 10. Februar 2022, 15:42 Link auf Dokumentation habe ich gerade gepostet.
ja, habs gesehen, Dankeschön! ich meld mich sobald ich was rausgefunden hab
hölzeli
User
Beiträge: 5
Registriert: Donnerstag 10. Februar 2022, 13:53

Also das mit der Definition der Signale in der Klasse selbst anstatt in der __init__ einer Instanz war die Lösung, vielen Dank!
Zusammengefasst (falls jmdn mal das selbe Problem hat): Signal() einem Klassenattribut (z.B. demo) zuweisen, Signal emittieren dann in einer Instanz (nicht auf Klassenlevel!) über self.demo.emit(). Zmdt hats bei mir so funktioniert.

Vielen Dank euch nochmal!

P.S.: die zweite Frage hat sich mittlerweile geklärt, ich kann den Beitrag aber nicht mehr bearbeiten. Layouts müssen einem anderen Layout über addLayout als Unterlayout oder über setLayout einem anderen Widget zugewiesen werden.
P.P.S.: nächstes mal poste ich die beiden Fragen separat
Antworten