2016-07-26 47 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