Unsolved How to catch a signal emitted from cpp class in Qml ?
-
@Jagh but if i dont create a object of handletextfield in main.cpp how can i connect the signal and slot ?
-
@Jagh You mean to say the following part is not required in main.cpp ??
HandleTextField handleTextField; QObject *topLevel = engine.rootObjects().value(0); QQuickWindow *window = qobject_cast<QQuickWindow *>(topLevel); // QObject::connect(window, SIGNAL(submitTextField()), // &handleTextField, SLOT(handleSubmitTextField())); QObject::connect(&handleTextField, SIGNAL(setTextField()), window, SLOT(setTextField()));
only i need to emit the signal and catch it in qml..in the same way as you have done ?
-
- You connect objects, not classes with signal-slot mechanism. So if you connect one object HandleTextField to something, this connection will not automatically transfer to other objects of the same class.
- Exactly, that part is not required, and in fact, it doesn't do anything. Connections for one object in your C++ code don't transfer to unrelated objects in QML.
- Yep, for each signal an object emits, QML exposes a property named on<SignalName>, in your case this would be onSetTextField. You can set this property as i have done, but AFAIK it should also be possible to set it from outside, having
testsignal.onSetTextField: { console.log("signal called") }
somewhere in your Qml should suffice
-
@Jagh thank you for your reply...
now i have removed that part from main.cpp...but now also when i emit a signal i am not able to catch it in Qml...
the way i am registering that handletextfiled class, is it correct ...???here is the code...
main.qml
import QtQuick 2.3 import QtQuick.Window 2.2 import QtQuick.Controls 1.2 import com.handletextfield 1.0 Window { visible: true width: 360 height: 360 HandleTextField { id: testsignal onSetTextField: { console.log("Signal catched successfully...") } } }
main.cpp
#include <QGuiApplication> #include <QQmlApplicationEngine> #include <QQuickWindow> #include <QQmlContext> #include "handletextfield.h" int main(int argc, char *argv[]) { QGuiApplication app(argc, argv); qmlRegisterType<HandleTextField>("com.handletextfield",1,0,"HandleTextField"); QQmlApplicationEngine engine; engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); return app.exec(); }
handletextfield.cpp
#include "handletextfield.h" HandleTextField::HandleTextField(QObject *parent) : QObject(parent) { handleSubmitTextField(); } void HandleTextField::handleSubmitTextField() { qDebug() << "c++: HandleTextField::handleSubmitTextField:" << endl; emit setTextField(); qDebug()<<"Signal emitted..."<<endl; }
-
You are sending signal way too early, before there was any chance for a connection to be established. In constructor the object hasn't been fully initialized yet, in particular, the QML-interpreter hadn't had a chance to initialize the object's properties from QML side yet.
-
@Jagh Okay...
then when should i emit a signal...so that i can catch over there...calling my function in constructor is the mistake...?? -
I changed your code a bit so that handleSubmitTextField() is called in more appropriate time(actually i just added a Button and called this function in onClicked handler), and the signal handler was successfully called.
To when: anytime between QML object initialization (implement Component.onCompleted if you want to catch it) and object destruction is ok.
-
@Jagh can you please post the code so that i will get a clear picture of what i need to do...thanks...
-
@Jagh I tried the way u told by adding a button and calling the handler...it worked thanks...\o/
-
And if you really want to execute some code as soon as possible and have a guarantee that a QML object was fully initialized by the time your code is running, do it in Component.onCompleted handler of that object.
-
Ok thanks... i will try that also...:-)
-
Hi i have doubt regarding catching a signal emitted from c++ file
if there are more than 2 .qml files does it catch the signal ?
for ex, i have one .cpp and 4 .qml such as mainform.qml,radio.qml,music.qml,setting .qml
so if i emit a signal and try to catch it in setting.qml does it work ?? -
@Naveen_D
Yes it works. I have tried before. -
@VincentLiu but in my case it is not working....
my code is...
this .cpp where i am emitting signal..if(!WordList.isEmpty()) { WordList.removeFirst(); WordList.removeLast(); // QMessageBox m_popupmsgbox; // m_popupmsgbox.setWindowTitle("Voice Recognizer"); // Phoneme=WordList.join(" "); // qDebug()<<"firstword"<<Phoneme<<endl; // QSpacerItem* horizontalSpacer = new QSpacerItem(500, 100, QSizePolicy::Minimum, QSizePolicy::Expanding); // m_popupmsgbox.setText( Phoneme); // QGridLayout* layout = (QGridLayout*)m_popupmsgbox.layout(); // layout->addItem(horizontalSpacer, layout->rowCount(), 0, 1, layout->columnCount()); // m_popupmsgbox.exec(); // emitSignalFunc(); // m_emitSignal= new EmitSignalClass; // m_emitSignal->emitSignalmethod(); VoiceRecognition voice; voice.playmusicsignal(); } else { qDebug()<<"List is empty"<<endl; }
my .qml is
Rectangle{ id:voicerecRect width: settings_main_rect.width/5 height: settings_main_rect.height/4 color: "transparent" VoiceRecognition { id: voiceRecognizer onPlaymusicsignal: { console.log("Signal catched...") } } Image { id: vr_image source: "qrc:/AppbarIcon.png" //source: "qrc:/Voice-Recoder-icon.png" width: parent.width-10 height: parent.height-10 smooth: true fillMode: Image.PreserveAspectFit anchors.centerIn: parent Text { id: vrtext anchors.top: parent.bottom anchors.horizontalCenter: vr_image.horizontalCenter text: qsTr("Voice Recorder") color: "white" font.pixelSize: parent.height * (2 / 9) } MouseArea { anchors.fill: parent onClicked: { //popup.open() voicerecRect.color = 'green' voiceRecognizer.vstartVoiceRecognition() } } } } }
i have registered the class using qmlregister and i am using signal handler to catch the signal...
-
@Naveen_D
Hi, first of all, I should say that I use different ways to do this. However, according to some similar experience on it. I guess you shouldn't use a new VoiceRecognition object in your .cpp file. I don't think distinct object derived from the same class can communicate this way. Please correct me if I am wrong. Thanks -
@VincentLiu the function in which i am emitting a signal is a global function so i need to create an obj of that class and emit.
-
@VincentLiu what are the different ways...?
-
Hello, can anyone please help me out with this...
thanks