Как использовать QStatemachine для влияния на ListView?

У меня есть этот Projekt, который использует QStatemachine для управления пользовательским интерфейсом, где я хочу добавить настраиваемый список. Предполагается, что пользовательским интерфейсом манипулируют только ключевые события. Насколько я понимаю, мне нужен ListView на стороне qml.

Делегат ListView реагирует только на ввод с помощью мыши или прямой ввод с клавиатуры. Но я использовал QStatemachine в C ++ для управления им, поскольку он обрабатывает все ключевые события для пользовательского интерфейса.
Когда я нажимаю клавишу со стрелкой вправо, я хочу, чтобы список был смещен влево.
(CurrentItem всегда в середине экрана.)

это начальное состояние lisfview

введите описание изображения здесь

Так что мой ListView выглядит так в данный момент.

Component {
id:myDelegation
Item {
x: 50
width: 80
height: 60
Rectangle {
width: 60
height: 60

Text {
text: name
anchors.centerIn: parent
}

color: parent.ListView.isCurrentItem ? "red" : "steelblue";
scale: parent.ListView.isCurrentItem ? 1.5 : 1;
}

}
}ListView {
id: listView1
x: 0
y: 50
width: 1920
height: 214
orientation: ListView.Horizontal
spacing: 4
model: TileList{}
delegate: myDelegation
preferredHighlightBegin: width / 2 - 10
preferredHighlightEnd: width / 2 + 10
highlightRangeMode: ListView.StrictlyEnforceRange
}

C ++ Statemachine — это QStatemachine, который отправляет сигналы в qml.

Как мне связать сигналы с делегатом Listview?

1

Решение

Шаг первый — представить конечный автомат как свойство контекста, чтобы он был виден qml:

engine.rootContext()->setContextProperty("SM", stateMachinePtr);

Шаг второй — использовать Connections Элемент для установления соединения:

Connections {
target: SM
onSomeSignal: doSomeStuff()
}
1

Другие решения

Самый простой способ — просто установить конечный автомат на «currentIndex».

Обычным шаблоном является наличие объекта интерфейса, который соединяет QML и QStateMachine.

class StateInterface : public QObject
{
Q_OBJECT
Q_PROPERTY(int currentIndex MEMBER m_currentIndex NOTIFY currentIndexChanged)

public:
explicit StateInterface(QObject *parent = 0);

signals:
void currentIndexChanged() const;

private:
int m_currentIndex;
};

Экземпляр этого объекта предоставляется QML через механизм «свойства контекста»

StateInterface stateInterface;
qmlEngine->rootContext()->setContextProperty("_stateInterface", &stateInterface);

И используется в QML по мере необходимости

ListView {
currentIndex: _stateInterface.currentIndex
}

QStateMachine использует то же самое stateInterface объект в качестве объекта назначения государственной собственности

QState *beginState = new QState(stateMachine);
beginState->assignProperty(&stateInterface, "currentIndex", 0);
// and so on.

Объект StateInterface также может предоставлять слоты, которые будут использоваться QML для изменения состояния. Например.

public slots:
void triggerReset() { emit trigger reset(); }

signals:
void reset();

И QStateMachine может, например, затем реагировать на эти сигналы с переходом сигнала в beginState

Подводя итог этой технике:

  1. QStateMachine контролирует состояние приложения
  2. все данные о состоянии, представляющие интерес для QML, предоставляются через один или несколько объектов интерфейса
  3. сторона QML использует данные о состоянии хорошим, декларативным способом, как если бы она сама выполняла обработку состояния
2

По вопросам рекламы [email protected]