Unsolved ....forwarded to the calling process.??
-
Here is a simple "system call" whose results are output to console.
or as doc said can be " forwarded to the calling process".
Please kindly provide an actual C++ code HOW to "forward to the calling process"....
(I did try to redirect to "<< (QString ) text"...) No go.Thanks
QProcess::execute ("service bluetooth status") ; '
Starts the program program with the arguments arguments in a new process, waits for it to finish, and then returns the exit code of the process. Any data the new process writes to the console is forwarded to the calling process.
-
@AnneRanch said in ....forwarded to the calling process.??:
Any data the new process writes to the console is forwarded to the calling process.
Correct - the output is forwarded to your process and you can read it via readAllStandardOutput()/readAllStandardError()
-
If you insist on using the static function then the child process standard output is injected (forwarded) into the parent process standard input.
#include <QCoreApplication> #include <QProcess> #include <QDebug> int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); int result = QProcess::execute("date", QStringList() << "-u"); // one line output if (result == 0) { // OK QString line; QTextStream in(stdin); in >> line; qDebug() << line; } else { qDebug() << result; } return a.exec(); }
If you use an instance of the QProcess class then you can use the functions referred to by @Christian-Ehrlicher on the instance to obtain the output of the child process.
-
@ChrisW67 No.. I do not "insist" - just happens to find a different way to run QProcess.
Anything wrong with that ?
And in using "static" I also found out that readAllStandardOutput() does not work.
And I was going to ask why - but your post basically answered by unposted question.How does QProcess reads readAllStandardOutput() when it "returns data to the calling process".
It is not "calling process " reading the data - it is still QProcess reading it.
So
if I use "non static" QProcess - how do I read the "data passed to calling process " - and by calling process , not by running QProcess ?Here is my code which should have a QStringList result of several lines and which get nothing...
QProcess *QP = new QProcess();
qDebug() << "DEBUG TRACE start new QProcess();";
if(!QP->execute(command))
{
// QP->waitForReadyRead(); execute waited
// QByteArray a = QP->readAllStandardOutput();
QStringList out = QString(QP->readAllStandardOutput()).split("\n");
qDebug() << "START DEBUG OUTPUT library " << out;
qDebug() << "END DEBUG OUTPUT library "; // << out;
return out;
}
else
{
qDebug() <<"FAILED QP->execute(command)";
}Here is my app debut output
Note no data between
START DEBUG OUTPUT library ("")
END DEBUG OUTPUT libraryWarning: Ignoring XDG_SESSION_TYPE=wayland on Gnome. Use QT_QPA_PLATFORM=wayland to run on Wayland anyway. QStringList BT_Utility_Library::ProcessCommand_TEST(QString) DEBUG TRACE start new QProcess(); QIODevice::read (QProcess): device not open START DEBUG OUTPUT library ("") END DEBUG OUTPUT library ("") QStringList BT_Utility_Library::ProcessCommand_TEST(QString) DEBUG TRACE start new QProcess(); ● bluetooth.service - Bluetooth service Loaded: loaded (/lib/systemd/system/bluetooth.service; disabled; vendor preset: enabled) Active: active (running) since Fri 2023-01-20 07:05:19 CST; 3h 2min ago Docs: man:bluetoothd(8) Main PID: 5845 (bluetoothd) Status: "Running" Tasks: 1 (limit: 9098) Memory: 2.1M CPU: 275ms CGroup: /system.slice/bluetooth.service └─5845 /usr/lib/bluetooth/bluetoothd Jan 20 07:05:20 nov251-desktop bluetoothd[5845]: Endpoint registered: sender=:1.43 path=/MediaEndpoint/A2DPSink/sbc_xq_552 Jan 20 07:05:20 nov251-desktop bluetoothd[5845]: Endpoint registered: sender=:1.43 path=/MediaEndpoint/A2DPSource/sbc_xq_552 Jan 20 07:05:20 nov251-desktop bluetoothd[5845]: Endpoint registered: sender=:1.43 path=/MediaEndpoint/A2DPSink/sbc Jan 20 07:05:20 nov251-desktop bluetoothd[5845]: Endpoint registered: sender=:1.43 path=/MediaEndpoint/A2DPSource/sbc Jan 20 07:05:20 nov251-desktop bluetoothd[5845]: Endpoint registered: sender=:1.43 path=/MediaEndpoint/A2DPSink/sbc_xq_453 Jan 20 07:05:20 nov251-desktop bluetoothd[5845]: Endpoint registered: sender=:1.43 path=/MediaEndpoint/A2DPSource/sbc_xq_453 Jan 20 07:05:20 nov251-desktop bluetoothd[5845]: Endpoint registered: sender=:1.43 path=/MediaEndpoint/A2DPSink/sbc_xq_512 Jan 20 07:05:20 nov251-desktop bluetoothd[5845]: Endpoint registered: sender=:1.43 path=/MediaEndpoint/A2DPSource/sbc_xq_512 Jan 20 07:05:20 nov251-desktop bluetoothd[5845]: Endpoint registered: sender=:1.43 path=/MediaEndpoint/A2DPSink/sbc_xq_552 Jan 20 07:05:20 nov251-desktop bluetoothd[5845]: Endpoint registered: sender=:1.43 path=/MediaEndpoint/A2DPSource/sbc_xq_552 QIODevice::read (QProcess): device not open START DEBUG OUTPUT library ("") END DEBUG OUTPUT library ("") sudo: a terminal is required to read the password; either use the -S option to read from standard input or configure an askpass helper sudo: a password is required ● bluetooth.service - Bluetooth service Loaded: loaded (/lib/systemd/system/bluetooth.service; disabled; vendor preset: enabled) Active: active (running) since Fri 2023-01-20 07:05:19 CST; 3h 2min ago Docs: man:bluetoothd(8) Main PID: 5845 (bluetoothd) Status: "Running" Tasks: 1 (limit: 9098) Memory: 2.1M CPU: 275ms CGroup: /system.slice/bluetooth.service └─5845 /usr/lib/bluetooth/bluetoothd Jan 20 07:05:20 nov251-desktop bluetoothd[5845]: Endpoint registered: sender=:1.43 path=/MediaEndpoint/A2DPSink/sbc_xq_552 Jan 20 07:05:20 nov251-desktop bluetoothd[5845]: Endpoint registered: sender=:1.43 path=/MediaEndpoint/A2DPSource/sbc_xq_552 Jan 20 07:05:20 nov251-desktop bluetoothd[5845]: Endpoint registered: sender=:1.43 path=/MediaEndpoint/A2DPSink/sbc Jan 20 07:05:20 nov251-desktop bluetoothd[5845]: Endpoint registered: sender=:1.43 path=/MediaEndpoint/A2DPSource/sbc Jan 20 07:05:20 nov251-desktop bluetoothd[5845]: Endpoint registered: sender=:1.43 path=/MediaEndpoint/A2DPSink/sbc_xq_453 Jan 20 07:05:20 nov251-desktop bluetoothd[5845]: Endpoint registered: sender=:1.43 path=/MediaEndpoint/A2DPSource/sbc_xq_453 Jan 20 07:05:20 nov251-desktop bluetoothd[5845]: Endpoint registered: sender=:1.43 path=/MediaEndpoint/A2DPSink/sbc_xq_512 Jan 20 07:05:20 nov251-desktop bluetoothd[5845]: Endpoint registered: sender=:1.43 path=/MediaEndpoint/A2DPSource/sbc_xq_512 Jan 20 07:05:20 nov251-desktop bluetoothd[5845]: Endpoint registered: sender=:1.43 path=/MediaEndpoint/A2DPSink/sbc_xq_552 Jan 20 07:05:20 nov251-desktop bluetoothd[5845]: Endpoint registered: sender=:1.43 path=/MediaEndpoint/A2DPSource/sbc_xq_552 "systemctl status bluetooth" 10:08:04: /mnt/07b7c3f8-0efb-45ab-8df8-2a468771de1f/PROJECTS/BT_JAN19_/CCC_SOURCE/btchat/btchat exited with code 0
-
@AnneRanch said in ....forwarded to the calling process.??:
if I use "non static" QProcess - how do I read the "data passed to calling process " - and by calling process , not by running QProcess ?
By executing readAllStandardOutput()/readAllStandardError() or connecting the appropriate signals as already told you many times...
-
@AnneRanch said in ....forwarded to the calling process.??:
if(!QP->execute(command))
int QProcess::execute(const QString &program, const QStringList &arguments = {}) is
static
. That is vital.QP->execute(command)
does not run the execute on yourQProcess *QP = new QProcess()
instance (even though it reads as though it does). You will not be able to do anyQP->read...()
this way. Hence in the output errorQIODevice::read (QProcess): device not open
You cannot use
QProcess::execute()
if you want to be able to read its output viaQProcess::read...()
. It is a convenience method which runs a command and waits for it to finish for you. You will want to useQProcess::start()
, for youQP->start(...)
. -
@JonB RTFM??
nt QProcess::execute(const QString &program, const QStringList &arguments)
Starts the program program with the arguments arguments in a new process, waits for it to finish, and then returns the exit code of the process. Any data the new process writes to the console is forwarded to the calling process. -
@AnneRanch said in ....forwarded to the calling process.??:
@ChrisW67 No.. I do not "insist" - just happens to find a different way to run QProcess.
Anything wrong with that ?Nothing, it is fit for fire-and-forget execution of commands where the output is minimal or not used. Since you want the output of the child process in a manageable form the static method is less useful.
So
if I use "non static" QProcess - how do I read the "data passed to calling process " - and by calling process , not by running QProcess ?Here is my code which should have a QStringList result of several lines and which get nothing...
Here is your code with appropriate formatting for the forum.
QProcess *QP = new QProcess(); qDebug() << "DEBUG TRACE start new QProcess();"; if(!QP->execute(command)) { // QP->waitForReadyRead(); execute waited // QByteArray a = QP->readAllStandardOutput(); QStringList out = QString(QP->readAllStandardOutput()).split("\n"); qDebug() << "START DEBUG OUTPUT library " << out; qDebug() << "END DEBUG OUTPUT library "; // << out; return out; } else { qDebug() <<"FAILED QP->execute(command)"; }
QProcess::execute() is a static function as @JonB points out.
Here is my example code written to not use the QProcess static convenience function and return the output in a string.
#include <QCoreApplication> #include <QProcess> #include <QDebug> int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); // Synchronous use of QProcess without using static functions. // Only good for short-running processes. QProcess proc; proc.setProgram("date"); proc.setArguments(QStringList() << "-u"); proc.start(); if (proc.waitForFinished(30000)) { qDebug() << "Finished"; if (proc.exitStatus() == QProcess::NormalExit) { qDebug() << "Normal exit" << proc.exitCode(); int result = proc.exitCode(); if (result == 0) { QString output = proc.readAllStandardOutput(); qDebug() << output; } else { qDebug() << "Failed with exit code" << result; qDebug() << proc.readAllStandardError(); } } } else { qDebug() << "Timed out"; } return a.exec(); }
-
@AnneRanch said in ....forwarded to the calling process.??:
@JonB RTFM??
I beg your pardon?
I explained it is a
static
function. I explained it means that writingQP->execute()
does not openQP
, and that is why your output showsQIODevice::read (QProcess): device not open
error.
For your purpose here it is much simpler to use
QProcess::start()
.QProcess::execute()
offers you no advantage over that, only makes life harder. Up to you. Earlier on @ChrisW67 showed code if you really want to useexecute()
[though I have to say, I did not find it worked correctly at least in Qt 5.15, Ubuntu], his later post shows usingstart()
. Also withexecute()
you will never have the option of being able to connect signals. -
@JonB before somebody posts another example how to modify a+b to b+a
kindly please provide reference to correct this official QT document when STATIC is implemented .RTFM and note that "execute" is referenced under "static".
nt QProcess::execute(const QString &program, const QStringList &arguments)
Starts the program program with the arguments arguments in a new process, waits for it to finish, and then returns the exit code of the process. Any data the new process writes to the console is forwarded to the calling process.To the contributors whose code "waits for finish " - please note the above highlighted part.
I appreciate all constructive contributions, however, somehow the original post OBJECTIVE to discuss how data is forwarded to calling process is being masked by usual personal innuendos ( format your code ,,, we told you so ... etc) .
PLEASE stop that. -
@AnneRanch said in ....forwarded to the calling process.??:
how data is forwarded to calling process
What exactly do you want to know here? How it's done internally so you can read it with the functions fomr QProcess? If not - what else?
-
@AnneRanch said in ....forwarded to the calling process.??:
kindly please provide reference to correct this official QT document when STATIC is implemented .
Kindly note that I did precisely that in the post you are asking about
int QProcess::execute(const QString &program, const QStringList &arguments = {}) is
static
That's what I wrote. It has the link to the documentation. Is that what you wanted that you're not happy with? Or something else?
RTFM and note that "execute" is referenced under "static".
I do "RTFM", thank you very much.
- If you use
QProcess::execute()
you will find it difficult to get any output correctly/reliably. IMHO. - If you use
QProcess::start()
plus some kind ofQProcess::waitForFinished()
you will be able to useQProcess::read...()
to read the output from the spawned process.
Why not just try saying "thank you"? That would be really nice. Or something without the "F" in it when people try to help you?
- If you use
-
I LIKE TO KNOW WHY THIS DOES NOT WORK WHEN USED A STATIC.....
'WHERE DOES IT SAY THAT IN THIS SNIPPET OF OFFICIAL DOCUMENTATION
?????
?
/
PLEASE
no more personal remarks / opinions why it should not be used as STATIC .....
'
PLEASE
pay attention to highlighted part which was the original subject if my post and is continually derailed by opinions....int QProcess::execute(const QString &program, const QStringList &arguments = {})
Starts the program program with the arguments arguments in a new process, waits for it to finish, and then returns the exit code of the process. Any data the new process writes to the console is forwarded to the calling process.
The environment and working directory are inherited from the calling process.
Argument handling is identical to the respective start() overload.
If the process cannot be started, -2 is returned. If the process crashes, -1 is returned. Otherwise, the process' exit code is returned.
See also start().
-
@AnneRanch said in ....forwarded to the calling process.??:
no more personal remarks / opinions why it should not be used as STATIC .....
When you write:
QProcess *QP = new QProcess(); QP->execute(command); qDebug() << QP->readAllStandardOutput();
it won't work because
QProcess::execute()
is astatic
method. You will get nothing back, and an error message from the last line saying theQProcess
is not open. Astatic
method does not operate on any instance you happen to call it on. The code above is really:QProcess *QP = new QProcess(); QProcess::execute(command); qDebug() << QP->readAllStandardOutput();
You can see the
QP
instance has not been used to open or execute the command. You cannot read from it.QProcess::execute()
has its own internalQProcess
instance it creates and destroys, you cannot access it.That is how
static
class methods work in C++. -
As mentioned above using a static method means you don't get an instance of the class that you can use non-static methods on. That means if you run
QProcess::execute
it internally creates a QProcess instance that you don't get access to. This means you can't useQProcess::readAllStandardOutput
because that is not a static method and you don't have access to an instance you can call it on. If you create another instance they don't share the output.Calling static method on a non-static object (so
QP->execute
) is just something that C++ lets you do, but it's just syntax sugar over static call and it has nothing to do with the QP instance. Those are not QProcess or Qt topics. That's just how static functions work in C++.All that doesn't mean documentation is wrong. With the static
QProcess::execute
a stream forwarding is used, meaning that if the subprocess writes to the output, e.g. withstd::cout << "hello"
the calling process catches it and puts it into its own output stream, so you will see it in the output stream of the calling process. If you want to catch it to, for example, put it in a textbox or something, you can do it but it's quite complicated.
First you need to do standard cout and cerr stream redirection. I'm not gonna go into detail because there's enough materials out there and it's not Qt specific topic.
Second, becauseQProcess::execute
is a blocking call you probably will have to start another thread to read that output in realtime, or better yet start thatQProcess::execute
in another thread so it doesn't block your UI.
Third, even if you redirect cout to some sort of handler of yours that subprocess output will be mixed with that of the calling process and you'll have to do some parsing to differentiate which part of the output is from which process.So that being said static
QProcess::execute
is not a good choice for the task of reading the output of the called process. It can be done if someone is stubborn enough, but it requires a lot of pointless work that can be replaced with just a few lines of creating a QProcess instance, callingstart
,waitForFinished
andreadAllStandardOutput
.QProcess::execute
is a convenience shortcut for cases when you don't need to interact with the process you're calling.The documentation is ok, just doesn't go into details where the streams are redirected, because it's not really meant to be used this way. If you want then you have to do some digging on stream redirection yourself, but that's really self inflicted pain that is not necessary.
-
Life is too short. Once again we have the "I'll delete all my posts" response.
-
@ChrisW67 Long time ago I posted a reply on a similar toplc and got a toxic answer.
Once bitten twice shy... -
Life is too short. Once again we have the "I'll delete all my posts" response.
Wow, who would be so rude/ungrateful after everybody has posted so much in response trying to help as to delete all their posts?!
Long time ago I posted a reply on a similar toplc and got a toxic answer.
Once bitten twice shy...You are right! I keep forgetting this, thinking it will be better and would be nice to help someone. I need to take the "bitten" ["mauled"? ;-) ] lesson to heart!
-
I've restored them so we can refer to them when the same question is asked in two weeks again.