简体   繁体   English

如何创建具有预定状态的自定义Quick QML项目

[英]How to create custom Quick QML Item with predefided states

I am quite new to Qt, so I am probably asking a pretty obvious question. 我对Qt很陌生,所以我可能会问一个很明显的问题。

I would like to create a super type for all of my custom QML GUI elements that I want to create in C++. 我想为要在C ++中创建的所有自定义QML GUI元素创建一个超类型。 This super type is supposed to add predefined states to a QML Item. 该超类型应该将预定义状态添加到QML项。 Something alike to this: 与此类似:

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

I know how to create a simple custom Item from this tutorial ( http://doc.qt.io/qt-5/qtqml-tutorials-extending-qml-example.html ). 我知道如何根据本教程( http://doc.qt.io/qt-5/qtqml-tutorials-extending-qml-example.html )创建一个简单的自定义项。 I guess the states could be defined by using an enum in the C++ class which inherits from QQuickItem . 我想状态可以通过使用从QQuickItem继承的C ++类中的枚举来定义。 However, this tutorial does not show how to create more complex Qt Quick elements like the state list. 但是,本教程没有显示如何创建更复杂的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:
};

So the questions I am wondering about are as follows: 因此,我想知道的问题如下:

  • Is it even possible to predefine QML State types and use them in multiple elements? 甚至可以预定义QML状态类型并在多个元素中使用它们?
  • How do I add complex QML types like State Lists in a C++ class such as StatedGuiElement ? 如何在C ++类(如StatedGuiElement添加复杂的QML类型(如状态列表)?

First you create your StatedGuiElement as a QQuickItem subclass. 首先,将您的StatedGuiElement创建为QQuickItem子类。

Then you crate a StatedGuiElement.qml , import the package that contains the C++ element, make a StatedGuiElement {} inside, add your states in QML to it, then you can use StatedGuiElement in your project. 然后,创建一个StatedGuiElement.qml ,导入包含C ++元素的包,在其中创建一个StatedGuiElement {}在其中添加您在QML中的状态,然后可以在您的项目中使用StatedGuiElement It will be the one with the QML extra stuff predefined in it. 它将是其中预定义了QML额外内容的一个。

This assumes the element actually has things you need to implement in C++. 这假设元素实际上具有您需要在C ++中实现的东西。 If not then it would not make sense to have a C++ element at all. 如果没有,那么完全没有C ++元素是没有意义的。 I am not sure whether old C++ state classes will work with QML, probably not, and using the QML states from C++ will be anything but convenient, so you really should do the states in QML, on top of whatever C++ stuff you may have. 我不确定旧的C ++状态类是否可以与QML一起使用,并且使用C ++的QML状态将很不方便,因此您真的应该在QML中进行状态处理,而不管您可能拥有什么C ++东西。

It is possible to define your properties once and use them im multiple elements, if you nest your QML elements inside a super-type QML element where you have all your states defined. 如果将QML元素嵌套在定义了所有状态的超型QML元素内,则可以一次定义属性并在多个元素中使用它们。 Child elements can access the parent parameters. 子元素可以访问父参数。

Alternatively, you can also just simply set the context property for each QML which should use the data like this in C++: 另外,您也可以只为每个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();

In the QML-side, you can also declare a custom property which holds the names of the states. 在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
    ]
}

If you need a property that is a list of elements, i..e. 如果您需要一个包含元素列表的属性,即 states being a list of State objects, then you can do this in C++ using the QQmlListProperty type. statesState对象的列表,那么您可以使用QQmlListProperty类型在C ++中执行此QQmlListProperty

You need a QObject derived type for the list element type. 列表元素类型需要QObject派生类型。

Example

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;
};

Register both with qmlRegisterType() qmlRegisterType()都注册

In QML 在QML中

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM