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?


  • Moderators

    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();
        }
    };

  • Lifetime Qt Champion

    Hi,

    Where is that ver application located ?



  • @SGaist

    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:

    0_1521579698036_eb72349f-68c7-4830-8eae-aa9c675f4edb-image.png

    Thanks for you help folks!


  • Lifetime Qt Champion

    Then you may have to call cmd.exe to execute the command if it's a builtin on windows.



  • @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!


  • Moderators

    @bockscaracer Even on Linux not everything is a separate executable, see https://www.gnu.org/software/bash/manual/html_node/Bash-Builtins.html



  • @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 via cmd /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 via cmd /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).


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.