简体   繁体   English

如何使用QStatemachine影响ListView?

[英]How to use QStatemachine to influence a ListView?

I have got this Projekt which uses a QStatemachine to manage the UI, where I want to add a customized List. 我有这个Projekt,它使用QStatemachine来管理UI,我想在其中添加自定义列表。 The UI is supposed to be only manipulated by key events. UI应该仅由按键事件来操纵。 As far as I understand I need a ListView on the qml side. 据我了解,我在qml端需要一个ListView。

The delegate of ListView only reacts on mouse input or direct key input. ListView的委托仅对鼠标输入或直接键输入作出反应。 But I have use the QStatemachine in C++ to operate it, since it is handling all key events for the UI. 但是我使用C ++中的QStatemachine来操作它,因为它正在处理UI的所有关键事件。 What I want to happen when I press the right arrow key is vor the list to be shifted to the left. 当我按下向右箭头键时,我想发生的事情是列表会向左移动。
(The currentItem is alway in the middle of the screen.) (currentItem始终在屏幕中间。)

这是lisfview的初始状态

在此处输入图片说明

So my ListView is looking like this at the Moment. 所以我的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
        }

The c++ Statemachine is a QStatemachine which sends Signals to qml. c ++状态机是一个QStatemachine,可以将信号发送到qml。

How do I bind the signals to the delegate of the Listview? 如何将信号绑定到Listview的委托?

The easiest way is to just have the state machine set the "currentIndex" 最简单的方法是只让状态机设置“ currentIndex”

A common pattern is to have an interface object that bridges between QML and the QStateMachine 一种常见的模式是拥有一个在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;
};

An instance of that object is exposed to QML via the "context property" mechansism 该对象的实例通过“上下文属性”机制暴露给QML

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

And used in QML as needed 并根据需要在QML中使用

ListView {
    currentIndex: _stateInterface.currentIndex
}

The QStateMachine uses the same stateInterface object as a target for state property assignments QStateMachine使用相同的stateInterface对象作为状态属性分配的目标

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

The StateInterface object can also provide slots to be used by QML to affect state changes. StateInterface对象还可以提供QML用来影响状态更改的插槽。 Eg 例如

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

signals:
    void reset();

And the QStateMachine can, for example, then react to those signals wth a signal transition into the beginState 然后,例如, QStateMachine可以对这些信号做出反应,将信号转换为beginState

To summarize this technique: 总结一下这项技术:

  1. the QStateMachine controls the application state QStateMachine控制应用程序状态
  2. all state data that is of interest to QML is exposed via one or more interface objects QML感兴趣的所有状态数据都通过一个或多个接口对象公开
  3. the QML side uses the state data in a nice, declarative way just like it would if it did the state handling itself QML端以一种很好的声明性方式使用状态数据,就像处理状态本身一样

Step one - expose the state machine as a context property so that it is visible to qml: 第一步-将状态机公开为上下文属性,以便qml可以看到它:

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

Step two - use a Connections element to establish a connection: 第二步-使用Connections元素建立连接:

Connections {
  target: SM
  onSomeSignal: doSomeStuff()
}

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

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