1

Qt 5.5で動作し、 Qt 5.2では動作しないコードがあります。問題はこの列挙型にあります:

#include <QtCore/QMetaType>
enum Area
{
    Area_A,
    Area_B,
    Area_C
};

Q_DECLARE_METATYPE(Area)

次に、このエリアプロパティを公開するオブジェクトがあります。

class MyClass : public QObject
{
    Q_OBJECT
    Q_PROPERTY(Area area READ area WRITE setArea NOTIFY areaChanged)
public:    
    explicit MyClass(QObject *parent = 0)
        : QObject(parent), m_area(Area_A){}

    Area area() const { return m_area; }    
    void setArea(Area area) {
        m_area = area;
        emit areaChanged(area);
    }

signals:
    void areaChanged(Area area);    
private:
    Area m_area;
};

そしてmain.cpp:

#include <QtGui/QGuiApplication>
#include <QtQml/QQmlApplicationEngine>
#include <QtQml/QQmlContext>
#include <QtQml/QtQml>
#include "MyClass.h"

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

    qmlRegisterType<MyClass>("GLib", 1, 0, "MyClass");

    MyClass controller;
    QQmlApplicationEngine engine;
    engine.rootContext()->setContextProperty("controller", &controller);
    engine.load("./main.qml");

    controller.setArea(Area_B);
    return app.exec();
}

コンパイルされ、すべて問題ありません。しかし、qmlで area プロパティを使用しようとしたとき:

import QtQuick 2.0
import QtQuick.Window 2.0
import GLib 1.0

Window {
    visible: true
    id: root

    property int area: controller.area 

    Text {
        id: name
        text: "Test"
        x: area * 30
        y: area * 30
    }
}

Qt 5.2 を使用している場合 (Linux、x64)、実行時エラーが発生します。

QMetaProperty::read: プロパティ 'MyClass::area' の未登録のデータ型 'Area' を処理できませんQMetaProperty::read: プロパティ 'MyClass::area' の未登録のデータ型 'Area' を処理できません

Qtのバグですか?Class スコープ外で宣言されている Enum を使用できないのはなぜですか?

4

2 に答える 2

5

Qt 5.5 では Q_ENUM マクロが導入され、Q_DECLARE_METATYPE を使用する必要がなくなりました。詳細については、https ://woboq.com/blog/q_enum.html をご覧ください。

于 2016-11-18T13:31:58.143 に答える
2

コードが Qt 5.5 で機能する理由はわかりませんが、Qt 5.2 で機能しない理由はわかっています。

Q_DECLARE_METATYPE(...)型を静的(コンパイル済み) コンテキストでのみ使用できるようにします。たとえば、 でタイプを使用する場合QVariant::fromValue(...)。ここで、関数に渡す型はコンパイル時に処理できます。これにQ_DECLARE_METATYPEは十分です。

ただし、QML ドキュメントなど、純粋なランタイムコンテキストで型を使用する場合、Qt ランタイムは で宣言された型を認識しませんQ_DECLARE_METATYPE。このためには、関数呼び出し (実行時に評価される) を行う必要があり、qRegisterMetatypeこれがそのためのツールです。

qRegisterMetaType<Area>("Area");

その行を必要としないQt 5.5の私の推測はqmlRegisterType、プロパティでのメタタイプの使用を検出し、上記の関数を自動的に呼び出す可能性があるということです。

于 2015-12-03T16:43:20.570 に答える