External process from Qml
-
Maybe I'm being silly here but since you are running what looks like the Hello Speak Example why do you start it as a separate process rather than a separate thread?
-
-
-
That's because you block the event loop that you need to read. Use
void ProcessWidget::vStartProcess() { qDebug()<<"entered the function"<<endl; const QString program = QStringLiteral("/home/ubuntu/Documents/Sample_Examples_Qt_Qml/VoiceRecognition/VoiceRecognition"); myProcess = new QProcess; QEventLoop blockLoop; connect(myProcess,SIGNAL(readyReadStandardError()),this,SLOT(vEndProcess())); connect(myProcess,SIGNAL(finished(int)),myProcess,SLOT(deleteLater())); connect(myProcess,SIGNAL(finished(int)),&blockLoop,SLOT(quit())); connect(this,&ProcessWidget::destroyed,myProcess,&QProcess::kill); myProcess->start(program); qDebug()<<"process started waiting for output"<<endl; blockLoop.exec(); }
-
That's because you block the event loop that you need to read. Use
void ProcessWidget::vStartProcess() { qDebug()<<"entered the function"<<endl; const QString program = QStringLiteral("/home/ubuntu/Documents/Sample_Examples_Qt_Qml/VoiceRecognition/VoiceRecognition"); myProcess = new QProcess; QEventLoop blockLoop; connect(myProcess,SIGNAL(readyReadStandardError()),this,SLOT(vEndProcess())); connect(myProcess,SIGNAL(finished(int)),myProcess,SLOT(deleteLater())); connect(myProcess,SIGNAL(finished(int)),&blockLoop,SLOT(quit())); connect(this,&ProcessWidget::destroyed,myProcess,&QProcess::kill); myProcess->start(program); qDebug()<<"process started waiting for output"<<endl; blockLoop.exec(); }
-
@p3c0 thanks for the reply...
yea i am doing the same now... i am using a C++ class and Qprocess to start another process....the new process gives me a string (it is a command said in live microphone) which i pass it through signal back to the qml...but what is happening is..when i call the c++ function from qml, the control doesn't wait until the function is over, it continues to print some debug statements, which i have given after that function call@Naveen_D said in External process from Qml:
but what is happening is..when i call the c++ function from qml, the control doesn't wait until the function is over, it continues to print some debug statements, which i have given after that function call
@Naveen_D said in External process from Qml:
if i use the EventLoop it is not returning control
I'm not sure I understand what you want to achieve. Do you want the process to act synchronously (loop until process is over) or asynchronously (return control almost immediately to the main app)?
-
@Naveen_D said in External process from Qml:
but what is happening is..when i call the c++ function from qml, the control doesn't wait until the function is over, it continues to print some debug statements, which i have given after that function call
@Naveen_D said in External process from Qml:
if i use the EventLoop it is not returning control
I'm not sure I understand what you want to achieve. Do you want the process to act synchronously (loop until process is over) or asynchronously (return control almost immediately to the main app)?
@VRonin the scenario is..when i call the c++ function from qml it should start the process...through which i get the output and will pass the output through a signal back to qml. till the process is not completed it should not return back to main app(i.e Qml app).
Now i am getting the output to my console but i am not able to send it as shown in the above code. -
@VRonin the scenario is..when i call the c++ function from qml it should start the process...through which i get the output and will pass the output through a signal back to qml. till the process is not completed it should not return back to main app(i.e Qml app).
Now i am getting the output to my console but i am not able to send it as shown in the above code.@Naveen_D Why should it not return? What you are trying to do is not how Qt apps should work. You should use signals/slots: you start the process, connect signals/slots and as soon as there is input from the process you handle it in the slot.
-
@Naveen_D Why should it not return? What you are trying to do is not how Qt apps should work. You should use signals/slots: you start the process, connect signals/slots and as soon as there is input from the process you handle it in the slot.
-
@jsulm Sorry sir i didn't get...is the above code wrong which i have posted ? or what changes i need to do ?
One more doubt..how to compare a string in Qml...like in Qt we do (str=="some string")
@Naveen_D ProcessWidget::vStartProcess is currently blocking, why? Why not just start the process, connect signals/slots and return from ProcessWidget::vStartProcess ?
void ProcessWidget::vStartProcess() { qDebug()<<"entered the function"<<endl; const QString program = QStringLiteral("/home/ubuntu/Documents/Sample_Examples_Qt_Qml/VoiceRecognition/VoiceRecognition"); myProcess = new QProcess; connect(myProcess,SIGNAL(readyReadStandardError()),this,SLOT(vEndProcess())); connect(myProcess,SIGNAL(readyReadStandardOutput()),this,SLOT(processStandardOutput())); connect(myProcess,SIGNAL(finished(int)),myProcess,SLOT(deleteLater())); connect(this,&ProcessWidget::destroyed,myProcess,&QProcess::kill); myProcess->start(program); }
processStandardOutput() will be called as soon as the process is writing something to standard output.
-
@Naveen_D ProcessWidget::vStartProcess is currently blocking, why? Why not just start the process, connect signals/slots and return from ProcessWidget::vStartProcess ?
void ProcessWidget::vStartProcess() { qDebug()<<"entered the function"<<endl; const QString program = QStringLiteral("/home/ubuntu/Documents/Sample_Examples_Qt_Qml/VoiceRecognition/VoiceRecognition"); myProcess = new QProcess; connect(myProcess,SIGNAL(readyReadStandardError()),this,SLOT(vEndProcess())); connect(myProcess,SIGNAL(readyReadStandardOutput()),this,SLOT(processStandardOutput())); connect(myProcess,SIGNAL(finished(int)),myProcess,SLOT(deleteLater())); connect(this,&ProcessWidget::destroyed,myProcess,&QProcess::kill); myProcess->start(program); }
processStandardOutput() will be called as soon as the process is writing something to standard output.
@jsulm Yes i got that...
i want to know how to compare string s in Qml...
the string which i am passing through the signal...i want to compare that in qml and next give functionality for that...i used the following code but didn't get...
onPlaymusicsignal: { console.log("Recorded Voice :" + recordedString) var receivedString = recordedString console.log(receivedString) if(receivedString == "GOTO MUSIC") { console.log("play music") } else { console.log("please try again") } }
even though the received string is GOTO MUSIC its printing in the console as please try again.
-
-
@jsulm Yes i got that...
i want to know how to compare string s in Qml...
the string which i am passing through the signal...i want to compare that in qml and next give functionality for that...i used the following code but didn't get...
onPlaymusicsignal: { console.log("Recorded Voice :" + recordedString) var receivedString = recordedString console.log(receivedString) if(receivedString == "GOTO MUSIC") { console.log("play music") } else { console.log("please try again") } }
even though the received string is GOTO MUSIC its printing in the console as please try again.
-
@Naveen_D I'm not JavaScript expert (what QML basically is), but as far as I know you can use === instead of ==
If there maybe a new line at the end of receivedString ? -
-
@jsulm ya i checked...after checking that code only i used var in the code as shown above...but i didn't get that clearly so posted this in forum.
-
if(receivedString.localeCompare("GOTO MUSIC") == 0) { console.log("play music") } else { console.log("please try again") }
@jsulm
i tried with both the codes...its going to else part.onPlaymusicsignal: { console.log("Recorded Voice :" + recordedString) var receivedString = recordedString console.log(receivedString) if(receivedString.localeCompare("GOTO MUSIC") == 0) { console.log("play music") musicScreen.visible= true } else { console.log("please try again") }
onPlaymusicsignal: { console.log("Recorded Voice :" + recordedString) var receivedString = recordedString var GotoMusicString = new String("GOTO MUSIC") console.log(receivedString) if(receivedString.localeCompare(GotoMusicString) == 0) { console.log("play music") musicScreen.visible= true } else { console.log("please try again") } }
-
@jsulm
i tried with both the codes...its going to else part.onPlaymusicsignal: { console.log("Recorded Voice :" + recordedString) var receivedString = recordedString console.log(receivedString) if(receivedString.localeCompare("GOTO MUSIC") == 0) { console.log("play music") musicScreen.visible= true } else { console.log("please try again") }
onPlaymusicsignal: { console.log("Recorded Voice :" + recordedString) var receivedString = recordedString var GotoMusicString = new String("GOTO MUSIC") console.log(receivedString) if(receivedString.localeCompare(GotoMusicString) == 0) { console.log("play music") musicScreen.visible= true } else { console.log("please try again") } }
-
@jsulm this is the output i am getting from the started process and the same output i am sending through the signal to qml
output>>>> "\n<<< please speak >>> \n\n \n\n"
output>>>> "Received Command: "GOTO MUSIC"\n"
Output of regular exp is: ""GOTO MUSIC""
signal data is >> ""GOTO MUSIC""qml: Recorded Voice :"GOTO MUSIC"
qml: "GOTO MUSIC"
qml: please try again