У меня есть этот Projekt, который использует QStatemachine для управления пользовательским интерфейсом, где я хочу добавить настраиваемый список. Предполагается, что пользовательским интерфейсом манипулируют только ключевые события. Насколько я понимаю, мне нужен ListView на стороне qml.
Делегат ListView реагирует только на ввод с помощью мыши или прямой ввод с клавиатуры. Но я использовал QStatemachine в C ++ для управления им, поскольку он обрабатывает все ключевые события для пользовательского интерфейса.
Когда я нажимаю клавишу со стрелкой вправо, я хочу, чтобы список был смещен влево.
(CurrentItem всегда в середине экрана.)
Так что мой 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?
Шаг первый — представить конечный автомат как свойство контекста, чтобы он был виден qml:
engine.rootContext()->setContextProperty("SM", stateMachinePtr);
Шаг второй — использовать Connections
Элемент для установления соединения:
Connections {
target: SM
onSomeSignal: doSomeStuff()
}
Самый простой способ — просто установить конечный автомат на «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
Подводя итог этой технике:
QStateMachine
контролирует состояние приложения