Trouble when using QObject::connect to connect QML signal to Cpp slot
-
Hello,
I try to create a very simple interaction between a QML item with a 'TextField' and cpp class.
QML item - WebRadioUrlSettingForm.qml
TextField { id: urlField implicitWidth: parent.width placeholderText: "Enter URL here..." onAccepted: urlForm.setWebRadioUrl(urlField.getText()) }
Cpp class - Player.cpp
class Player : public QObject { Q_OBJECT QML_ELEMENT QML_SINGLETON public: explicit Player(QObject *parent = nullptr); //some variables and function public slots: void setWebRadioUrl(QString newUrl);
The problem is when I try to connect those in the main.cpp class as it is shown in the documentation
int main(int argc, char *argv[]) { QGuiApplication app(argc, argv); QScopedPointer<Player> player(new Player); QQmlApplicationEngine engine; QQuickView view(QUrl::fromLocalFile("WebRadioUrlSettingForm.qml")); QQuickItem* item = view.rootObject(); QObject::connect(item, SIGNAL(setWebRadioUrl(QString)), player, SLOT(setWebRadioUrl(QString))); qmlRegisterSingletonInstance("Player", 1, 0, "Player", player.get()); const QUrl url(u"qrc:/POCWebRadioPlayer/main.qml"_qs); QObject::connect(&engine, &QQmlApplicationEngine::objectCreated, &app, [url](QObject *obj, const QUrl &objUrl) { if (!obj && url == objUrl) QCoreApplication::exit(-1); }, Qt::QueuedConnection); engine.load(url); return app.exec(); }
On this line:
QObject::connect(item, SIGNAL(setWebRadioUrl(QString)), player, SLOT(setWebRadioUrl(QString)));
I get this error:
"no matching function for call to 'QObject::connect(QQuickItem*&, const char*, QScopedPointer<Player>&, const char*)'"Is it because I made a mistake on the connect function parameters? Or because the receiver (the 'player' class) is a scoped pointer? Or because there is two QObject::connect, which are refering to different functions in the qobject.h file, in the same function? Or something else?
Thanks for reading.
Have a nice day
-
@Aymeric_Qt Don't do that. Here's why:
https://doc.qt.io/qt-6/qtquick-bestpractices.html#interacting-with-qml-from-c
http://doc.qt.io/qt-6/qtqml-cppintegration-overview.html#interacting-with-qml-objects-from-c
https://youtu.be/vzs5VPTf4QQ?t=23m20sJust call your C++ object slot from QML:
onAccepted: Player.setWebRadioUrl(urlField.getText())
Or you could do that in your WebRadioUrlSettingForm file and do:
onSetWebRadioUrl: url => Player.setWebRadioUrl(url)
-
@Aymeric_Qt said in Trouble when using QObject::connect to connect QML signal to Cpp slot:
QScopedPointer
thats not a valid overload for the connect statement you have to use the QObjecte class object, so get it via
data()
-
Hi @J-Hilk
I've just add the .data() but I still get the same error. However it is certainly a solution to the first part of this problem.QObject::connect(item, SIGNAL(setWebRadioUrl(QString)), player.data(), SLOT(setWebRadioUrl(QString)));
Beside I have a another question: why can't I write "QObject* item = view.rootObject();" (like they do in the documentation) ?
Because "view.rootObject()" returns a pointer to a QQuickItem which inherits from QObject ? Can it be a problem too ? -
@Aymeric_Qt said in Trouble when using QObject::connect to connect QML signal to Cpp slot:
why can't I write
Cast the pointer returned by rootObject() to QObject*
-
@Aymeric_Qt Don't do that. Here's why:
https://doc.qt.io/qt-6/qtquick-bestpractices.html#interacting-with-qml-from-c
http://doc.qt.io/qt-6/qtqml-cppintegration-overview.html#interacting-with-qml-objects-from-c
https://youtu.be/vzs5VPTf4QQ?t=23m20sJust call your C++ object slot from QML:
onAccepted: Player.setWebRadioUrl(urlField.getText())
Or you could do that in your WebRadioUrlSettingForm file and do:
onSetWebRadioUrl: url => Player.setWebRadioUrl(url)
-
@GrecKo
Thank you for your reply. I saw the same warning ("Warning: Although it is possible to access QML objects from C++ and manipulate them, it is not the recommended approach...") in this page but I thought it was only applied to this section.
Which, thinking about this now, does not make any sense because in order to connect to a QML signal I need to access the QML object by name so indeed it was not a good idea/practice (the video you linked is very clear about this and very interesting btw).I think that calling the cpp object slot from the QML will be much easier!
Thank you all for your answers
-