本文介绍了在QML信号中暴露一个枚举的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在qml中使用正确的枚举类型接收到信号 mySignal 的问题。我想我已经做了一切正确的事情:




  • 枚举是一个单独的类,派生自 QObject

  • 枚举注册为 Q_ENUMS

  • 包含枚举的类是注册到 qmlRegisterUncreatableType

  • 信号定义的类也是一个 QObject 并注册 qmlRegisterUncreatableType



值得注意的事实:




  • 运行程序会将打印的日志打印在从main.qml中调用的插槽中,但qml中未收到发出的信号。

  • 取消注释在textclass.cpp中的发布允许在QML中接收信号,但与枚举值的比较不会被触发,因为它应该是。



为什么我不接受QML中的枚举的信号,为什么我不能与QML中的枚举值进行比较呢?



我有看到关于Qt缺陷页面上的枚举的缺陷报告,所以我明白支持Qt中的枚举不是坚实的。但是,我真的希望能够将QAM中的值与枚举的信号进行比较,而不是在我接收到的信号中。由于某些原因,输入到mySlot的值很乐意接受在信号处理程序中无法识别的相同枚举值。



使用Ubuntu上的Qt 5.4。



error.h:

  #ifndef ERROR_H 
#define ERROR_H

#include< QObject>
#include< QtQml>

class错误:public QObject
{
Q_OBJECT
Q_ENUMS(Type)

public:
显示错误(QObject * parent = 0){Q_UNUSED(parent)};
〜Error(){};

static void RegisterTypes(void)
{
qmlRegisterUncreatableType< Error>(Types,1,0,Error,Error class uncreatable);
}

枚举类型{
OK = 0,
FILE_ERROR
};
};

#endif // ERROR_H

testclass.h:

  #ifndef TESTCLASS_H 
#define TESTCLASS_H

#include< QObject>
#include< QVariant>
#include< QDebug>

#includeerror.h

class TestClass:public QObject
{
Q_OBJECT

public:
显式TestClass(QObject * parent = 0);
〜TestClass();

static void RegisterTypes(void)
{
qmlRegisterUncreatableType&TestClass>(TestClass,1,0,TestClass,TestClass uncreatable);
};

信号:
void mySignal(Error :: Type arg);
void mySignal(int arg);

public slots:
void mySlot(QVariant arg);
};

#endif // TESTCLASS_H

testclass.cpp:

  #includetestclass.h

TestClass :: TestClass(QObject * parent):QObject(parent)
{

}

TestClass ::〜TestClass()
{

}

void TestClass :: mySlot(QVariant arg)
{
qDebug()<< mySlot为< arg.toInt();
int retval = static_cast< int>(arg.toInt());
发出mySignal(static_cast< Error :: Type>(retval));
//发出mySignal(retval);
}

main.cpp:

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

#includeerror.h
#includetestclass.h

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

错误:: RegisterTypes();
TestClass :: RegisterTypes();

TestClass * tPtr = new TestClass();

engine.rootContext() - > setContextProperty(_ t,tPtr);

engine.load(QUrl(QStringLiteral(qrc:/main.qml)));
return app.exec();
}

main.qml:

  import QtQuick 2.4 
import QtQuick.Window 2.2
import类型1.0
import TestClass 1.0

窗口{
visible:true
width:button.width + 20
height:button.height + 20
Rectangle {
id:button
width:theText.width + $ 20
b $ b target:_t

onMySignal:{
console.log(onMySignal:,arg)
if(arg == Error.OK){
console.log(OK)
}
else if(arg == Error.FILE_ERROR){
console.log(FILE_ERROR)
}
else {
console.log(UNDEFINED)
}
}
}

文本{
id:theText
anchors.centerIn:parent
文本:按我!
font.pixelSize:30
}

MouseArea {
anchors.fill:parent
onClicked:_t.mySlot(Error.FILE_ERROR)
onPressed:button.scale = 0.9
onReleased:button.scale = 1.0
}
}
}


解决方案

这个问题是双重的。



第一个问题:




  • 错误::类型未在Meta类型系统中注册,
    以下行需要添加错误类声明:



    Q_DECLARE_METATYPE(Error :: Type)




第二个问题:




  • 是否为错误
    类别选择了错误当我注册了这与内置类型发生冲突。
    注册需要更改为:



    qmlRegisterUncreatableType(Types,1,0,ErrorClass,Error class uncreatable); / p>

    (QML代码也需要更新以反映这个
    课程。)




改变这两件事情解决了这个问题,现在可以在QML代码中正确收到信号。


