【问题标题】:How can we declare enumerations in QML, without any JavaScript?我们如何在没有任何 JavaScript 的情况下在 QML 中声明枚举?
【发布时间】:2016-03-31 09:43:56
【问题描述】:

QML 是否允许我们定义枚举?如果是这样,我们如何在 QML 中声明枚举?

我想在 QML 中声明一个枚举,如下面的 C++ 枚举。如果可能的话,我想在没有任何 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;
}

我该怎么办?

【问题讨论】:

    标签: qt enums qml


    【解决方案1】:

    自 Qt 5.10 起,QML 直接支持枚举。 See Qt documentation which contains sample code.

    您可以使用enum 关键字定义一个。 type 及其 values 必须以大写字母开头,否则遵循命名变量的规则(例如,可以包含数字和下划线)。

    要使用枚举,您必须明确包含包括组件ComponentName.EnumType.EnumValue 在内的完整范围。即使在组件本身中使用它也是如此。

    例如

    // 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"
    }
    

    请注意,枚举值被视为int,您可以这样分配和比较它们。

    虽然没有记录(因此可能会发生变化),默认情况下第一个具有值0,第二个具有值1,等等。但是您可以分配一个非负整数值。您甚至可以将两个枚举值分配给同一个整数值,尽管这可能不是一个好主意。您不能分配计算结果为整数的表达式。

    例如

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

    感谢Michael Brasser's blog comment about assigning simple values

    【讨论】:

    • “组件名称”从何而来?是QML文件名的前缀还是?
    • 我的代码示例中ComponentName.EnumType.EnumValue 的示例是MyComponent.Shape.PointyComponentName 是您正在创建的组件的文件名。
    • 如何使它适用于 C++ 调用的主 qml 文件,例如main.qml?
    • 您在组件中创建枚举,如上所述,然后通过其完整范围在main.qml 中使用它,如上所述。
    【解决方案2】:

    从 Qt 5.10 开始,您现在还可以直接在 QML 中声明 Enum 类型: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."
      }
    }
    

    【讨论】:

      【解决方案3】:

      您可以使用纯 Qml 单例,因此您不需要任何 C++ 或 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
      }
      

      颜色/qmldir:

      singleton MyColors 1.0 MyColors.qml
      

      你的 qml 文件:

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

      【讨论】:

      • 附注一下,属性不能以大写字母开头。
      • 至少将 MyColors.qml 中的属性设置为只读。
      【解决方案4】:

      首先,使用enum class 而不是enum 以获得更好的类型安全性

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

      然后使用Q_ENUMS 为Qt 注册它(使用Q_ENUM 用于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();
      };
      

      要使枚举在 QML 中可用,请将其注册(在 mycolors.cpp 文件中):

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

      并在您的main() 中调用Colors::init()

      在 QML 中,您现在拥有

      import MyQmlModule 1.0
      
      // MyColors.RED
      // MyColors.GREEN
      // MyColors.BLUE
      

      【讨论】:

        猜你喜欢
        • 2020-09-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-12-24
        • 2023-02-24
        • 2014-08-22
        • 2014-10-23
        • 1970-01-01
        相关资源
        最近更新 更多