Qt Quick - Как взаимодействовать со свойством qml исключительно из кода C ++ - PullRequest
0 голосов
/ 21 февраля 2020

В проекте Qt5, написанном с использованием Visual Studio 2019, мне нужно очень тесно общаться с несколькими свойствами qml из класса c ++. Точнее, мне нужно иметь возможность изменять свойства x, y, width и height окна qml из моего класса c ++, а также мне нужно получать уведомление и, конечно, знать новое значение, когда эти свойства изменились.

Написав часть кода на стороне qml, я смог найти следующее решение:

qml file:

...
ApplicationWindow
{
    id: mainWindow
    ...
    onXChanged: {if (mfMainFormHelper) mfMainFormHelper.onFormXChanged(mainWindow.x);}
    onYChanged: {if (mfMainFormHelper) mfMainFormHelper.onFormYChanged(mainWindow.y);}
    onWidthChanged: {if (mfMainFormHelper) mfMainFormHelper.onFormWidthChanged(mainWindow.width);}
    onHeightChanged: {if (mfMainFormHelper) mfMainFormHelper.onFormHeightChanged(mainWindow.height);}

    Connections
    {
        target: mfMainFormHelper

        onDoChangeX:
        {
            mainWindow.x = value;
        }

        onDoChangeY:
        {
            mainWindow.y = value;
        }

        onDoChangeWidth:
        {
            mainWindow.width = value;
        }

        onDoChangeHeight:
        {
            mainWindow.height = value;
        }
    }
    ...

WQtMainFormHelper.h

class WQtMainFormHelper : public QObject
{
    Q_OBJECT

    Q_SIGNALS:
        void doChangeX(int value);
        void doChangeY(int value);
        void doChangeWidth(int value);
        void doChangeHeight(int value);
    ...
    public:
    ...
        virtual Q_INVOKABLE void onFormXChanged(int value);
        virtual Q_INVOKABLE void onFormYChanged(int value);
        virtual Q_INVOKABLE void onFormWidthChanged(int value);
        virtual Q_INVOKABLE void onFormHeightChanged(int value);
    ...

main. cpp

...
WQtMainFormHelper mainFormHelper;
m_pQTEngine->rootContext()->setContextProperty("mfMainFormHelper", &mainFormHelper);
...

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

Итак, мой вопрос: как достичь тех же функций, что и выше, но писать весь код в моем классе c ++ без ANY строки кода на стороне qml

Ответы [ 2 ]

0 голосов
/ 26 февраля 2020

Наконец-то я смог решить свою проблему следующим образом:

  1. Я создал класс, унаследованный от QObject
  2. Я получил свой указатель окна qml как объект QWindow с QQmlApplicationEngine, после загрузки qml
  3. Я использовал функцию connect () для подключения необходимых мне сигналов, как в следующем примере: connect(pQtWindow, &QWindow::widthChanged, this, &WQtFormHelper::onFormWidthChanged);
  4. Я использовал прокси Qt для чтения и записи в свойства моего окна, как в следующем примере: int value = QQmlProperty(pQtWindow, "width").read().value<int>();

    QQmlProperty(pQtWindow, "width").write(1000);

    ( NOTE pQtWindow->setProperty("width", 1000); также работает )

0 голосов
/ 25 февраля 2020

Попробуйте заменить Q_SIGNAL & Q_INVOKABLE на Q_PROPERTIES и реализовать все слоты / сигналы. А в пользовательском интерфейсе используйте привязку свойств в mainWindow, например «x: mfMainFormHelper.x» для всех 4 свойств.

Не используйте оператор присвоения, он нарушает привязку свойства (т. Е. Уведомления прекращают работу над этим свойством)

...