How to use a custom Qt type with a QML signal?

浪尽此生 提交于 2019-12-24 02:18:13

问题


I've created a custom type inside my Qt 5.2 qml application

class Setting : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QString key READ key WRITE setKey)
    Q_PROPERTY(QVariant value READ value WRITE setValue)

public:
    Setting(QObject * parent = 0);

    QString key() const;
    void setKey(QString const & key);

    QVariant value() const;
    void setValue(QVariant const & value);

private:
    QString m_key;
    QVariant m_value;
};

and registered it in my main function:

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    qmlRegisterType<Setting>("Setting", 1,0, "Setting");

    // ...
}

In my application I would like to have a button that has a signal with my custom type as a parameter:

import Setting 1.0

Button
{
    signal settingChanged(string, Setting)

    // ...
}

Every time I hit the button the signal should be emitted.

If I try to connect my qml signal with my C++ slot

QObject::connect(myButton, SIGNAL(settingChanged(QString, Setting)), this, SLOT(settingChanged(QString, Setting)));

Qt says

QObject::connect: No such signal Button_QMLTYPE_41_QML_45::settingChanged(QString, Setting) in ...

If I remove my custom type from the signal definition

Button
{
    signal settingChanged(string)

    // ...
}

and modify the connect call

QObject::connect(myButton, SIGNAL(settingChanged(QString)), this, SLOT(settingChanged(QString)));

the connect call worked.

I could use my custom qml type Setting inside the qml part of my application. But what I do wrong if I would like to use it with my signal settingChanged?

Thanks!


回答1:


After I've readed the Qt documentation very carefully, I've found the answer here

http://qt-project.org/doc/qt-5/qtqml-cppintegration-interactqmlfromcpp.html#connecting-to-qml-signals

The documentation says

When a QML object type is used as a signal parameter, the parameter should use var as the type, and the value should be received in C++ using the QVariant type.

So, the signal definition inside the qml description of Setting has to be replaced with var.

import Setting 1.0

Button
{
    signal settingChanged(string, var)

    // ...
}

To connect the qml signal with the C++ slot, the code has to be

Object::connect(myButton, SIGNAL(settingChanged(QString, QVariant)), this, SLOT(settingChanged(QString, QVariant)));

At this point the connection worked!

To make the whole thing running, the QVariant has to be casted to the right type inside the slot. In my case to a Setting type.

void Foo::settingChanged(QString name, QVariant const & var)
{
    Setting * setting = qobject_cast<Setting*>(var.value<QObject*>());

    // ...
}


来源:https://stackoverflow.com/questions/25650594/how-to-use-a-custom-qt-type-with-a-qml-signal

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!