External process from Qml
-
wrote on 16 Jan 2017, 09:07 last edited by
Hi everyone,
is it possible to call an external process from qml ? -
is it possible to call an external process from qml ?
Not directly but you can create a C++ component and expose it to QML and make it execute the external processes
-
is it possible to call an external process from qml ?
Not directly but you can create a C++ component and expose it to QML and make it execute the external processes
wrote on 16 Jan 2017, 09:20 last edited by@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 Can you post the C++ code ?
-
wrote on 16 Jan 2017, 10:02 last edited by
@p3c0 ya sure.
here is the c++ code#include "ProcessWidget.h" ProcessWidget::ProcessWidget(QWidget *parent) : QWidget(parent) { } 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(finished(int)),myProcess,SLOT(deleteLater())); myProcess->start(program); qDebug()<<"process started waiting for output"<<endl; connect(this,&ProcessWidget::destroyed,myProcess,&QProcess::kill); } void ProcessWidget::vEndProcess() { const QString processOut = QString::fromLatin1(myProcess->readAllStandardError()); qDebug()<<"output>>>>"<<processOut<<endl; const QRegularExpression regXp("Received Command:s*(.+)"); const auto regXpMatch = regXp.match(processOut); if(regXpMatch.hasMatch()){ qDebug() << "Output of regular exp is: "<< regXpMatch.captured(1); signalData= regXpMatch.captured(1); qDebug()<<"signal data is >>"<<signalData<<endl; emit playmusicsignal(signalData); } } ProcessWidget::~ProcessWidget() { }
-
-
wrote on 17 Jan 2017, 04:32 last edited by
@p3c0 Sir i used execute instead of start but...i am not able to pass the output which i got from the new process, back to qml...what may be the problem ?
my code#include "ProcessWidget.h" ProcessWidget::ProcessWidget(QWidget *parent) : QWidget(parent) { } 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(finished(int)),myProcess,SLOT(deleteLater())); connect(this,&ProcessWidget::destroyed,myProcess,&QProcess::kill); myProcess->execute(program); // myProcess->waitForStarted(30000); qDebug()<<"process started waiting for output"<<endl; } void ProcessWidget::vEndProcess() { const QString processOut = QString::fromLatin1(myProcess->readAllStandardError()); qDebug()<<"output>>>>"<<processOut<<endl; const QRegularExpression regXp("Received Command:s*(.+)"); const auto regXpMatch = regXp.match(processOut); if(regXpMatch.hasMatch()){ qDebug() << "Output of regular exp is: "<< regXpMatch.captured(1); signalData= regXpMatch.captured(1); qDebug()<<"signal data is >>"<<signalData<<endl; emit playmusicsignal(signalData); } } ProcessWidget::~ProcessWidget() { }
in the above code, i didn't get any debug statements in console from vEndProcess function
-
@Naveen_D Are you sure you want
readyReadStandardError
orreadAllStandardOutput
instead ? -
wrote on 17 Jan 2017, 10:29 last edited by
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?
-
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?
-
wrote on 17 Jan 2017, 11:29 last edited by
-
-
wrote on 17 Jan 2017, 11:57 last edited by
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 callwrote on 17 Jan 2017, 12:32 last edited by VRonin@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)?
wrote on 18 Jan 2017, 04:28 last edited by@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.
1/34