Управление QML-интерфейсом из C ++ QStateMachine - PullRequest
0 голосов
/ 15 января 2019

Я создаю прототип приложения и хотел бы контролировать переходы пользовательского интерфейса QML из QStateMachine на стороне C ++ приложения. Чтобы упростить задачу, можно сказать, что пользовательский интерфейс QML состоит из нескольких страниц, содержащих кнопки, которые должны инициировать переход с одной страницы на другую.

// main.qml
Window {

    // ..
        StackLayout {
            id: layout
            anchors.fill: parent
            currentIndex: uiController.currentPage // binding with the C++ side

            Page0 {
                id: page0
            }
            Page1 {
                id: page1
            }
            Page2 {
                id: page2
            }
            Page3 {
                id: page3
            }
        }
    // ..
    }
}

Теперь у каждого Page есть Button, чтобы пользователь мог перейти на другую страницу:

// example of Page0.qml 
Page {
    id: root

    // ..    

    Button {
        text: "Page 1"
        width: 100
        height: 100
        anchors.top: text.bottom
        anchors.horizontalCenter: text.horizontalCenter
        anchors.horizontalCenterOffset: 10
        onClicked: {
            console.log("Button clicked")
            backend.msg = "Button clicked !"
            uiController.buttonClicked = 1; // binding with the C++ side
        }
    }
    // ..      
}

На стороне C ++ у меня есть контроллер, который внутренне использует машину состояний для управления переходами:

class UIController : public QObject
{
    Q_OBJECT
    Q_PROPERTY(int buttonClicked READ buttonClicked WRITE setButtonClicked NOTIFY buttonClickedChanged)
    Q_PROPERTY(int currentPage READ currentPage WRITE setCurrentPage NOTIFY currentPageChanged)

public:
    // ..

private:
    QStateMachine m_machine;
    int m_buttonClicked;
    int m_currentPage;
};

Теперь важной частью является настройка QStateMachine:

UIController::UIController()
    : m_buttonClicked(0)
{   
    QState *page1 = new QState();
    QState *page2 = new QState();
    QState *page3 = new QState();
    QState *page4 = new QState();
    // ButtonTransition rely on a ButtonEvent 
    ButtonTransition *tr1 = new ButtonTransition(1);
    ButtonTransition *tr2 = new ButtonTransition(2);
    ButtonTransition *tr3 = new ButtonTransition(3);
    ButtonTransition *tr4 = new ButtonTransition(4);

    // the current page is a state property
    page1->assignProperty(this, "currentPage", 0);
    page2->assignProperty(this, "currentPage", 1);
    page3->assignProperty(this, "currentPage", 2);
    page4->assignProperty(this, "currentPage", 3);

    tr1->setTargetState(page2);
    tr2->setTargetState(page3);
    tr3->setTargetState(page4);
    tr4->setTargetState(page1);

    page1->addTransition(tr1);
    page2->addTransition(tr2);
    page3->addTransition(tr3);
    page4->addTransition(tr4);

    m_machine.addState(page1);
    m_machine.addState(page2);
    m_machine.addState(page3);
    m_machine.addState(page4);
    m_machine.setInitialState(page1);

    m_machine.start();
}

И, наконец, для переходов, которые происходят:

/* this setter function is called everytime the QML side change the
   buttonClicked property of the UiController */
void UIController::setButtonClicked(int button)
{
    if (m_buttonClicked != button) {
        m_buttonClicked = button;
        m_machine.postEvent(new ButtonEvent(button));
        emit buttonClickedChanged();
    }
}

На самом деле это работает, но я спрашиваю, есть ли лучшие способы сделать это: я думаю, что этот подход немного "неуклюжий".

Особенно возможно связать переход конечного автомата напрямую с сигналами QML? (как для QSignalTransition)

Спасибо.

1 Ответ

0 голосов
/ 15 января 2019

В частности, возможно ли привязать переход конечного автомата непосредственно к сигналам QML?

Да. Вы можете подключить сигнал entered() из любого подсостояния, например, к. buttonClickedChanged().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...