Unsolved text append waits until hcitoo scan is finished
-
@ChrisW67 Yes, QTBluetooth "support" won't even recognize that I turned Bluetooth off in OS - and happily reports "finished " - no error.
I did try at lest two versions of QTCreator with same result.
FYI _ I am using Ubuntu. -
@Jamieghosal I think the basic "problem" is
OProcess.waitForFinished(60000);
I do not get how QT executes basic C function by "waiting" for it to return "true".
That basically blocks the rest of the code and I expect "process" not to do that.
So it back to finding out how to make "process" NOT to block the rest of the code. Long time ago I used QProgressBar and it is the time to try it again - I should be able to "update" the QProgressBar on each second - hence the QProcess needs to be convinced to do so. -
@AnneRanch QProcess is asynchronous as already explained. Learn how to use it that way.
-
@SGaist And what do you think I am doing ? I do not need such comments.
Cheers -
Well, you are using the blocking API, hence my suggestion. Stop doing that and use signals and slots to manage your QProcess object.
Make a list of the commands you want to execute. Pick the first, start it, then when it is done (use the finished signal to know), start the next on the list and so on until they are all done. No freeze will happen.
-
@SGaist Tep, that is what I am doing and as usual I am stuck on "connect".
Sure could use a real example of connect to get me going...
This "wait for completion" sure was of no help to really understand QProcess... -
There's an example in the finished signal documentation using a lambda.
There's a chapter dedicated to the explanation on how signal and slots work. -
@AnneRanch said in text append waits until hcitoo scan is finished:
Tep, that is what I am doing and as usual I am stuck on "connect".
Sure could use a real example of connect to get me going...
This "wait for completion" sure was of no help to really understand QProcess...does this help?
#ifndef HCITOOLPROCESS_H #define HCITOOLPROCESS_H #include <QObject> #include <QProcess> #include <QElapsedTimer> #include <iostream> class HciToolProcess : public QObject { Q_OBJECT public: enum HciCommands : uint8_t { Dev, Inq, Scan, }; explicit HciToolProcess(QObject *parent = nullptr) : QObject(parent), m_currentCommand{HciCommands::Dev} { connect(&m_process, QOverload<int,QProcess::ExitStatus>::of(&QProcess::finished), this, &HciToolProcess::nextCommand); } bool startProcess(){ if(m_currentCommand != HciCommands::Dev) return false; m_elapsedTime.start(); m_process.start(QStringLiteral("hcitool"), QStringList(HciCommandToString(m_currentCommand)), QIODevice::ReadWrite); return true; } signals: void timeElapsed(const QString &time); // to update your textEdit_2 void allProcessesDone(); private: void nextCommand(int exitCode, QProcess::ExitStatus exitStatus){ std::cout<<"\n * Program to demonstrate the usage of linux commands in qt * \n"; QString StdOut = m_process.readAllStandardOutput(); //Reads standard output QString StdError = m_process.readAllStandardError(); //Reads standard error std::cout<<"\n Printing the standard output..........\n"; std::cout<<std::endl<<StdOut.toStdString(); std::cout<<"\n Printing the standard error..........\n"; std::cout<<std::endl<<StdError.toStdString(); std::cout<<"\n Printing exit code..........\n"; std::cout<<std::endl<<exitCode; std::cout<<"\n Printing exitStatus..........\n"; std::cout<<std::endl<<exitStatus; std::cout<<"\n\n"; QString elapsedTime = QString::number(m_elapsedTime.restart()); emit timeElapsed(elapsedTime); m_currentCommand = static_cast<HciCommands>(m_currentCommand + 1); if(static_cast<uint8_t>(m_currentCommand) <= static_cast<uint8_t>(HciCommands::Scan)){ m_process.start(QStringLiteral("hcitool"), QStringList(HciCommandToString(m_currentCommand)), QIODevice::ReadWrite); } else { m_currentCommand = HciCommands::Dev; emit allProcessesDone(); } } QString HciCommandToString( HciCommands cmd) { switch (cmd) { case HciCommands::Dev: return QStringLiteral("dev"); case HciCommands::Inq: return QStringLiteral("inq"); case HciCommands::Scan: return QStringLiteral("scan"); default: Q_UNREACHABLE(); return QLatin1String(); } } private: QElapsedTimer m_elapsedTime; HciCommands m_currentCommand; QProcess m_process; }; #endif // HCITOOLPROCESS_H
-
@J-Hilk
I was thinking about writing something like this, but assumed the effort would be ignored.If you were to get rid of your enumeration/
switch
statement and instead create some list of the commands (plus parameters) to be used, which the caller passes/sets on the class, it would be a generic "execute any arbitrary list of commands sequentially" class. -
@JonB sure, here ya go :D
#ifndef HCITOOLPROCESS_H #define HCITOOLPROCESS_H #include <QObject> #include <QProcess> #include <QElapsedTimer> #include <iostream> class HciToolProcess : public QObject { Q_OBJECT public: struct CommandAndArguments{ QString command; QStringList arguments; }; explicit HciToolProcess(QObject *parent = nullptr) : QObject(parent), m_index{-1} { connect(&m_process, QOverload<int,QProcess::ExitStatus>::of(&QProcess::finished), this, &HciToolProcess::onProcessFinished); } bool startProcess(QList<CommandAndArguments> commands){ if(m_index != -1 || commands.isEmpty()) return false; m_cmdAndArgs = commands; m_elapsedTime.start(); //m_index is -1 so the function will set it to 0 processCommandAndArguments(); return true; } signals: void timeElapsed(const QString &time); // to update your textEdit_2 void allProcessesDone(); private: void processCommandAndArguments(){ m_index++; if(m_index < m_cmdAndArgs.size()){ m_process.start(m_cmdAndArgs.at(m_index).command, m_cmdAndArgs.at(m_index).arguments, QIODevice::ReadWrite); } else { m_index = -1; emit allProcessesDone(); } } void onProcessFinished(int exitCode, QProcess::ExitStatus exitStatus){ std::cout<<"\n * Program to demonstrate the usage of linux commands in qt * \n"; QString StdOut = m_process.readAllStandardOutput(); //Reads standard output QString StdError = m_process.readAllStandardError(); //Reads standard error std::cout<<"\n Printing the standard output..........\n"; std::cout<<std::endl<<StdOut.toStdString(); std::cout<<"\n Printing the standard error..........\n"; std::cout<<std::endl<<StdError.toStdString(); std::cout<<"\n Printing exit code..........\n"; std::cout<<std::endl<<exitCode; std::cout<<"\n Printing exitStatus..........\n"; std::cout<<std::endl<<exitStatus; std::cout<<"\n\n"; QString elapsedTime = QString::number(m_elapsedTime.restart()); emit timeElapsed(elapsedTime); processCommandAndArguments(); } private: QElapsedTimer m_elapsedTime; QProcess m_process; QList<CommandAndArguments> m_cmdAndArgs; int32_t m_index; }; #endif // HCITOOLPROCESS_H