Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QProcess - unexpected behaviour with execute()
QtWS25 Last Chance

QProcess - unexpected behaviour with execute()

Scheduled Pinned Locked Moved General and Desktop
11 Posts 2 Posters 3.1k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • R Offline
    R Offline
    Robbin
    wrote on last edited by
    #1

    Hello everyone,

    I am facing a very strange problem.
    I am trying to execute external program using QProcess, but QProcess::start() returns wrong result and QProcess::execute() returns the result in a way which cannot be captured.

    What I am doing is a Linux console application which will be working with long lines of text. I want to be able to cut the text at the end of each line, thus showing one result per line. In order to do this, I need to get the size of the terminal window. I don't know and I couldn't find better ways to do that then to use "tput":http://en.wikipedia.org/wiki/Tput

    I tried having QProcess both on the stack and on the heap, using both start and execute. Here is what I am currently trying:

    In the constructor:

    @
    proc = new QProcess(this);
    proc->setProcessChannelMode(QProcess::MergedChannels);
    proc->setEnvironment(QProcess::systemEnvironment());

    connect( proc, SIGNAL(stateChanged(QProcess::ProcessState)), this, SLOT(stateChanged(QProcess::ProcessState)));
    

    @

    and then later in the execution:
    @
    proc->execute("tput cols");
    connect( proc, SIGNAL(readyReadStandardOutput()), this, SLOT(readyReadScreenWidth()));
    proc->waitForFinished(-1);
    proc->close();
    disconnect( proc, SIGNAL(readyReadStandardOutput()), this, SLOT(readyReadScreenWidth()));
    @

    I am using disconnect because I am using the same QProcess object for the height as well, which looks pretty much the same. I know I could use the QObject::sender() method, but I don't think that's the problem.

    @
    void base::readyReadScreenWidth()
    {
    QByteArray data = proc->readAllStandardOutput();
    qDebug() << "width:" << data;
    width = data.trimmed().toInt();
    }
    @

    Now, the strange thing is - when I use execute, it returns the correct resolution of the terminal window, however it just spits it out in the terminal, not comming on the object "proc" stdout or stderr. If I use the start method instead, the result I get is wrong - even if I resize the window, it'll keep showing me width 80 and height 24.

    I am currently compiling on a CentOS 5.4 virtual machine because I want to avoid compatibility issues if I need to run my application on different boxes (and I know for sure that the oldest one which I will need to run this on is a CentOS 5.4 box). I am using Qt 4.8.6, however the same QProcess code resides in 5.3.2 as well.

    What I mean is the following, located in qprocess.cpp in the sources:
    @
    int QProcess::execute(const QString &program, const QStringList &arguments)
    {
    QProcess process;
    process.setReadChannelMode(ForwardedChannels);
    process.start(program, arguments);
    if (!process.waitForFinished(-1))
    return -2;
    return process.exitStatus() == QProcess::NormalExit ? process.exitCode() : -1;
    }
    @

    What that method does is creating another instance of the class QProcess to which it passes the program name and arguments and sets that stderr and stdout are merged and sent to it. It waits for the process to finish, but does NOT take care of the output. At the end of the method, that instance just goes out of scope and thus destroyed. And that is why I get the output to the terminal, but not back in my application. I don't know if that is intended behaviour, but it certainly is not helpful....

    I am puzzled as to why using start() returns 80x24 as well, I can only imagine that this geometry is somehow hard coded (as a default size for terminal applications?). Can someone more into Qt confirm please?

    Can someone tell me if there is any bether way of doing what I am trying to achieve? I would like to use the Qt way of doing things, don't want to resort to pure c/c++ methods like popen.

    1 Reply Last reply
    0
    • R Offline
      R Offline
      Robbin
      wrote on last edited by
      #2

      Seriously guys, did nobody had such problem before??
      It's quite weird....

      1 Reply Last reply
      0
      • SGaistS Offline
        SGaistS Offline
        SGaist
        Lifetime Qt Champion
        wrote on last edited by
        #3

        Hi,

        It's not really hardcoded (in a sense), it's the default used by your system (technically for all *nix 80x24). If you change it, you should see the new value instead.

        Interested in AI ? www.idiap.ch
        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

        1 Reply Last reply
        0
        • R Offline
          R Offline
          Robbin
          wrote on last edited by
          #4

          Hi and thanks for the response.

          Indeed I didn't thought that probably these numbers are the defaults for the linux boxes. 80x24 seems pretty low nowdays, not sure why would linux devs keep going at it. Still, as I mentioned in my post, execute() cannot be used as it returns the exit status only and start() returns wrong result, at least within my project and test case.
          I couldn't find a workaround, so I ended up using "popen" instead, but I would really like to use QProcess or whatever else may be relevant and considered to be the Qt way.

          If you can see a flaw in what I tried, or if you can suggest another way of actually clearing the screen in a console application, I would be most grateful. My project is pretty much on hold for now with one of the reasons being the problem with clearing the screen (which also flickers during these updates, so I can't do them too often :( )

          1 Reply Last reply
          0
          • SGaistS Offline
            SGaistS Offline
            SGaist
            Lifetime Qt Champion
            wrote on last edited by
            #5

            Maybe low, but compatible with current and older devices and also if you don't have a graphic server. And don't forget python :)

            Anyway, can you explain what your application should exactly do ?

            Interested in AI ? www.idiap.ch
            Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

            1 Reply Last reply
            0
            • R Offline
              R Offline
              Robbin
              wrote on last edited by
              #6

              I am trying to build an application which updates the screen every second (or twice every second) with information which it reads from a resource - file, socket, anything. Pretty much sort of a monitoring of live stats (like mytop, (h)top, etc). What I couldn't do is clear the screen in a way it wouldn't flicker and also get the size of the terminal. What I used is the linux "tput" command and was trying to execute it with QProcess::execute or QProcess::start.

              Is there anything in Qt which I couldn't find that would provide me with information about the terminal size and also is there anything in Qt which would allow me to clear the terminal without executing external application? If not, how can I do this with QProcess, since it doesn't work correctly, as I described in my first post.

              1 Reply Last reply
              0
              • R Offline
                R Offline
                Robbin
                wrote on last edited by
                #7

                I am trying to build an application which updates the screen every second (or twice every second) with information which it reads from a resource - file, socket, anything. Pretty much sort of a monitoring of live stats (like mytop, (h)top, etc). What I couldn't do is clear the screen in a way it wouldn't flicker and also get the size of the terminal. What I used is the linux "tput" command and was trying to execute it with QProcess::execute or QProcess::start.

                Is there anything in Qt which I couldn't find that would provide me with information about the terminal size and also is there anything in Qt which would allow me to clear the terminal without executing external application? If not, how can I do this with QProcess, since it doesn't work correctly, as I described in my first post.

                1 Reply Last reply
                0
                • SGaistS Offline
                  SGaistS Offline
                  SGaist
                  Lifetime Qt Champion
                  wrote on last edited by
                  #8

                  Something 's not clear, is it a console application (QCoreApplication) Or do you want to show your content in a console from your GUI ?

                  Interested in AI ? www.idiap.ch
                  Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                  1 Reply Last reply
                  0
                  • SGaistS Offline
                    SGaistS Offline
                    SGaist
                    Lifetime Qt Champion
                    wrote on last edited by
                    #9

                    Something 's not clear, is it a console application (QCoreApplication) Or do you want to show your content in a console from your GUI ?

                    Interested in AI ? www.idiap.ch
                    Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                    1 Reply Last reply
                    0
                    • R Offline
                      R Offline
                      Robbin
                      wrote on last edited by
                      #10

                      Ugh, sorry for the late response, been busy with work and didn't do much about that project.

                      Yes, it's a QCoreApplication, it's application which is supposed to output stuff into the terminal once started. What I am trying to do is call external application to clean the terminal window of previous text and replace it with new one. Was just surprised by QProcess behaviour and was looking for a more Qt way then using popen(). When I use the external application (called "tput"), I kind of get the behaviour I want, but it gives it sort of a flickering, which makes me think what I use is not quite optimal.....

                      1 Reply Last reply
                      0
                      • R Offline
                        R Offline
                        Robbin
                        wrote on last edited by
                        #11

                        Ugh, sorry for the late response, been busy with work and didn't do much about that project.

                        Yes, it's a QCoreApplication, it's application which is supposed to output stuff into the terminal once started. What I am trying to do is call external application to clean the terminal window of previous text and replace it with new one. Was just surprised by QProcess behaviour and was looking for a more Qt way then using popen(). When I use the external application (called "tput"), I kind of get the behaviour I want, but it gives it sort of a flickering, which makes me think what I use is not quite optimal.....

                        1 Reply Last reply
                        0

                        • Login

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • Users
                        • Groups
                        • Search
                        • Get Qt Extensions
                        • Unsolved