Search code examples
qtpython-2.7pyqtqt4

Cleanly closing a qt Gui application application programatically


Hello I've been using PyQt 4.8 on windows to create a simple gui application. The gui(main window) has one button, and one QLineEdit widget. Pressing the button simply calls a function to process the contents of the QLineEdit widget. So far it works well. My main looks like this

class StartQt4App(QtGui.QMainWindow):

    def process_stuff(self,param):
        #Do stuff here


if __name__="__main__":
    app=QtGui.QApplications(sys.argv)
    myapplication=StartQt4App()
    myapplication.show()
    sys.exit(app.exec_())

Using py2exe I can create an windows executable e.g mygui_app.exe However I want to adapt it so that it can be run from the windows command line. i.e if the user types

Run mygui_app.exe "c:\text_file.txt"

The application launches, this time without the GUI and automatically processes the parameter that was entered when the application was called.

So far this is what I have come up with

class StartQt4App(QtGui.QMainWindow):

    def process_stuff(self,param):
        #Do stuff here

    def process_stuff_again(self,param):
        #Do stuff here
        return


if __name__="__main__":
    if len(sys.argv)==1:

        app=QtGui.QApplications(sys.argv)
        myapplication=StartQt4App()
        myapplication.show()
        sys.exit(app.exec_())
    else:
        app=QtGui.QApplications(sys.argv)
        myapplication=StartQt4App()
        myapplication.process_stuff_again(param)
        sys.exit(app.exec_())

Essentially if the application has been called with parameters I don't want/need to show the gui, simply call the processing function. Once processing is done exit cleanly

Currently it works, at least as far as processing the file goes. However it does not exit, once the processing is complete. Instead the program remains active (I can see it using the Windows Task Manager).

My question is how do I programatically quit the application? so that once done it cleanly shuts itself down.

I have experimented with

  • app.quit()
  • app.exit()
  • myapplication.exit()
  • myapplication.quit()

None work, essentially the application is still alive and kicking. In desperation I removed the

sys.exit(app.exec_())

from the else portion of the code and now it just crashes, as it it processes the file and then promptly crashes. Very consistently crashes.

Any suggestion as to how to cleanly get the application to close nicely when its called from the command line?


Solution

  • Not really familiar with PyQt, probably you're doing something wrong in your processing function which leads your app crashed.

    Also, in case you processing something synchronously, your

    app.quit()

    called before

    app.exec_()

    and doesn't have any effect because event loop (that started with app.exec_()) not started yet.

    If you still need to have event loop started before your processing function called (i.e. you're using event loop in your processing function), you can do a quirk like this (it's C++, I'm not familiar with PyQt):

    #include <QCoreApplication>
    #include <QTimer>
    #include <QDebug>
    
    class MyApp : public QObject
    {
        Q_OBJECT
    public slots:
        void process()
        {
            qDebug() << "Processing...";
            qDebug() << "Quit application...";
            qApp->quit();;
        }
    };
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
        MyApp myapp;
        QTimer::singleShot(0, &myapp, SLOT(process()));
        int rc = a.exec();
        qDebug() << "app finished with" << rc << "code";
    }
    
    #include "main.moc"
    

    Also, QMainWindow class doesn't have quit/exit methods (at least in C++).