QML Connection with c++
-
I have to do a project in which I command a qt application via ipc events. So the workflow is as follows:
- a node ipc server generates an event that is sent to a unix socket.
- the socket receives the event and this is managed by the C ++ code.
- according to the name of the event a different signal is emitted to the qml that performs a specific function.
The problem lies in the fact that if I send the event immediately after connecting, the workflow works and I get the desired behavior.
ipc.server.on( 'connect', (sock) => { console.log("Connected!!" + sock.toString()); toSendSocket = sock ipc.server.emit(toSendSocket, "eventName?args") });
If instead the sending of the event depends on a user input, I can not get the desired behavior.
const rl = readline.createInterface({ input: process.stdin, output: process.stdout }); rl.question('Event? ', (answer) => { if(answer === "z") { ipc.server.emit(toSendSocket, "eventName?args") } else { ipc.server.emit(toSendSocket, "eventName?args") } rl.close(); });
Obviously this is an example but in any case there will be events generated by the user that trigger the sending of node ipc events to the qt program.
In both cases I receive the node ipc event in the c ++ part of the qt application, but in the second case the event is not propagated to the qml. I can not figure out what the problem is, is there anyone who has any idea where the error might be?
I insert the parts of the code that manage events from node to qml.
IpcConnectionManager::IpcConnectionManager(): socket(new QLocalSocket(this)) { in.setDevice(socket); in.setVersion(QDataStream::Qt_5_10); socket->connectToServer("/tmp/socketName.sock", QIODevice::ReadWrite); if (socket->waitForConnected(100000)){ qDebug("Connected!"); connect(socket, &QLocalSocket::readyRead, this, &IpcConnectionManager::getIPCData); socket->waitForBytesWritten(-1); } else qDebug("NOT Connected!"); } void IpcConnectionManager::getIPCData() { QString data; QByteArray arrayData = socket->readAll(); data = QString::fromLocal8Bit(arrayData); qint32 argsIndex = data.indexOf("?"); QString eventName = data.mid(0, argsIndex); qDebug().noquote() <<"IPC CONNECTION MANAGER eventName " << eventName; QString args = data.mid(argsIndex+1, data.length()); qDebug().noquote() <<"IPC CONNECTION MANAGER args " << args; if (eventName == "event1") { emit event1(); } else if (eventName == "event2") { emit event2(args); } }
These events that are read from the socket are forwarded to another class that emits them to the qml.
IPCEventManager::IPCEventManager() { QThread* ipcThread = new QThread; IpcConnectionManager* ipcConnectionManager = new IpcConnectionManager(); ipcConnectionManager->moveToThread(ipcThread); connect(ipcConnectionManager, SIGNAL (event2(QString)), this, SLOT (event2Function(QString))); connect(ipcConnectionManager, SIGNAL (event1()), this, SLOT (event1Function())); connect(this, SIGNAL (sendResultToSocket(QString, QString)), ipcConnectionManager, SLOT (onSendMeQMLResponse(QString, QString))); ipcThread->start(); } void IPCEventManager::receiveQMLResponse(QString eventName, QString response) { emit sendResultToSocket(eventName, response); } void IPCEventManager::event2(QString url) { emit event2(url); } void IPCEventManager::event1() { emit event1(); }
Finally, the qml part is defined as follows:
IPCEventManager { id: myIpcEventManager onEvent2: { event2(args) } onEvent1: { event1() } }
-
Hi and welcome to devnet,
Are you sure you are getting all the data needed in
getIPCData
each time it's called ? -
Hi and welcome to devnet,
Are you sure you are getting all the data needed in
getIPCData
each time it's called ?@SGaist each time it's called I get all qDebug prints on console until the emit to qml.
For example i have a qdebug here:void IPCEventManager::event2(QString url) { qDebug() << "PRINT HERE EVENT2 BEFORE QML" emit event2(url); }
I always get that print, so I can conclude that the workflow always comes to the emit to the qml.
-
Hi and welcome to devnet,
Are you sure you are getting all the data needed in
getIPCData
each time it's called ?@SGaist I solved by modifying the javascript part of the server. I noticed that on the server I received two connection events. By inserting a control and maintaining the socket of the first connection, the events invited by input are also executed.
Now I just have to understand why it connects twice. I checked the constructor where the connect on qt is executed but only runs once.IpcConnectionManager::IpcConnectionManager(): socket(new QLocalSocket(this)) { in.setDevice(socket); in.setVersion(QDataStream::Qt_5_10); socket->connectToServer("/tmp/socketName.sock", QIODevice::ReadWrite); if (socket->waitForConnected(100000)){ qDebug("Connected!"); connect(socket, &QLocalSocket::readyRead, this, &IpcConnectionManager::getIPCData); socket->waitForBytesWritten(-1); } else qDebug("NOT Connected!"); }``` This is performed only once.
-
@SGaist I solved by modifying the javascript part of the server. I noticed that on the server I received two connection events. By inserting a control and maintaining the socket of the first connection, the events invited by input are also executed.
Now I just have to understand why it connects twice. I checked the constructor where the connect on qt is executed but only runs once.IpcConnectionManager::IpcConnectionManager(): socket(new QLocalSocket(this)) { in.setDevice(socket); in.setVersion(QDataStream::Qt_5_10); socket->connectToServer("/tmp/socketName.sock", QIODevice::ReadWrite); if (socket->waitForConnected(100000)){ qDebug("Connected!"); connect(socket, &QLocalSocket::readyRead, this, &IpcConnectionManager::getIPCData); socket->waitForBytesWritten(-1); } else qDebug("NOT Connected!"); }``` This is performed only once.
Now I just have to understand why it connects twice. I checked the constructor where the connect on qt is executed but only runs once.
Does it connect twice with the connect( ) statement? If so, you can make the connection unique so as to make it connect only once. You may add a fifth argument, Qt::UniqueConnection, inside the end of connect( ).