onReadyRead attribute does not function the same on Windows as Linux
-
I have a very simple application that basically runs an application via QProcess and returns the result. My Process class is of course written in C++ and is/has Q_INVOKABLE so that my QML can call the function and read the result.
On Linux, I call the simple application "fortune-mod" to return a silly fortune to my front-end QML app. My QML code looks like this:
Process { id: process onReadyRead: text_field.text = "You are running:\n" + readAll(); }
Like I say, on Linux this works fine, however on Windows, the "onReadyRead" simply isn't evaluated or called at all. And as you can imagine, if onReadyRead isn't called, my readAll() functional isn't called either.
Why is Windows behaving differently here? Is there a different function I need to call for Windows?
-
Show us the code of Process & tell how are you using it on Windows. There is no "fortune-mod" on Windows, so if you're attempting to call it, then QProcess likely fails.
-
So I have a button with a connection. In the connect , I hook up the onClicked event to my process.start(), and then call the shell command. On Linux I'm calling fortune -s, but since fortune doesn't exist on Windows, I've tried various other commands such as time, date, and ver. My button and Connection looks like this:
Button { id: button x: 108 y: 173 text: qsTr("Button") font.pointSize: 8 } Connections { target: button onClicked: process.start("ver", [""]); }
The ver command on Windows prints the version and build number, which I would like to return to my QML gui. Interesting, if I change the process from "ver" to something like "git like this:
Connections { target: button onClicked: process.start("git", ["gui"]); }
It works as expected - the git gui is launched.
My process method is pretty straight forward, built from various examples I've found:
#include <QProcess> #include <QVariant> class Process : public QProcess { Q_OBJECT public: Process(QObject *parent = 0) : QProcess(parent) { } Q_INVOKABLE void start(const QString &program, const QVariantList &arguments) { QStringList args; for (int i = 0; i < arguments.length(); i++) args << arguments[i].toString(); QProcess::start(program, args); } Q_INVOKABLE QByteArray readAll() { return QProcess::readAll(); } };
-
Hi,
Where is that
ver
application located ? -
That's the question isn't it? I'm a native Linux user and I'm not terribly familiar with Windows. On Linux, nearly everything is an application located in /bin or /usr/bin. As such, fortune-mod is an application. On Windows, ver isn't an application, its some kind of system command built into batch or the cmd shell.
Either way, mode code is doing exactly what it should be. For example, when I change my connection to call an application located in my system path instead:
Connections { target: button onClicked: process.start("git", ["--version"]); }
My process behaves as expected:
Thanks for you help folks!
-
Then you may have to call
cmd.exe
to execute the command if it's a builtin on windows. -
That's the question isn't it? I'm a native Linux user and I'm not terribly familiar with Windows. On Linux, nearly everything is an application located in /bin or /usr/bin. As such, fortune-mod is an application. On Windows, ver isn't an application, its some kind of system command built into batch or the cmd shell.
Either way, mode code is doing exactly what it should be. For example, when I change my connection to call an application located in my system path instead:
Connections { target: button onClicked: process.start("git", ["--version"]); }
My process behaves as expected:
Thanks for you help folks!
@bockscaracer to add to what @SGaist says...
From the docs for QProcess, here. I think this applies in your case.
"Notes for Windows Users
Some Windows commands (for example, dir) are not provided by separate applications, but by the command interpreter itself. If you attempt to use QProcess to execute these commands directly, it won't work. One possible solution is to execute the command interpreter itself (cmd.exe on some Windows systems), and ask the interpreter to execute the desired command." -
@bockscaracer to add to what @SGaist says...
From the docs for QProcess, here. I think this applies in your case.
"Notes for Windows Users
Some Windows commands (for example, dir) are not provided by separate applications, but by the command interpreter itself. If you attempt to use QProcess to execute these commands directly, it won't work. One possible solution is to execute the command interpreter itself (cmd.exe on some Windows systems), and ask the interpreter to execute the desired command."@kenchan Yup it sure does. Thanks for this!
-
@kenchan Yup it sure does. Thanks for this!
@bockscaracer Even on Linux not everything is a separate executable, see https://www.gnu.org/software/bash/manual/html_node/Bash-Builtins.html
-
@kenchan Yup it sure does. Thanks for this!
@bockscaracer
Under Windoze, a list of "shell builtins" is available from e.g. https://blog.brainasoft.com/all-internal-commands-of-cmd/. If you use any of these you must go viacmd /c
. You can either:- Hard-code these (e.g. directly or via a "lookup" table); or
- Use
cmd /c
always, just in case.... (If you do this for commands with arguments, be careful about the quoting needed to go viacmd /c
.)
Under Linux, I find it hard to think of much which is built into
bash
and not available as a external executable that would be of interest to execute as a standalone command.Under both OSes, if you use things like redirection symbols (
<
,>
,|
), and some others, you must go via the shell (cmd /c
//bin/bash -c
).