如何使用带有QML信号的自定义Qt类型?

时间:2014-09-03 17:46:41

标签: c++ qt qml qt5

我在Qt 5.2 qml应用程序中创建了一个自定义类型

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;
};

并将其注册在我的主要功能中:

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

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

    // ...
}

在我的应用程序中,我希望有一个按钮,其中包含一个以我的自定义类型作为参数的信号:

import Setting 1.0

Button
{
    signal settingChanged(string, Setting)

    // ...
}

每按一下按钮,就会发出信号。

如果我尝试将qml信号与我的C ++插槽连接

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

Qt说

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

如果我从信号定义中删除自定义类型

Button
{
    signal settingChanged(string)

    // ...
}

并修改连接呼叫

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

连接通话有效。

我可以在应用程序的qml部分中使用我的自定义qml类型 Setting 。但是,如果我想将它用于我的信号 settingChanged ,我做错了什么?

谢谢!

1 个答案:

答案 0 :(得分:2)

在我仔细阅读了Qt文档之后,我在这里找到了答案

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

文档说

  

当QML对象类型用作信号参数时,参数   应该使用var作为类型,并且应该在C ++中接收值   使用QVariant类型。

因此,Setting的qml描述中的信号定义必须替换为var

import Setting 1.0

Button
{
    signal settingChanged(string, var)

    // ...
}

要将qml信号与C ++插槽连接,代码必须是

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

此时连接工作正常!

要使整个事情运行,QVariant必须在插槽内转换为正确的类型。在我的情况下为Setting类型。

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

    // ...
}