Signal von Objekt aus Klassenmodel in QML nutzen



  • Hallo,

    ich bin gerade dabei in meinem Projekt mit Signal/Slot von C++ in QML Funktionen umzusetzen. Jetzt bin ich aber bei einem Verständnisproblem angekommen wo mir der Ansatz fehlt und hoffe hier kann mir jemand helfen.

    Ich habe ein QAbstractListModel, in dem liegen Objekte der Klasse Clients. Mit dem Model wird eine Liste in der UI gefüllt wo ein Client gewählt werden kann. Es werden dann alle Werte angezeigt und man kann einzelne Werte ändern. Mit bestätigen werden diese Werte in das Objekt geschrieben und übernommen.

    Jetzt habe ich in den jeweiligen Objekten die Werte bekannt gemacht (Beispiel:)

    Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
    

    und versuche jetzt durch das Signal vom Notify im QML eine Funktion auszuführen und stehe vor dem Problem das die jeweiligen Clients im Model erstellt werden und ich deswegen kein "Target" für die QML Verbindung habe wie ich sie sonnst im QML erstelle (der *** Teil wo ich sonnst das Objekt auf das reagiert werden soll angebe).

        Connections {
            target: ***
            onNameChanged: doStuff()
        }
    

    (Quelle: http://doc.qt.io/archives/qt-4.8/qtbinding.html#receiving-signals)

    Hat evtl. jemand einen Tipp für mich wie ich auf die Signale reagieren könnte?

    Am besten wäre wenn ich die Möglichkeit hätte Global auf das Signal (Objektunabhängig) zu reagieren, da ja jeder Client im Model das entsprechende Signal ausführen und im UI bei allen die gleiche Funktion ausgelöst werden kann.

    Besten Dank im Voraus

    PS. Ich hatte überlegt im Zweifel wenn es über Signale nicht funktioniert bei Änderung des Wertes die Funktion im der QML direkt aufzurufen aus dem jeweiligen Objekt. Das liefert aber die Probleme das
    a) das sicher nicht so gewollt ist wenn SIGNAL / SLOT zur Verfügung stehen ich ich sonnst ja auch gerne nutze
    b) ich nicht weiss wie ich auf die Funktionen die im QML stehen aus C++ zugreifen kann



  • Hallo nochmal,

    ich bin jetzt einen Schritt weiter, ich habe im meinem QAbstractListModel das Signal dataChanged(index, index, {role}) in die setData(const QModelIndex &index, const QVariant &value, int role) Funktion des Models implementiert.
    Damit sollte ich die Role die geändert wurde und den Index des Items das geändert wurde erhalten. Und auf das kann ich wiederrum aus dem QML zugreifen.
    Ein normales Connections funktioniert dann auch:

    Connections {
            target: MovieClientModel
            onDataChanged: {
                console.log("Data in Model has Changed")
            }
    }
    

    Löst dann auch wunderbar einmal pro ausgesendetem Signal aus.

    Nur habe ich das Problem die Parameter die das Signal übergibt (die beiden QModelindex und der int) zu nutzen. Hat vielleicht jemand einen Tipp für mich wie ich auf die Parameter des Signals in den Connections zugreifen kann?

    Ich würde gerne an Hand der Role umschalten und eine entsprechende Funktion ausführen.


  • Moderators

    hi @Throndar
    sehr gut, dass du dir schon einmal selbst weiterhelfen konntest ;-)

    zu deine Frage,

    du kannst auf QML Seite ganz einfach auf die Parameter zugreifen, die mit dem Signal kommen, indem du den namen der Argumente schreibst. Zum Beispiel:

    signals:
        void meinSignal(int eineNummer, QString einText);
    
    Connections{
        ....
        onMeinSignal: {
            console.log("Signal ist da:" , eineNummer, einText)
       }
    }
    


  • Hallo @J.Hilk

    ja, ich versuche halt schon selber eine Lösung zu finden und wenn es klappt beantworte ich meine Fragen hier auch gleich im Forum damit anderen geholfen ist :)

    Aber eine Frage habe ich an der Stelle, du hast in deinem Beispiel ein Signal meinSignal in QML definiert was du unten bei den Connections wieder nutzt, das habe ich soweit verstanden. Was mich jetzt verwundert ist, da ich das Signal ja schon "fertig" von einer C++ Klasse erhalte ob ich dann wirklich das ganze im QML nochmal vorher definieren muss wie bei einem komplett neuen Signal.

    Ich war davon ausgegangen wenn das Signal bereits mit Parametern ankommt würde ein neues definieren im QML das ankommende "überschreiben", halt klassisch wie beim überladen einer Funktion.


  • Moderators

    @Throndar said in Signal von Objekt aus Klassenmodel in QML nutzen:

    Hallo @J.Hilk

    ja, ich versuche halt schon selber eine Lösung zu finden und wenn es klappt beantworte ich meine Fragen hier auch gleich im Forum damit anderen geholfen ist :)

    Sehr löblich ;-)! thumbs up

    Aber eine Frage habe ich an der Stelle, du hast in deinem Beispiel ein Signal meinSignal in QML definiert was du unten bei den Connections wieder nutzt, das habe ich soweit verstanden. Was mich jetzt verwundert ist, da ich das Signal ja schon "fertig" von einer C++ Klasse erhalte ob ich dann wirklich das ganze im QML nochmal vorher definieren muss wie bei einem komplett neuen Signal.

    Ich war davon ausgegangen wenn das Signal bereits mit Parametern ankommt würde ein neues definieren im QML das ankommende "überschreiben", halt klassisch wie beim überladen einer Funktion.

    Das ist schlechte Formatierung von meiner Seite aus. Der erste Teil, signals.... ist in deiner c++ Klasse, nur der zweite Teil ist in QML,

    Eventuell musst du dein eigenes Signal definieren. Wenn ich das hier richtig sehe hat das Signal was du nutzt 2 Argumente die index heißen, denke nicht, dass das Möglich ist in QML, die sollten unterschiedlich heißen, damit du die differenzieren kannst.



  • Hallo @J.Hilk ,

    entschuldige die späte Rückmeldung, gerade erst wieder an den Rechner gekommen.

    Manchmal sieht man den Wald vor lauter Bäumen nicht, die Bezeichnung vom Signal das ich überlade hatte ich aus der Doku und ganz vergessen dort Namen hinzuzufügen. Mit deinem Hinweis hattest du natürlich voll und ganz Recht und kaum macht man alles richtig, schon gehts! ;)

    Vielen Dank erneut für deine Hilfe


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.