2012-01-12 30 views
39

Desidero inviare un segnale da C++ a uno slot nel mio file QML. Ho già funzionato senza parametri di tipo primitivo, anche se se voglio inviare un QString al mio slot QML ho un errore durante la connessione.Segnale C++ allo slot QML in Qt

ho collegare in main.cpp

QObject *contentView = rootObject->findChild<QObject*>(QString("contentView")); 
QObject::connect(&myObj,  SIGNAL(finishedGatheringDataForItem(QString)), 
       contentView, SLOT(updateViewWithItem(QString))); 

la parte relavant del mio file QML

Rectangle { 
     objectName: "contentView" 
     function updateViewWithItem(string) { console.log('got some Items'); } // slot 
} 

Errore:

Object::connect: No such slot QDeclarativeRectangle_QML_2::updateViewWithItem(QString) 
+1

Non hai argomenti QString nel tuo updateViewWithItem? (Quale l'errore indica) – Bart

+0

Mi dispiace, ho dimenticato di aggiungerlo di nuovo dopo il test. Ancora non funziona però. Ho provato updateViewWithItem (QString) e updateViewWithItem (stringa). – alex

+1

segnale da C++ significa una libreria C++ o una classe Qt ??? – UmNyobe

risposta

28

penso che sarebbe meglio se controlli questo tutorial:

http://doc.qt.io/qt-4.8/qtbinding.html

soprattutto questa sezione:

http://doc.qt.io/qt-4.8/qtbinding.html#receiving-signals

penso che l'errore in questo caso potrebbe essere o che non ha dichiarato come uno slot o non hai fatto è invocabile. Entrambe le opzioni sono spiegate nel tutorial di Qt.

Inoltre, è necessario utilizzare un QVariant per scambiare dati tra C++ e QML. Puoi anche registrare tipi, ad es. Widget e materiale, in modo che tu possa usarli in QML come un tipo "nativo" come un rettangolo. Nella maggior parte dei casi questo non è raccomandato, tranne se hai bisogno di alcune certe classi esterne o di alcuni dati che non puoi visualizzare diversamente nell'interfaccia QML.

Il motivo per QVariant è l'approccio basato su Script di QML. QVariant contiene fondamentalmente i tuoi dati e una descrizione del tipo di dati, in modo che il QML sappia come gestirlo correttamente. Ecco perché devi specificare il parametro in QML con String, int ecc. Ma lo scambio di dati originale con C++ rimane un QVariant

Ho già usato il qmlRegisterType, ma è una soluzione molto scomoda per tipi di dati semplici. È piuttosto utilizzato per dati più complessi, come widget personalizzati, elementi Canvas o Video che QML non supporta o estende in modo originale QStandardItemModels. È un modo più conveniente per scambiare dati tra QML e C++ e non necessita di segnali o slot in prima istanza, perché QStandardItemModel aggiorna automaticamente la GUI. Per utilizzare QStandardItemModel è necessario registrare il Tipo con qmlRegisterType ... Il modello può quindi essere utilizzato in viste basate su modelli come ListView ecc.

Ho allegato un tutorial per questo argomento, descrive come utilizzare QListModel.

http://doc.qt.io/qt-4.8/qdeclarativemodels.html

+0

Non uso una sottoclasse QDeclarativeView qui. Come ho sottolineato nella mia domanda, tutto funziona se non esco dal parametro. Devo introdurre QString al mio QML in qualche modo? – alex

+3

In tal caso, provare a utilizzare QVariant. Ho avuto questo problema un paio di volte che QML non riconosce altri tipi di dati rispetto a QVariant. – mmoment

+0

Ehi, questo ha risolto il problema per me! Mi chiedo ancora se c'è una soluzione migliore a questo. Hai mai provato a usare qmlRegisterType? – alex

25

Si dovrebbe usare Connessioni in questo caso (forse è l'unico modo per connettersi).

  1. mettere il vostro oggetto myObj al file QML da `` setContextProperty

    qmlVectorForm->rootContext()->setContextProperty("YourObject", myOb); 
    
  2. il segnale è

    finishedGatheringDataForItem(QString signalString) 
    
  3. Nel file QML, aggiungere Connectios piace qui sotto:

    Connections { 
        target: YourObject 
        onFinishedGatheringDataForItem: { 
         qmlString = signalString 
        } 
    } 
    
+0

Dove nel file QML? – HorusKol

+0

Ciò potrebbe causare ritardi nell'interfaccia utente quando i dati vengono scambiati ad alta frequenza o in grandi quantità. – mmoment

+2

Certo che SIGNAL SLOT non ha sempre buone prestazioni. Pertanto, per l'ottimizzazione, è necessario elaborare i dati prima di inviarli tramite SEGNALE. In alcuni casi, se ci si connette tra due thread, si noti che non si invia SIGNAL con una frequenza così elevata, causando un'interfaccia utente bloccata. Dovresti creare un meccanismo per controllare la frequenza di invio (forse usare il timer o il ritardo) – Ken