Проблема с сигналами между QML и С++

97
07 августа 2019, 15:20

Проблема состоит в том, как отследить сигнал при смене песни в QMediaPlayer::durationChanged и это значение установить в Slider через свойство to?

MainWindwow.cpp

//Включаем наш QML
ui = new QQuickWidget;
ui->setSource(QUrl("qrc:/main.qml"));
setCentralWidget(ui);
ui->setResizeMode(QQuickWidget::SizeRootObjectToView);
//Находим корневой элемент
Root = ui->rootObject();
//Соединяем C++ и QML, делая видимым функции С++ через элемент window
ui->rootContext()->setContextProperty("window", this);
AppController appcontroller;
ui->rootContext()->setContextProperty("app", &appcontroller);

Моя попытка установить соединение состоялась в том, чтобы создать новый класс, благодаря которому, будет происходить отправка сигнала:

Вот пример такого класса:

appcontroller.h

#ifndef APPCONTROLLER_H
#define APPCONTROLLER_H
#include <QObject>
#include <iostream>
class AppController : public QObject
{
    Q_OBJECT
public:
    explicit AppController(QObject *parent = nullptr);
signals:
    // Сигнал для передачи данных в qml-интерфейс
    void sendToQml(qint64 value);
public slots:
    // Слот для приёма данных из c++
    void receiveFromC(qint64 value);
};
#endif // APPCONTROLLER_H

appcontroller.сpp

#include "appcontroller.h"
AppController::AppController(QObject *parent) : QObject(parent)
{
}
void AppController::receiveFromC(qint64 value)
{
    emit sendToQml(value);
}

Так же конект в qml:

main.qml

Connections
{
    target: app
    onSendToQml:
    {
        slider.position = value
    }
}

Но все равно конект не происходит.

connect(player, &QMediaPlayer::durationChanged, appcontroller, &AppController::receiveFromC);
Answer 1

Может кому-нибудь понадобится.

Чтобы отправить сигнал из C++ кода в qml-интерфейс я добавил в свой основной класс Mainwindow дополнительный сигнал и слот. Слот был нужен для принятия значения, а сигнал соответственно - для передачи этого значения:

MainWindow.h

signals:
    void sendValueToQml(qint64 value);
public slots:
    void takeValue(qint64);

MainWindow.cpp

void MainWindow::takeValue(qint64 value)
{
    emit sendValueToQml(value);
}

Ну и сам конект (Дополнительно, я value прописал еще и в самом классе):

connect(player, &QMediaPlayer::positionChanged, this, &MainWindow::takeValue);

Теперь в сам qml файл нужно добавить следующее
( Где window подключается через контекст ui->rootContext()->setContextProperty("window", this); )

Connections
{
    target: window
    onSendValueToQml: slider.value = value
}

И тут есть небольшая хитрость с написанием самого сигнала. Во-первых название сигнала должно начинаться не с on и с большой буквы (Желательно). И затем в Connections нужно записать: on + название сигнала с большой буквы. Допустим:

signalToQml - на C++
onSignalToQml - на QML

И прелесть вся в том, что можно создавать множество различных сигналов и слотов. И потом просто добавлять все в Connections.

READ ALSO
Qt Signal при добавлении нового окна в приложении

Qt Signal при добавлении нового окна в приложении

Существует ли возможность в Qt посредством SIGNAL отследить, если было добавлено новое QWindow окно? Необходимо, чтобы определённый объект следил...

123
С чем связано ограничение на объявление friend функций в локальных классах?

С чем связано ограничение на объявление friend функций в локальных классах?

С чем связано ограничение на объявление friend функций в локальных классах?

98
Как сделать , чтобы после нажатия на крестик(закрыть приложение), выскакивал MessageBox?

Как сделать , чтобы после нажатия на крестик(закрыть приложение), выскакивал MessageBox?

Вот про логику, как сделать сам MessageBox , я знаюВпихиваю код в деструктор:

125