How can we declare enumerations in QML, without any JavaScript?

拟墨画扇 提交于 2020-01-29 02:53:12

问题


Does QML allow us to define enums? If so, how we can declare enumerations in QML?

I want to declare an enum in QML like the following C++ enum. If possible, I want to do this without any JavaScript.

enum Color { RED, GREEN, BLUE };
Color r = RED;
switch(r)
{
    case RED  : std::cout << "red\n";   break;
    case GREEN: std::cout << "green\n"; break;
    case BLUE : std::cout << "blue\n";  break;
}

What should I do?


回答1:


You can use a pure Qml singleton, so you don't need any C++ or javascript.

colors/MyColors.qml:

pragma Singleton
import QtQuick 2.5
QtObject {
    id: singleton

    property int red: 0
    property int green: 1
    property int blue: 2
}

colors/qmldir:

singleton MyColors 1.0 MyColors.qml

Your qml file:

import "colors" 1.0
// MyColors.red
// MyColors.green
// MyColors.blue



回答2:


Since Qt 5.10, enumerations are directly supported in QML. See Qt documentation which contains sample code.

You can define one with the enum keyword. The type and its values must start with a capital letter but otherwise follow rules for naming a variable (e.g. can include digits and underscore).

To use the enum, you have to explicitly include the full scope including the component ComponentName.EnumType.EnumValue. This is true even when using it within the component itself.

e.g.

// MyComponent.qml
Rectangle {
    id: root

    // Define Shape enum
    enum Shape {
        None,
        Round,
        Pointy,
        Bobbly,
        Elusive
    }

    // Note: property using enum is of type int
    property int selectedShape: MyComponent.Shape.None

    visible: selectedShape !== MyComponent.Shape.None
    color: selectedShape === MyComponent.Shape.Pointy? "red": "green"
}

Note that enumerated values are treated as int and you can assign and compare them as such.

Although not documented (and therefore potentially subject to change), by default the first one has value 0, the second 1, etc.. However you can assign a non-negative integer value. You can even assign two enum values to the same integer value though that is probably not a good idea. You cannot assign an expression that evaluates to an integer.

e.g.

enum Shape {
    None = 5, // valid
    Round, // automatically assigned 6
    Pointy = -1, // not valid
    Bobbly = Round // not valid
    Elusive = (8-7) // not valid
}

Thanks to Michael Brasser's blog comment about assigning simple values.




回答3:


First, use enum class instead of enum for better type safety

enum class Color { RED, GREEN, BLUE };
Color r = Color::RED;

Then register it for Qt using Q_ENUMS (use Q_ENUM for Qt 5.5+):

mycolors.h

#pragma once

#include <QObject>

class MyColors : public QObject
{
    Q_OBJECT

public:
    enum class Color {
        RED,
        GREEN,
        BLUE
    };
    Q_ENUMS(Color)

    static void init();
};

To make the enum available in QML, register it (in a mycolors.cpp file):

void MyColors::init()
{
    qRegisterMetaType<MyColors::Color>("MyColors::Color");
    qmlRegisterType<MyColors>("MyQmlModule", 1, 0, "MyColors");
}

and call Colors::init() in your main().

In QML you now have

import MyQmlModule 1.0

// MyColors.RED
// MyColors.GREEN
// MyColors.BLUE



回答4:


Since Qt 5.10, you can now also declare Enum types directly in QML: https://v-play.net/updates/v-play-2-15-0-qt-5-10-qt-creator-4-5-support-firebase-data-structures-and-queries#qt-5-10-qml-enum-instanceof

// MyText.qml
import QtQuick 2.0

Text {
  enum MyEnum {
    Normal,
    Heading
  }

  property int textType: MyText.MyEnum.Normal

  font.bold: textType == MyText.MyEnum.Heading
  font.pixelSize: textType == MyText.MyEnum.Heading ? 24 : 12
}

// Main.qml
import VPlayApps 1.0

App {
  MyText {
    textType: MyText.MyEnum.Heading
    text: "I'm a headline."
  }
}


来源:https://stackoverflow.com/questions/34461378/how-can-we-declare-enumerations-in-qml-without-any-javascript

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!