【问题标题】:Q_ENUM undefined value in qml when enum is defined in base class在基类中定义枚举时,qml 中的 Q_ENUM 未定义值
【发布时间】:2018-07-24 08:30:43
【问题描述】:

Q_ENUM 在用于继承的枚举时无法按 (I) 预期工作。

例如,有基本结构 A(遗留类)和继承自 A 和 QObjectBA 有一个枚举,B 有这个枚举的Q_ENUM

b.h

#pragma once

#include <QObject>
#include <QDebug>

struct A
{
    A() = default;
    virtual ~A() = default;

    enum E_FOO{
        FOO = 1000,
        FOOO,
        FOOOO
    };
};

class B
        : public QObject
        , public A
{
    Q_OBJECT
    Q_ENUMS(E_FOO)  // OPTION 1 doesn't work

public:
    B() {
        qDebug() << "enums from A" << B::FOO << B::FOOO<<B::FOOOO;
        qDebug() << "enums from B" << B::BAR  << B::BARR  << B::BARRR;
    }
//    Q_ENUM(E_FOO)  // OPTION 2 doesn't work

//    using E_FOO_FORWARDED = A::E_FOO;  // OPTION 3 doesn't work
//    Q_ENUM(E_FOO_FORWARDED)


   // additional enum (for testing a "normal" case)
    enum E_BAR {
        BAR = 1111,
        BARR,
        BARRR
    };
    Q_ENUM(E_BAR)
};

这里有一些要加载的 qml 文件,它只在创建时打印枚举值。

MainWindow.qml

import QtQuick 2.7
import QtQuick.Layouts  1.0
import QtQuick.Controls 2.3

import mmm 1.0


ApplicationWindow { 
    Component.onCompleted:{
        console.log("checking if values are correct:")
        console.log("B.FOO should be = 1000", B.FOO)
        console.log("B.BAR should be = 1111", B.BAR)
    }
}

这是一个运行它的主文件:

main.cpp

#include <QGuiApplication>

#include <QtQml/QQmlApplicationEngine>
#include <QtQuick/QQuickWindow>

#include <QObject>
#include <QDebug>
#include "b.h"

int main(int argc, char *argv[])
{
    qmlRegisterUncreatableType<B>("mmm",1, 0, "B", "err");

    // (check qDebug capabilities that are coded inside the 
    B b; consturctor)

    // checking enum inside qml
    QGuiApplication a(argc, argv);
    QQmlApplicationEngine eng(QUrl("qrc:/qml/MainWindow.qml"));
    QQuickWindow* window = qobject_cast<QQuickWindow*>(eng.rootObjects().first());
    window->show();

    return a.exec();
}

结果是

enums from A 1000 1001 1002
enums from B B::E_BAR(BAR) B::E_BAR(BARR) B::E_BAR(BARRR)
qml: checking if values are correct:
qml: B.FOO should be = 1000 undefined
qml: B.BAR should be = 1111 1111

所以:

  • Q_ENUM 的新功能(qDebug 中的名称打印)不起作用
  • 旧的Q_ENUMS 也不行
  • qml 中的值未定义
  • 正常枚举(不是来自基类)按预期工作

我尝试制作具有相同结果的别名类型 (using E_FOO_FORWARDED = A::E_FOO)。这个问题有解决办法吗?


项目的其他文件

inherited_enum.pro

QT += gui core qml quick

TEMPLATE = app
CONFIG += c++14 console qml
SOURCES += main.cpp 
RESOURCES += qml.qrc

qml.qrc

<RCC>
    <qresource prefix="/qml">
        <file>MainWindow.qml</file>
    </qresource>
</RCC>

【问题讨论】:

  • 我想这个问题可以通过从 QObject 派生基类并在那里定义枚举来解决。
  • 是的,但我希望基类尽可能精简。我最终宣布“转发”枚举,如enum E_FOO_FORWARDED{F_FOO = A::FOO, ...}

标签: c++ qt enums qml


【解决方案1】:

Q_ENUM 这样的Qt 扩展由宏和moc 处理,它们只处理所需的C++ 子集。它并不真正处理继承,只适用于当前的类定义。

因此,您必须将 Q_ENUMS 放入底层 enum 的定义类中。

【讨论】:

  • 我觉得应该有一些错误信息或者至少是警告。 B::FOO 在课堂上是可见的,所以我想问题出在 moc 上。我试图通过别名类型来克服这个问题,但它可能也不被支持(正如你所提到的)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-03-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-10
相关资源
最近更新 更多