如何创建具有预定义状态的自定义 Quick QML 项
How to create custom Quick QML Item with predefided states
我对 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)。我想状态可以通过使用 C++ class 中的枚举来定义,它继承自 QQuickItem
。但是,本教程并未展示如何创建更复杂的 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 状态类型并在多个元素中使用它们吗?
- 如何在 C++ class 中添加复杂的 QML 类型,例如状态列表,例如
StatedGuiElement
?
首先,您将 StatedGuiElement
创建为 QQuickItem
子类。
然后你创建一个StatedGuiElement.qml
,导入包含C++元素的包,在里面制作一个StatedGuiElement {}
,在QML中添加你的状态,然后你可以使用StatedGuiElement
在你的项目中。它将是其中预定义了 QML 额外内容的那个。
这假定该元素实际上具有您需要在 C++ 中实现的内容。如果不是,那么拥有 C++ 元素根本就没有意义。我不确定旧的 C++ 状态 类 是否可以与 QML 一起使用,可能不会,并且使用 C++ 中的 QML 状态一点也不方便,所以你真的应该在 QML 中做状态,在任何 C++ 东西之上你可能有。
如果您将 QML 元素嵌套在定义了所有状态的超类型 QML 元素中,则可以一次定义您的属性并在多个元素中使用它们。子元素可以访问父参数。
或者,您也可以简单地为每个 QML 设置上下文 属性,它应该在 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
]
}
如果您需要 属性 这是一个元素列表,即.. states
是 State
对象的列表,那么您可以使用 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 {
}
]
}
我对 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)。我想状态可以通过使用 C++ class 中的枚举来定义,它继承自 QQuickItem
。但是,本教程并未展示如何创建更复杂的 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 状态类型并在多个元素中使用它们吗?
- 如何在 C++ class 中添加复杂的 QML 类型,例如状态列表,例如
StatedGuiElement
?
首先,您将 StatedGuiElement
创建为 QQuickItem
子类。
然后你创建一个StatedGuiElement.qml
,导入包含C++元素的包,在里面制作一个StatedGuiElement {}
,在QML中添加你的状态,然后你可以使用StatedGuiElement
在你的项目中。它将是其中预定义了 QML 额外内容的那个。
这假定该元素实际上具有您需要在 C++ 中实现的内容。如果不是,那么拥有 C++ 元素根本就没有意义。我不确定旧的 C++ 状态 类 是否可以与 QML 一起使用,可能不会,并且使用 C++ 中的 QML 状态一点也不方便,所以你真的应该在 QML 中做状态,在任何 C++ 东西之上你可能有。
如果您将 QML 元素嵌套在定义了所有状态的超类型 QML 元素中,则可以一次定义您的属性并在多个元素中使用它们。子元素可以访问父参数。
或者,您也可以简单地为每个 QML 设置上下文 属性,它应该在 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
]
}
如果您需要 属性 这是一个元素列表,即.. states
是 State
对象的列表,那么您可以使用 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 {
}
]
}