Connecting C++ signal to QML slot
-
Hi,
I am new to qt and want to pass a simple signal from a c++ widget to qml. I followed the structure in this document with a few changes. . The code complies but nothing shows up due to this error:
QObject::connect: No such slot QQuickItem::qmlSlot(QVariant) in ../qmltest/mainwindow.cpp:15
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////QT += core gui qml quickwidgets
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++11
...///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
mainwindow.cpp:
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
auto cppObj = new Widget();
auto quickWidget = new QQuickWidget(QUrl("qrc:/main.qml"));
auto qmlObj = quickWidget->rootObject();// Connect C++ signal to QML slot connect(cppObj, SIGNAL(cppSignal(QVariant)), qmlObj, SLOT(qmlSlot(QVariant)));
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
mainwindow.h:
class MainWindow : public QMainWindow
{
Q_OBJECTpublic:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
};
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
widget.cpp:Widget::Widget(QWidget *parent)
: QWidget(parent)
{button = new QPushButton("Click Me!", this); connect(button, &QPushButton::clicked, [=] { emit cppSignal("hello"); });
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
widget.h:class Widget : public QWidget
{
Q_OBJECT
QPushButton *button;
signals:
void cppSignal(const QVariant& sentMsg) const;public:
Widget(QWidget *parent = 0);
~Widget();
};
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
main.qml:
import QtQuick 2.15
import QtQuick.Controls 2.15Item {
Rectangle {
width: 100; height: 100
function qmlSlot(receivedMsg) {
console.log("QML received: " + receivedMsg)
}}
}
Can anyone help me with this? I also used MetaObject::invokeMethod(qmlObj, "qmlSlot"); same error.
Note that in this project I designed a keyboard by QWidgets to type and want to pass the pushed keys to the qml which is a chat GUI in this work. So I have to use qquickwidgets to show both keyboard and chat GUI in the same window. -
@Mary_M
you try to connect to a method of the rootItem(). But in your qml file the object with the desired method is not the root item. It has a parent Item.Its probably anyway easier to do the connection inside QML and not in C++.
-
@raven-worx Thank you! I tried with the root item, no error but the text doesn't show up! Also, I need the signal to be emitted from C++.
-
@Mary_M It is recommended to make the connection in qml:
*.cpp
auto cppObj = new Widget(); auto quickWidget = new QQuickWidget(); quickWidget->rootContext()->setContextProperty("cppObj", cppObj); quickWidget->setSource(QUrl("qrc:/main.qml"));
main.qml
import QtQuick 2.15 import QtQuick.Controls 2.15 Item { Rectangle { width: 100; height: 100 } Connections{ target: cppObj function onCppSignal(receivedMsg){ console.log("QML received: " + receivedMsg) } } }
-
Try something like this:
Q_INVOKABLE void triggerEvent(QString text) { emit signalEvent(text); } Person() { startTimer(1000); } void timerEvent(QTimerEvent *e) { QString text = "Hello"; triggerEvent(text); } signals: void signalEvent(QString text); //In qml: id: myQmlObject onSignalEvent: { console.log(" Message " + text); }
-
@eyllanesc Thank you so much! but when I use connections this is the error:
QObject::connect: Cannot connect Widget::cppSignal(QVariant) to (nullptr)::qmlSlot(QVariant)I also tried this one but still the same:
Item {
Rectangle {
id: rect
width: 100; height: 100
Text{id:myText} }
Connections{
target: cppObj
function onCppSignal(receivedMsg){
MyText.text = receivedMsg;
}
}
} -
@eyllanesc You are right! I deleted connect in mainwindow now and built it again. No error now but no output either! Only empty window showed up. At the end I used Qframe and gridline to add button and rect alongside. Many thanks!