如何使用QML中的QFlags参数调用slot

时间:2016-07-26 01:50:22

标签: qt qml

我在一个带有几个值的QObject中定义了一个枚举,我正在将枚举注册为QFlags,如Qt文档所指定的那样。我已经将enum和QObject注册为我可以从QML中访问的元类型。

问题是,一旦我定义了一个以QFlags为参数的C ++ QObject槽,它在调用时就不会出错,而是传入枚举中的第一个定义值(即。它的值是带有数字0的枚举条目的值。

很难描述,所以我创建了一个小的工作示例(使用C ++ 11 / Qt 5.7)。当您运行它并单击打开的窗口中的任意位置时,即使在main.qml中我打电话QFlags<QMLThing::MyEnum>(VALA),也会打印出thing.doThing(QMLThing.VALC)

我开始创建一个&#34; Qt Quick Application&#34;在QtCreator。然后添加了一个名为&#34; QMLThing&#34;的类。以下是每个文件的源代码:

QMLThing.hpp

#ifndef QMLTHING_HPP
#define QMLTHING_HPP

#include <QObject>

class QMLThing : public QObject
{
    Q_OBJECT

public:
    enum MyEnum {
        VALA = 0,
        VALB = 1,
        VALC = 2,
        VALD = 4,
    };

    Q_ENUM(MyEnum)
    Q_DECLARE_FLAGS(MyEnums, MyEnum)

public:
    explicit QMLThing(QObject *parent = 0);

public slots:
    void doThing(QMLThing::MyEnums val);
};

Q_DECLARE_OPERATORS_FOR_FLAGS(QMLThing::MyEnums)
Q_DECLARE_METATYPE(QMLThing::MyEnums)

#endif // QMLTHING_HPP

QMLThing.cpp

#include "QMLThing.hpp"

#include <QDebug>

QMLThing::QMLThing(QObject *parent) : QObject(parent)
{}

void QMLThing::doThing(QMLThing::MyEnums val)
{
    qDebug() << val;
}

的main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QtQml>

#include "QMLThing.hpp"

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

    qmlRegisterType<QMLThing>("stuff", 1, 0, "QMLThing");

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

    return app.exec();
}

main.qml

import QtQuick 2.7
import QtQuick.Window 2.2

import stuff 1.0

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    MouseArea {
        anchors.fill: parent
        onClicked: {
            thing.doThing(QMLThing.VALC)
        }
    }

    Text {
        text: qsTr("Click here and look in the terminal")
        anchors.centerIn: parent
    }

    QMLThing {
        id: thing
    }
}

这似乎很像一个错误,但也许我只是遗漏了一些东西。

2 个答案:

答案 0 :(得分:1)

你错过了Q_FLAG(MyEnums)

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QtQml>

#include <QObject>

class QMLThing : public QObject
{
    Q_OBJECT

public:
    enum MyEnum {
        VALA = 0,
        VALB = 1,
        VALC = 2,
        VALD = 4,
        VALE = VALC | VALD
    };

    Q_DECLARE_FLAGS(MyEnums, MyEnum)
    Q_FLAG(MyEnums)

public:
    explicit QMLThing(QObject *parent = 0) :
        QObject(parent)
    {
    }

public slots:
    void doThing(QMLThing::MyEnums val)
    {
        qDebug() << val;
    }
};

Q_DECLARE_OPERATORS_FOR_FLAGS(QMLThing::MyEnums)
Q_DECLARE_METATYPE(QMLThing::MyEnums)

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

    qmlRegisterType<QMLThing>("stuff", 1, 0, "QMLThing");

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

    return app.exec();
}

#include "main.moc"

main.qml

import QtQuick 2.7
import QtQuick.Window 2.2

import stuff 1.0

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    MouseArea {
        anchors.fill: parent
        onClicked: {
            thing.doThing(QMLThing.VALC)
            thing.doThing(QMLThing.VALC | QMLThing.VALD)
        }
    }

    Text {
        text: qsTr("Click here and look in the terminal")
        anchors.centerIn: parent
    }

    QMLThing {
        id: thing
    }
}

如上所述[{3}},您无需使用Q_ENUM()

  

注意:Q_FLAG宏负责注册单个标志   使用元对象系统的值,因此不必使用   Q_ENUM()以及此宏。

答案 1 :(得分:0)

不确定到底发生了什么,但首先是:

public:
enum MyEnum {
    VALA,
    VALB,
    VALC,
    VALD,
};

你需要移除最后一个昏迷。 我还建议至少将第一个枚举设置为某个值,通常为0,这样您就知道自己要去哪里,但不需要设置以下枚举项,因为它们将从最后一个设置中自动递增。

最后,我不完全确定QMLThing.ValC,不应该是QMLThing::MyEnums::ValC吗?