Seite 1 von 1

Signal kann nicht ausgegeben werden - Signal has no attribute emit

Verfasst: Donnerstag 10. Februar 2022, 14:27
von hölzeli
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

Re: Signal kann nicht ausgegeben werden - Signal has no attribute emit

Verfasst: Donnerstag 10. Februar 2022, 14:48
von __deets__
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.

Re: Signal kann nicht ausgegeben werden - Signal has no attribute emit

Verfasst: Donnerstag 10. Februar 2022, 15:33
von __blackjack__
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?

Re: Signal kann nicht ausgegeben werden - Signal has no attribute emit

Verfasst: Donnerstag 10. Februar 2022, 15:40
von __deets__
Ich denke da hat __blackjack__ recht, siehe https://wiki.qt.io/Qt_for_Python_Signals_and_Slots

Re: Signal kann nicht ausgegeben werden - Signal has no attribute emit

Verfasst: Donnerstag 10. Februar 2022, 15:40
von hölzeli
__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!

Re: Signal kann nicht ausgegeben werden - Signal has no attribute emit

Verfasst: Donnerstag 10. Februar 2022, 15:42
von __deets__
Link auf Dokumentation habe ich gerade gepostet.

Re: Signal kann nicht ausgegeben werden - Signal has no attribute emit

Verfasst: Donnerstag 10. Februar 2022, 15:44
von hölzeli
__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!

Re: Signal kann nicht ausgegeben werden - Signal has no attribute emit

Verfasst: Donnerstag 10. Februar 2022, 15:45
von hölzeli
__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

Re: Signal kann nicht ausgegeben werden - Signal has no attribute emit

Verfasst: Samstag 12. Februar 2022, 13:56
von hölzeli
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