2016-07-26 67 views
1

我有一个在QObject中定义的枚举,其中包含几个值,并且我将Qum注册为QFlags,如Qt文档指定的那样。我将枚举和QObject注册为元模型,我可以在QML中很好地访问它。如何从QML调用带QFlags参数的插槽

问题是,一旦我定义了一个QFlags作为参数的C++ QObject插槽,它在调用时不会收到错误,而是传递枚举中的第一个定义的值(即它的值是数字0的枚举项的值)。

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

我开始在QtCreator中创建一个“Qt Quick Application”。然后添加一个名为“QMLThing”的类。下面是每个文件的源代码:

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

这似乎很像一个bug,但也许我只是失去了一些东西。

回答

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

如前所述here,你并不需要使用Q_ENUM()

注:Q_FLAG宏负责注册个人国旗 val与元对象系统一起使用,所以除了这个宏之外,不需要使用Q_ENUM() 。

+0

我可以看到从[this](http://doc.qt.io/qt-5/qtqml-cppintegration-data.html#enumeration-types)页面没有提及'Q_FLAG',所以我[添加了一个](https://codereview.qt-project.org/#/c/166046/)。 – Mitch

0

不完全知道是怎么回事,但是首先:

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

您需要删除最后昏迷。 我还建议设置至少第一个枚举,到一个特定的值,通常为0,所以你知道你要去哪里,但不需要设置以下枚举项,因为它们将从最后一个集自动递增。

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

+0

您对最后一个逗号的评论是不正确的,它是绝对允许的。我更新了问题,以便枚举值已分配值。不,QMLThing.VALC是正确的语法,如果您使用QML中的console.log(QMLThing.VALC),则会打印出2,这是正确的值。这个问题直接关系到将QML中的数字传递给带有QFlags参数的插槽。 – YoklJO

+0

我不知道你在使用C++ 11,那么在那种情况下,是的,最后一个项目之后的昏迷是失败的。 关于第二点,我不完全确定,现在我:)。 – Nox

+0

所有的好,对不起,我没有指定。 – YoklJO