2015-02-15 10 views
9

Gerade stieß ich auf ein seltsames Verhalten von Qt-Framework beim Aufrufen überladener C++ - Methoden aus Qml und versuchen, den Grund dafür zu verstehen. Lassen Sie uns sagen, ich habe eine QList<QVariant> -artige Klasse mit den folgenden Methoden:Qt/Qml und Methode Überladungen

... 
Q_SLOT void append(const QVariant &item); 
Q_SLOT void append(const QVariantList &items); 
Q_SLOT void insert(int index, const QVariant &item); 
Q_SLOT void insert(int index, const QVariantList &items); 
... 

QML:

onclicked: { 
    var itemCount = myListObject.size(); 
    myListObject.insert(itemCount, "Item " + (itemCount + 1)); 
} 

Qt entscheidet irgendwie die void insert(int index, const QVariantList &items) Überlastung mit items Argument ein null QVariant eine leere QVariantList gesetzt aufzurufen anstelle der void insert(int index, const QVariant &item) Überladung mit QString verpackt in QVariant.

Nun, wenn ich die Reihenfolge der Erklärungen wie folgt ändern, funktioniert es wie erwartet:

Q_SLOT void insert(int index, const QVariantList &items); 
Q_SLOT void insert(int index, const QVariant &item); 

ich nichts unter Qt-Framework in der Dokumentation in Bezug auf die Reihenfolge der Erklärungen finden konnten, und wie es wirkt sich auf die Art und Weise Methoden gelöst werden während des Aufrufs.

Kann mir bitte jemand erklären? Vielen Dank.

Antwort

3

Diese Frage bezieht sich auf das Überladen in JavaScript. Sobald Sie damit bekannt werden - Sie verstehen Grund von "seltsames Verhalten" Ihres Codes. Schauen Sie sich einfach Function overloading in Javascript - Best practices an.

In wenigen Worten - ich empfehle Ihnen als nächstes zu tun: seit Sie QVariant Variablen auf beiden Seiten (QML und Qt/C++) betreiben können - Variante als Parameter übergeben, und verarbeiten Sie auf Qt/C++ Seite, wie Sie möchten .

Sie können so etwas wie folgt verwenden:

Ihre C++ Klasse erstellt und weitergegeben QML (zB als setContextProperty("TestObject", &tc)):

public slots: 
    Q_SLOT void insert(const int index, const QVariant &something) { 
     qDebug() << __FUNCTION__; 
     if (something.canConvert<QString>()) { 
      insertOne(index, something.toString()); 
     } else if (something.canConvert<QStringList>()) { 
      insertMany(index, something.toStringList()); 
     } 
    } 

private slots: 
    void insertOne(int index, const QString &item) { 
     qDebug() << __FUNCTION__ << index << item; 
    } 

    void insertMany(int index, const QStringList &items) { 
     qDebug() << __FUNCTION__ << index << items; 
    } 

Irgendwo in Ihrem QML:

Button { 
    anchors.centerIn: parent 
    text: "click me" 
    onClicked: { 
     // Next line will call insertOne 
     TestObject.insert(1, "Only one string") 
     // Next line will call insertMany 
     TestObject.insert(2, ["Lots", "of", "strings"]) 
     // Next line will call insertOne 
     TestObject.insert(3, "Item " + (3 + 1)) 
     // Next line will call insertOne with empty string 
     TestObject.insert(4, "") 
     // Next line will will warn about error on QML side: 
     // Error: Insufficient arguments 
     TestObject.insert(5) 
    } 
} 
+4

können Sie erwähnen, was speziell in der Javascript-Überladung System dieses Verhalten provozieren? – UmNyobe

+1

danke für das Versuchen..Ich war nicht auf der Suche nach einer Lösung ... Lösung ist einfach - nur die Reihenfolge der Deklarationen ändern ... Ich habe versucht zu verstehen (für zukünftige Referenz) wie und warum Qt beschließt, die falsche Überladung aufzurufen und ignoriert die Datentypen einfach vollständig. Wenn die Reihenfolge geändert wird, hat es jedoch kein Problem, die richtigen Methodensignaturen zu finden. Auf der Randnotiz beschränkt Ihre Lösung meine Klasse, nur bestimmte Datentypen zu akzeptieren. – gplusplus

+0

Tatsächlich beantwortet dies nicht die Hauptfrage, d.h. * warum * das Verhalten auftritt. Mit Blick auf dieses [alte Commit] (https://qt.gitorious.org/qt/tmartsums-qt/commit/1d7b672fd46abab51a0124ad19aad18e5d14f1a8) gibt es keinen (offensichtlichen) Grund dafür, dass es nicht funktioniert. Fehler?? – BaCaRoZzo

Verwandte Themen