2016-11-29 11 views
0

Я довольно новичок в Qt, поэтому я, вероятно, задаю довольно очевидный вопрос.Как создать пользовательский Quick QML-элемент с предопределенными состояниями

Я хотел бы создать супер-тип для всех моих пользовательских элементов GUI GUI, которые я хочу создать на C++. Этот супер-тип должен добавлять предопределенные состояния к элементу 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++, который наследуется от 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 и использовать их в нескольких элементов?
  • Как добавить сложные типы QML, такие как State Lists в классе C++, например StatedGuiElement?

ответ

1

Сначала вы создаете свой StatedGuiElement в качестве подкласса QQuickItem.

Тогда вы клеть StatedGuiElement.qml, импортировать пакет, содержащий элемент C++, сделать StatedGuiElement {} внутри, добавить свои состояния в QML к нему, то вы можете использовать StatedGuiElement в вашем проекте. Это будет тот, у которого в нем есть предопределенный материал QML.

Предполагается, что на самом деле у элемента есть вещи, которые необходимо реализовать на C++. Если нет, то не имеет смысла иметь C++-элемент вообще. Я не уверен, будут ли старые классы классов C++ работать с QML, возможно, нет, а использование состояний QML из C++ будет чем угодно, но вам удобнее, поэтому вам действительно нужно делать состояния в QML, помимо всего, что у вас есть на C++.

0

Можно определить свои свойства один раз и использовать их в нескольких элементах, если вы вложите элементы 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 
    ] 
} 
0

Если вам нужно свойство, являющееся списком элементов, i..e. states, являющийся списком объектов State, вы можете сделать это на C++, используя тип QQmlListProperty.

Для типа элемента списка необходим производный тип 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 { 
     } 
    ] 
}