Results 1 to 7 of 7

Thread: Wrapping Command Line Application in a Qt GUI?

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Join Date
    Mar 2016
    Posts
    4
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Wrapping Command Line Application in a Qt GUI?

    You mean the console app can only be run once?
    Yes there can only be a single console app and each window in the GUI will send\recv messages to the command-line app. The console app lifetime will be the duration of the GUI application. Imagine that there are 4 windows in the GUI app: A, B, C, D. If window A requests data it should only come back to window A and not other windows. In theory I wanted to be able to write something like this for each of the functions:

    Qt Code:
    1. // psuedo code
    2. ::GetTradeData( QString* output )
    3. {
    4. QProcess()->write("GetTradeData\n"); // send a command to the console app
    5. QProcess()->read(output); // read it's response and return it to the caller
    6. }
    To copy to clipboard, switch view to plain text mode 

    Sending requests to the command application seems to work great: each window can send data to the command line app via the QProcess()->write() method. Unfortunately QProcess()->read() seems to never return a buffer. I'm not sure if this is because 1) the race condition between the console application outputting data and the GUI calling read() or 2) all command line output is going to the function that I have connected the signals and slots to:

    Qt Code:
    1. connect(myCommandLineApp, SIGNAL(readyReadStandardOutput()), this, SLOT(recvCommandOutput()));
    2. connect(myCommandLineApp, SIGNAL(readyReadStandardError()), this, SLOT(recvCommandErrorOutput()));
    To copy to clipboard, switch view to plain text mode 

    That code works great for the asychronous output that's sometimes outputted by the console app.

    Not sure what you mean with polling.

    QProcess is, and likely any other backend you might implement will be, asynchronous, so there is not and likely won't be any reason for polling.
    Here's where I'm stumped. Because I never received output from the QProcess()->read() call I instead had recvCommandOutput() insert results into a results data structure. The results output have a transaction ID that I can set when I make my query. I then attempted to poll on the results data structure like so looking for my transaction ID:

    Qt Code:
    1. // psuedo code
    2. ::GetTradeData( QString* output )
    3. {
    4. QProcess()->write(transactionId + "GetTradeData\n"); // send a command to the console app
    5.  
    6. do{
    7.  
    8. results = CheckForResults( transactionId );
    9.  
    10. }while( results == NULL)
    11.  
    12. }
    To copy to clipboard, switch view to plain text mode 

    The issue with this is that the polling will loop forever. recvCommandOutput() is never hit once I start looping. Again I believe this is because I have a single MainWindow thread.

    Reading between the lines in both of your messages I now believe I am making a mistake in attempting to make the asychronous calls appear sychronous to the GUI. While it would make the GUI code easier to write I feel like I will run into issues in the future.

    While I understand that you are not currently using direct networking the QNetworkAccessManager and QNetworkReply provides a reasonable example of one way to handle separation of responses. When given a request the (typically single) QNetworkAccessManager (StockQuote) immediately returns a QNetworkReply (IStockQuoteReply with concrete subclasses StockQuoteReply, StockVolumeReply perhaps) that you connect to the handlers that should deal with the reply. The reply object is the one that issues the various signals related to the request that created it. In this way you avoid having all replies go to a single place that must then separate them.
    Yes, the more I think about it this is the correct way to go. Do you know if there is something similar for command line app output? Also, how would you handle the case where there are multiple StockQuote and StockVolume windows open? Again only one window should receive the output.

    Thank you both for all your help. I'm beginning to get an idea for what I have to write.

  2. #2
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Wrapping Command Line Application in a Qt GUI?

    Quote Originally Posted by soupfly View Post
    In theory I wanted to be able to write something like this for each of the functions:
    That does not really fit your application.
    Your current backend is already asynchronous and any future backend has a likely chance of also being asynchronous (e.g. network based).
    As a GUI you are not in a situation where you can just block and wait for response, that would result in bad user experience.

    Quote Originally Posted by soupfly View Post
    Unfortunately QProcess()->read() seems to never return a buffer.
    It will if there is something to return.
    Which is not likely in the pseudo code above since that would require that the data has been written to the child process, then your process having been suspended long enough for the child to process and write back before your program has had a chance to resume and call read.

    Not impossible, but highly unlikely.


    Quote Originally Posted by soupfly View Post
    Because I never received output from the QProcess()->read() call I instead had recvCommandOutput() insert results into a results data structure. The results output have a transaction ID that I can set when I make my query
    Good, that is what I meant with making request and response associated to each other.

    Quote Originally Posted by soupfly View Post
    The issue with this is that the polling will loop forever. recvCommandOutput() is never hit once I start looping. Again I believe this is because I have a single MainWindow thread.
    It is less a matter of having a single thread but exclusively using the single thread for one purpose (looping) so it can't do anything else (like processing events for QProcess).
    Basically you've deadlocked yourself.

    Quote Originally Posted by soupfly View Post
    Reading between the lines in both of your messages I now believe I am making a mistake in attempting to make the asychronous calls appear sychronous to the GUI.
    Definitely. A GUI should never assume that I/O is instantaneous, especially nothing that will require communication with a different system (via network, cable, etc).
    It is very rare that such communication has deterministic and guaranteed response times that would make blocking the UI a viable approach.

    Luckily most I/O in Qt is handled asynchronously so you don't have to do anything special (e.g. threads) to make it non-blocking.

    Quote Originally Posted by soupfly View Post
    Do you know if there is something similar for command line app output?
    No, as application output is very application specific, i.e. how the application separates output of different responses, etc.

    Quote Originally Posted by soupfly View Post
    Also, how would you handle the case where there are multiple StockQuote and StockVolume windows open?
    The window just needs to know which StockQuote object to work with.
    In the QNAM example it would just need to know which QNAM to work with.

    Quote Originally Posted by soupfly View Post
    Again only one window should receive the output.
    Since you can associate responses to requests, you just need to pick the right "reply" handler to pass it to, like QNAM knows which QNetworkReply to pass incoming response data to.
    Each window only knows its reply object, so it won't be confused by other windows' data.

    Cheers,
    _

Similar Threads

  1. Replies: 3
    Last Post: 9th March 2011, 12:52
  2. Replies: 32
    Last Post: 29th January 2011, 22:14
  3. Replies: 1
    Last Post: 7th September 2010, 15:49
  4. Replies: 3
    Last Post: 23rd February 2010, 04:33
  5. Retrieving command line arguments inside a Qt application
    By prykHetQuo in forum Qt Programming
    Replies: 5
    Last Post: 14th February 2009, 14:28

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Qt is a trademark of The Qt Company.