I have problems receiving the signal mySignal with the correct enum type in qml. I think I have done everything right:

  • The enum is in a separate class, derived from QObject
  • The enum is registered with Q_ENUMS
  • The class containing enum is registered with qmlRegisterUncreatableType
  • The class the signal is defined in, is also a QObject and also registered with qmlRegisterUncreatableType

Notable facts:

  • Running the program prints the log in the slot called from main.qml, but the signal emitted is not received in qml.
  • Uncommenting the emit in textclass.cpp allows the signal to be received in QML, but the comparison with the enum value is not triggered as it should be.

Why do I not recieve the signal with the enum up in QML and why cannot I compare to the enum value in QML even though is is exposed with Q_ENUMS?

I have seen a defect report regarding enums on the Qt defect page, so I understand that the support for enums in Qt is not rock solid. However, I really would like to be able to compare values to enums up in QML for signals received and at the moment I am not. For some reason the value entered into mySlot gladly accepts the same enum value that is not recognized in the signal handler. Code listings below.

Qt 5.4 on Ubuntu was used.

error.h:

#ifndef ERROR_H
#define ERROR_H

#include <QObject>
#include <QtQml>

class Error : public QObject
{
    Q_OBJECT
    Q_ENUMS(Type)

public:
    explicit Error(QObject *parent = 0) {Q_UNUSED(parent)};
    ~Error() {};

    static void RegisterTypes(void)
    {
        qmlRegisterUncreatableType<Error>("Types", 1, 0, "Error", "Error class uncreatable");
    }

    enum Type {
        OK = 0,
        FILE_ERROR
    };
};

#endif // ERROR_H

testclass.h:

#ifndef TESTCLASS_H
#define TESTCLASS_H

#include <QObject>
#include <QVariant>
#include <QDebug>

#include "error.h"

class TestClass : public QObject
{
    Q_OBJECT

public:
    explicit TestClass(QObject *parent = 0);
    ~TestClass();

    static void RegisterTypes(void)
    {
        qmlRegisterUncreatableType<TestClass>("TestClass", 1, 0, "TestClass", "TestClass uncreatable");
    };

signals:
    void mySignal(Error::Type arg);
    void mySignal(int arg);

public slots:
    void mySlot(QVariant arg);
};

#endif // TESTCLASS_H

testclass.cpp:

#include "testclass.h"

TestClass::TestClass(QObject *parent) : QObject(parent)
{

}

TestClass::~TestClass()
{

}

void TestClass::mySlot(QVariant arg)
{
    qDebug() << "mySlot called" << arg.toInt();
    int retval = static_cast<int>(arg.toInt());
    emit mySignal(static_cast<Error::Type>(retval));
    //   emit mySignal(retval);
}

main.cpp:

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

#include "error.h"
#include "testclass.h"

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

    Error::RegisterTypes();
    TestClass::RegisterTypes();

    TestClass* tPtr = new TestClass();

    engine.rootContext()->setContextProperty("_t", tPtr);

    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    return app.exec();
}

main.qml:

import QtQuick 2.4
import QtQuick.Window 2.2
import Types 1.0
import TestClass 1.0

Window {
    visible: true
    width: button.width + 20
    height: button.height + 20
    Rectangle {
        id: button
        width: theText.width + 20
        height: theText.height + 20
        anchors.margins: 10
        anchors.centerIn: parent
        border.width: 3

        Connections {
            target: _t

            onMySignal: {
                console.log("onMySignal: ", arg)
                if (arg == Error.OK) {
                    console.log("OK")
                }
                else if (arg == Error.FILE_ERROR) {
                    console.log("FILE_ERROR")
                }
                else {
                    console.log("UNDEFINED")
                }
            }
        }

        Text {
            id: theText
            anchors.centerIn: parent
            text: "press me!"
            font.pixelSize: 30
        }

        MouseArea {
            anchors.fill: parent
            onClicked: _t.mySlot(Error.FILE_ERROR)
            onPressed: button.scale = 0.9
            onReleased: button.scale = 1.0
        }
    }
}
解决方案

The problems to this was two-fold.

First problem:

  • Error::Type was not registered within the Meta type system, thefollowing line needs to be added after the Error class declaration:

    Q_DECLARE_METATYPE(Error::Type)

Second problem:

  • Was that I had selected the name 'Error' for the Errorclass when I registered it. This clashed with a built in type. Theregistration needs to be changed to this:

    qmlRegisterUncreatableType("Types", 1, 0, "ErrorClass", "Error class uncreatable");

    (The QML code would also need to be updated to reflect this ofcourse.)

Changing these two things solved the problem, and the signal can now correctly be received in QML-code.

这篇关于在QML信号中暴露一个枚举的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-24 01:24