Signal and Slots mit struct



  • Hey Leute,

    ist es möglich Strukturen mittels Signal und Slot zu übergeben?
    Also hab nen Signal und Slot so definiert

    signals:
       void emitSignal(struct struct_name *name);
    
    public slots:
       void updateSlot(struct struct_name *name);
    

    Und in meinem Thread vor dem connect

    qRegisterMetaType<struct struct_name>("struct_name");
    

    und mein connect sieht so aus:

    connect(this, SIGNAL(emitSIgnal(struct)), this, SLOT(updateSlot(struct)));
    

    Und jedes mal sagt er mir das er das Signal nicht kennt 😞
    Wie übergebe ich denn dem connect die Struktur?



  • du musst den kompletten typ des struct angeben und nicht nur das schlüsselwort 🙂

    und das struct schlüsselwort ist in c++ nicht notwendig wenn man eine instanz/variable eines struct anlegen möchte

    Probiers mal mit:

    connect(this, SIGNAL(emitSIgnal(struct_name *)), this, SLOT(updateSlot(struct_name *)));
    


  • Vielen Dank!
    Hat funktioniert!



  • Wenn du Pointer über Signals übergeben willst, brauchst du die nicht als MetaType registrieren. Das was du gemacht hast ist nur nötig, wenn du das Struct als Wert übergeben willst.



  • Problem mit dem pointer als Parameter: Wer ist fürs Löschen zuständig?



  • Hängt vom Anwendungsfall ab, meinst du nicht?



  • KuhTee schrieb:

    Hängt vom Anwendungsfall ab, meinst du nicht?

    Klar. Problematisch bleibt es trotzdem.
    * Sender kümmert sich um die Freigabe, dann muss er sich aber auch drum kümmern, dass der Zeiger gültig bleibt. Wird aber schwer, weil der Sender natürlich nicht wissen kann, wie lange das Ding gültig sein muss (denke nur an einen Thread, der mit dem übergebenen Zeiger länger rumrechnet)
    * Empfänger kümmert sich um die Freigabe. Was passiert, wenn mehrere Empfänger an dem Signal hängen?

    Und jedes mal sagt er mir das er das Signal nicht kennt

    Das liegt nicht am qRegisterMetaType, sondern an 2 Fehlern:
    * C++ ist case sensitive - schau mal auf das "i" in "emitSignal" 😉
    * Es werden beim connect Signaturen erwartet, also NUR die Typen der Parameter.

    SIGNAL(emitSignal(struct))
    

    ist ebenso falsch wie

    SIGNAL(emitSignal(struct_name sn))
    

    Korrekt wäre (wenn man die Zeiger rausnimmt):

    SIGNAL(emitSignal(struct_name))
    

    Für den SLOT gilt das Selbe.



  • arghonaut schrieb:

    Klar. Problematisch bleibt es trotzdem.
    * Sender kümmert sich um die Freigabe, dann muss er sich aber auch drum kümmern, dass der Zeiger gültig bleibt. Wird aber schwer, weil der Sender natürlich nicht wissen kann, wie lange das Ding gültig sein muss (denke nur an einen Thread, der mit dem übergebenen Zeiger länger rumrechnet)
    * Empfänger kümmert sich um die Freigabe. Was passiert, wenn mehrere Empfänger an dem Signal hängen?

    Im schlimmsten Fall kann man ja immer noch einen QSharedPointer verwenden.

    Wegen "Sender kümmert sich": Doch, das kann er wissen. Hängt ja aber vom Anwendungsfall ab 😉

    Bei "Empfänger kümmert sich" wirds wirklich schon schwieriger. Wenn man davon ausgibt, dass es einen Empfänger gibt, dann bekommt man das noch irgendwie hin. Aber was wenn es erstmal nur ein Signal ist und man nicht weiss, ob sich wirklich jemand connected hat. Dann ist ein purer Pointer keine Option.



  • KuhTee schrieb:

    Im schlimmsten Fall kann man ja immer noch einen QSharedPointer verwenden.

    Der dann wieder per qRegisterMetaType registriert werden muss.

    Wegen "Sender kümmert sich": Doch, das kann er wissen. Hängt ja aber vom Anwendungsfall ab 😉

    Ja, sicher 😉

    Ich würde sagen, Zeiger dann wenn wirklich Zeiger gebraucht werden -> "genau dieses Objekt" (z.B. die Items in einm QListWidget). Referenzen sind keine Option, da bei QueuedConnections wieder kopiert wird, und man dann eben nicht "genau dieses Objekt" im SLOT bekommt.
    Wenn es nur um Daten geht -> Value oder const Referenz. Ist sicher und Memory-Leak-frei. Und wahrscheinlich das, was der OP eigentlich haben will.


Anmelden zum Antworten