2012-01-12 5 views
39

Я хочу отправить сигнал с C++ в слот в моем файле QML. У меня уже есть рабочие без параметров примитивного типа, хотя, если я хочу отправить QString в свой QML-слот, я получаю сообщение об ошибке при подключении.Сигнал C++ в слот QML в Qt

подключить в main.cpp

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

relavant часть моего QML файла

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

Ошибка:

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

У вас нет аргумента QString в вашем updateViewWithItem? (Которое указывает на ошибку) – Bart

+0

Извините, что не забыли добавить его снова после тестирования. Тем не менее, не работает. Я попробовал updateViewWithItem (QString) и updateViewWithItem (строка). – alex

+1

Сигнал от C++ означает библиотеку C++ или класс Qt ??? – UmNyobe

ответ

28

Я думаю, что было бы лучше, если вы это проверить учебное пособие:

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

особенно в этом разделе:

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

Я думаю, ваша ошибка в этом случае может быть либо, что вы не объявим его как слот или вы не сделали его возможности ссылаться. Оба варианта описаны в учебнике Qt.

Кроме того, вам необходимо использовать QVariant для обмена данными между C++ и QML. Вы также можете регистрировать типы, например. Виджеты и прочее, так что вы можете использовать их в QML как «родной» тип, например прямоугольник. В большинстве случаев это не рекомендуется, за исключением случаев, когда вам нужен какой-то определенный extern-класс или некоторые данные, которые вы не можете отобразить иначе в вашем QML-интерфейсе.

Причиной для QVariant является подход QML, основанный на сценарии. QVariant в основном содержит ваши данные и описание типа данных, поэтому QML знает, как правильно его обрабатывать. Вот почему вам нужно указать параметр в QML с помощью String, int и т. Д. Но исходный обмен данными с C++ остается QVariant

Раньше я использовал qmlRegisterType, но это очень неудобно для простых типов данных. Он скорее используется для более сложных данных, таких как пользовательские элементы Widgets, Canvas или Video, которые QML не поддерживает или не поддерживает QStandardItemModels. Это более удобный способ обмена данными между QML и C++ и не требует сигналов или слотов в первом экземпляре, потому что QStandardItemModel автоматически обновляет графический интерфейс. Для использования QStandardItemModel вам необходимо зарегистрировать Type с qmlRegisterType ... Модель может затем использоваться в представлениях на основе моделей, таких как ListView и т. Д.

Я приложил учебное пособие по этой теме, в котором описано, как использовать QListModel.

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

+0

Здесь я не использую подкласс QDeclarativeView. Как я указал в моем вопросе, все это работает, если я просто не укажу параметр. Должен ли я каким-то образом вводить QString в QML? – alex

+3

В этом случае попробуйте использовать QVariant. У меня была эта проблема несколько раз, когда QML не распознает другие типы данных, чем QVariant. – mmoment

+0

Эй, это решило проблему для меня! Все еще интересно, есть ли лучшее решение для этого. Вы когда-нибудь пытались использовать qmlRegisterType? – alex

25

Вы должны использовать Connections в этом случае (возможно, это единственный способ подключения).

  1. Поместите свой объект myObj в QML файл, `` setContextProperty

    qmlVectorForm->rootContext()->setContextProperty("YourObject", myOb); 
    
  2. Ваш сигнал

    finishedGatheringDataForItem(QString signalString) 
    
  3. В QML файл, добавьте Connectios любит ниже:

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

Где в QML-файле? – HorusKol

+0

Это может привести к задержкам в пользовательском интерфейсе при обмене данными на высокой частоте или в больших количествах. – mmoment

+2

Уверен, что SIGNAL SLOT не всегда имеет хорошую производительность. Поэтому для оптимизации вы должны обработать данные перед отправкой через SIGNAL. В некоторых случаях, если вы подключаетесь между двумя потоками, plz замечает, что не отправляйте SIGNAL с такой высокой скоростью, это приведет к зависанию пользовательского интерфейса. Вы должны сделать механизм для управления частотой отправки (возможно, использовать таймер или задержку) – Ken