【问题标题】:How to create custom Quick QML Item with predefided states如何创建具有预定义状态的自定义 Quick QML 项目
【发布时间】:2016-11-29 20:56:23
【问题描述】:

我对 Qt 很陌生,所以我可能会问一个非常明显的问题。

我想为我想用 C++ 创建的所有自定义 QML GUI 元素创建一个超类型。 这个超类型应该为 QML 项目添加预定义的状态。类似的东西:

    import StatedGuiElement 1.0
    import QtQuick 2.0

    Item {
        width: 300; height: 200

        StatedGuiElement {
            id: aStatedGuiElement
            anchors.centerIn: parent
            width: 100; height: 100
            //some visible Custom Gui Elements
    states:[
        State {
            name: "A_STATE"

        },
        State {
            name: "ANOTHER_STATE"
        }]
}

我知道如何通过本教程 (http://doc.qt.io/qt-5/qtqml-tutorials-extending-qml-example.html) 创建一个简单的自定义项目。我想可以通过使用继承自QQuickItem 的 C++ 类中的枚举来定义状态。但是,本教程并未展示如何创建更复杂的 Qt Quick 元素,例如状态列表。

class StatedGuiElement : public QQuickItem
{
    Q_OBJECT
    Q_PROPERTY(QString name READ name WRITE setName)
    //pass States via Q_PROPERTY?
public:
    //define Enum for fixed States here?
    //ENUM STATES {A_STATE, ANOTHER_STATE}
    StatedGuiElement( QQuickItem *parent = 0);

    QString name() const;
    void setName(const QString &name);


private:
    QString m_name;
    //Some List of States?


signals:

public slots:
};

所以我想知道的问题如下:

  • 甚至可以预定义 QML 状态类型并在多个元素中使用它们吗?
  • 如何在 StatedGuiElement 等 C++ 类中添加复杂的 QML 类型(如状态列表)?

【问题讨论】:

    标签: c++ qt qml qtquick2 qquickitem


    【解决方案1】:

    首先,您将StatedGuiElement 创建为QQuickItem 子类。

    然后你创建一个StatedGuiElement.qml,导入包含C++元素的包,在里面创建一个StatedGuiElement {},在QML中添加你的状态,然后你可以在你的项目中使用StatedGuiElement。它将是其中预定义了 QML 额外内容的那个。

    这假定元素实际上具有您需要在 C++ 中实现的东西。如果不是,那么拥有 C++ 元素就没有任何意义。我不确定旧的 C++ 状态类是否可以与 QML 一起使用,可能不会,并且使用 C++ 中的 QML 状态会很不方便,所以你真的应该在 QML 中做状态,除了你可能拥有的任何 C++ 东西。

    【讨论】:

      【解决方案2】:

      如果您将 QML 元素嵌套在定义了所有状态的超类型 QML 元素中,则可以定义一次属性并在多个元素中使用它们。子元素可以访问父参数。

      或者,您也可以简单地为每个 QML 设置 context 属性,它应该在 C++ 中使用这样的数据:

      QQuickView view;
      
      QStringList data;
      
      // fill the list with data via append()
      
      view.rootContext()->setContextProperty("dataList", QVariant::fromValue(data));
      
      // now the QML can freely use and access the list with the variable name "dataList"
      
      view.setSource(QUrl::fromLocalFile("MyItem.qml"));
      view.show();
      

      在 QML 方面,您还可以声明一个包含状态名称的自定义属性。

      Item {
          property variant state_list: ["element1", "element2", "element3"]
          // or if you defined a list in the C++ part as a context property
          // you can use this instead:
          // property variant state_list: dataList
      
          states: [
              State {
                  name: state_list[0]
              },
      
              State {
                  name: state_list[1]
              },
      
              // and so on
          ]
      }
      

      【讨论】:

        【解决方案3】:

        如果您需要一个元素列表的属性,即... statesState 对象的列表,那么您可以使用 QQmlListProperty 类型在 C++ 中执行此操作。

        列表元素类型需要QObject 派生类型。

        例子

        class Entry : public QObject
        {
            // the list entry element's API
        };
        
        class MyItem : public QQuickItem
        {
            Q_OBJECT
            Q_PROPERTY(QQmlListProperty<Entry> entries READ entries)
        
        
        public:
            QQmlListProperty<Entry> entries() const {
                return QQmlListProperty<Entry>(this, m_entries);
            }
        
        private:
            QList<Entry*> m_entries;
        };
        

        qmlRegisterType()注册两者

        在 QML 中

        MyItem {
            entries: [
                Entry {
                },  
                Entry {
                }
            ]
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2017-01-20
          • 1970-01-01
          • 1970-01-01
          • 2010-10-24
          • 2019-07-17
          • 1970-01-01
          • 2015-12-29
          相关资源
          最近更新 更多