HOWTO implement a batch process that displays status via a QMainWindow? [Solved]



  • What is the correct way to create a batch process that displays the status in a QMainWindow? There is an 'engine' class that will do all the work, then there is a custom QMainWindow that will be along the lines of QProgressDialog, except it will display a bit more status on what is happening.

    Since there is going to be a GUI, it is assumed that QCoreApplication::exec() needs to be called once the QMainWindow has been created. The question is: how does the engine get started automatically? Should it be running in a background thread that is started before calling QCoreApplication::exec() and then have it close down the QMainWindow to have QCoreApplication::exec() return?

    Any other suggestions?

    Sam


  • Lifetime Qt Champion

    Hi,

    I am not sure I am following you right. Do you have a script/process started on the command line that you would like to make a GUI for ? (i.e mplayer) or do you have a working object ("engine class") that you would like to use and make a GUI for it ?



  • It is my "Sales Center" for a photography sales system. Under normal usage, users will click on a button in another program to launch the Sales Center where the user can find a customer's order, bring up the order on the screen, tweek the order, add details, etc. Finally allow the user to copy over the images ordered and print the invoice.

    My users want to fast track things and have an option such that from the first program, you click on a button and it launches the Sales Center in a mode that it automatically copies over all the images for all the orders that are ready to be copied, and then to print the invoices for them.

    I could do all this in the background, but depending on how many orders there are, it could take a bit of time. So I would like to display a GUI that shows two progress bars, one for the number of orders and the second for the number of images per order that need to be copied. When all is said and done, the GUI and the program in general should go away.

    Does that shed some light on what I am doing?


  • Lifetime Qt Champion

    Yes it does. So you would need a QProcess that would run your Sales Center (which is a command line application if I understood you correctly) and parse the output of that process to give a feedback to your user. Does you Sales Center application end by itself when everything is done ?



  • Well, the Sales Center is not normally a command line application, it is normally a GUI app, but when it is launched with the correct command line arguments, it will run as a batch process.

    Rather than outputting to a console, I want to pop up a GUI that will display status. When the batch process is done, it should close the GUI and exit the whole process.

    In traditional Windows programming, I would simply pop up the GUI and then on a timer start the background batch process that would signal to the GUI the status and then close the GUI/process when completed.

    I know that I could do that with Qt, too, but I have a feeling there is a better way of doing it:)

    Sam


  • Lifetime Qt Champion

    Then why not just add that GUI for the batch mode in Sales Center ? Thus you won't have to parse anything or manage the lifetime of the widgets from an external process



  • There IS only one program, the SalesCenter. In main(), it determines the mode that it needs to run in, normal or batch, and goes from there.

    In normal mode it creates the standard QMainWindow and does it's thing.

    The question is how best to implement the batch mode:

    Option 1: create the batch's QMainWindow that in the constructor creates the QProcess that will do the batch processing. Wire up signals and slots so the QProcess can send status to the QMainWindow. This is basically what I would do in standard Windows programming.

    My hangup with option 1 is that the QMainWindow is in control and knows about the QProcess. I would prefer that the GUI does NOT have any knowledge of the batch process that is going on, which is the design of QProgressDialog. QProgressDialog knows NOTHING of what is actually running, it is completely disconnected from the task that is running. The problem is that QProgressDialog needs QCoreApplication::exec() to be called so that the message loop is running.

    Option 2: ???? implement a disconnected approach similar to QProgressDialog, but I don't even begin to know how to go about doing that in Qt.

    I can do option 1, I just prefer cleaner designs, when I can:)


  • Lifetime Qt Champion

    Since you start SalesCenter anyway, what I was proposing was a completely different (and simplified for that matter) GUI that would start the QProcess, parse the output to update a QProgressBar.

    You control which GUI to show in your main.cpp



  • What you suggest is simply a modification of my first option. For the record, I want to show two progresses, one for each order but then a sub progress showing the progress of each order.

    My goal though is NOT to show the main GUI, there is no need for it, besides, I run into the same issue: A GUI knows details about the batch process. There is no reason any GUI should need to know about the batch process, the GUI should simply reflect the signals it is getting from slots.

    The ultimate goal, if possible, is to have the QProcess in the driver seat, not a GUI. Is my impression correct that my ultimate goal is not possible with Qt? It is in the WinSDK and .Net world, so I am assuming it is also possible in the Qt world:)

    For what it is worth, here is .Net's example of using it's ApplicationContext class to control things outside of a GUI:

    http://msdn.microsoft.com/en-us/library/system.windows.forms.applicationcontext.aspx


  • Lifetime Qt Champion

    I am not suggesting to show the main GUI at all. If I have followed you right, you have somewhere an object that prepares the batch, then execute the orders one after the other, and each of these order run will provide some report while running. Am I right ?

    If so you will need to parse the output of your process (through QProcess) and from that parsing you'll emit the status update you want to report to your GUI and once the batch is completed you just call qApp->exit() and you're done.

    My basic idea is:
    @
    int main(int argc, char *argv[])
    {
    QApplication app(argc, argv);

    if (runBatchMode) {
      BatchRunner br; // <- where you run your QProcesses
      BatchGUI bg;
      connect(&br, SIGNAL(batchProgress(int), &bg, SLOT(setBatchProgress(int))); 
    

    connect(&br, SIGNAL(orderProgress(int), &bg, SLOT(setOrderProgress(int)));
    connect(&br, SIGNAL(batchDone()), qApp, SLOT(exit()));
    br.runBatch();
    bg.show();
    } else {
    MainWindow mw;
    mw.show();
    }

    return app.exec();
    }
    @

    Does it follow yours ?



  • Sorry for the long absence, that looks like exactly what I am looking for/thinking about. Thank you!


  • Lifetime Qt Champion

    You're welcome !

    If this answer your question, don't forget to update the thread title prepending [solved] so other forum users may know a solution has been found :)


Log in to reply
 

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