30

i just asking myself how to restart my own qt application?

Can somebody please show me an example?

Piotr Dobrogost
  • 41,292
  • 40
  • 236
  • 366
Klaus
  • 301
  • 1
  • 3
  • 3

10 Answers10

60

To restart application, try:

#include <QApplication>
#include <QProcess>

...

// restart:
qApp->quit();
QProcess::startDetached(qApp->arguments()[0], qApp->arguments());
masoud
  • 55,379
  • 16
  • 141
  • 208
  • This worked great, except for the redundant first argument, so I edited the answer to remove the program name from the arguments list. Thanks! – Devan Williams Sep 27 '16 at 00:22
  • if you are inside a qt widget when calling qApp->quit() wouldn't the execution stop just right there resulting in the QProcess::startDEtached not being called? – Robson Apr 13 '18 at 07:18
  • Note that if `qApp->quit();` it will result in a mess that will likely crash the system, or at least force the user to hard restart it. In such cases, other methods that are guaranteed to terminate the process are recommended. – dtech May 23 '18 at 00:17
  • I would suggest to change second parameter to contain elements starting from the 2nd because otherwise the program name appears twice: QString program = qApp->arguments()[0]; QStringList arguments = qApp->arguments().mid(1); qApp->quit(); QProcess::startDetached(program, arguments); (see my answer version). – trig-ger Jun 22 '21 at 17:29
7

To restart a running Qt application (at least in Qt 5.15.2) you can do the following:

#include <QApplication>
#include <QProcess>

//...

QString program = qApp->arguments()[0];
QStringList arguments = qApp->arguments().mid(1); // remove the 1st argument - the program name
qApp->quit();
QProcess::startDetached(program, arguments);
trig-ger
  • 1,195
  • 1
  • 11
  • 18
5

I'm taking the other answers solutions, but better. No need for pointers, but there is a need for a ; after the while statement of a do { ... } while( ... ); construct.

int main(int argc, char *argv[])
{
    const int RESTART_CODE = 1000;

    do
    {
        QApplication app(argc, argv);
        MainWindow main_window(app);
    } while( app.exec() == RESTART_CODE);

    return return_from_event_loop_code;
}
rubenvb
  • 74,642
  • 33
  • 187
  • 332
  • 5
    +1 but maybe you should mention that the application should call [`QCoreApplication::exit(1000)`](http://doc.qt.nokia.com/latest/qcoreapplication.html#exit) to actually restart. – mtvec Aug 02 '11 at 09:53
  • This doesn't work on PyQt. See this Gist: https://gist.github.com/anonymous/5146031 – Eike Mar 12 '13 at 19:39
  • @Job I'm sorry, I don't see that in the docs for [Qt 4.8](http://qt-project.org/doc/qt-4.8/qcoreapplication.html#exit) nor [Qt 5.0](http://qt-project.org/doc/qt-5.0/qtcore/qcoreapplication.html#exit). – rubenvb Mar 12 '13 at 19:44
  • @rubenvb You didn't look at my Gist right? I did translate the idea to Python. – Eike Mar 12 '13 at 19:46
  • @Eike no I didn't. Python is not at all relevant to this question. That's all I'm saying. PyQt != Qt. – rubenvb Mar 13 '13 at 08:06
  • 2
    This solution is a work-around and has a prerequisite. If the application has global or static variables, these variables are not re-initialized, but a really restart does. – guan boshen Mar 15 '17 at 11:57
  • This doesn't work for me on Mac OS, application crashes. – kato2 Aug 26 '19 at 19:49
  • I recommend not using this method, because it will not reregister statics. This is problematic for example for the QApplication::instance(), as it was registered before and now cannot be reregistered. – Brainiac Dec 22 '19 at 23:55
4

Assuming that 1337 is your restart code:

main.cxx

int main(int argc, char * argv[])
{  
  int result = 0;

  do
  {
     QCoreApplication coreapp(argc, argv);
     MyClass myObj;
     result = coreapp.exec();
  } while( result == 1337 );

  return result;
}

myClass.cxx

qApp->exit(1337);
braggPeaks
  • 1,158
  • 10
  • 23
2

Doing a real process restart without subclassing:

QCoreApplication a(argc, argv);
int returncode = a.exec();
if (returncode == -1)
{
  QProcess* proc = new QProcess();
  proc->start(QCoreApplication::applicationFilePath());
}
return returncode;

Edit for Mac OS like earlier example.

To restart call

QCoreApplication::exit(-1);

somewhere in your code.

Aise
  • 21
  • 1
  • 1
    this seems the most logical of all the answers. but I guess that you will have the two executables running for a brief period of time together, right? – Robson Apr 13 '18 at 07:20
  • This works great! Unfortunately it does no pass the same command line arguments it received when created. I added QCoreApplication::arguments() to the start call to fix this. – mrexodia Mar 03 '21 at 10:46
1

Take a look at How to restart an application thread on qtcentre.org, where muisei gives this code

#define RESTART_CODE 1000
int main(int argc, char *argv[])
{
  int return_from_event_loop_code;
  QPointer<QApplication> app;
  QPointer<MainWindow> main_window;
  do
  {
    if(app) delete app;
    if(main_window) delete main_window;

    app = new QApplication(argc, argv);
    main_window = new MainWindow(app);
    return_from_event_loop_code = app->exec();
  }
  while(return_from_event_loop_code==RESTART_CODE)

  return return_from_event_loop_code;
}
Piotr Dobrogost
  • 41,292
  • 40
  • 236
  • 366
  • 1. You shouldn't check for `NULL` before `delete`, 2. You could declare the `QPointer`s inside the loop, then you don't have to delete them at all (being smart pointers and all), 3. You don't need pointers at all, 4. You have a syntax error (check my answer). – rubenvb Jun 15 '11 at 10:25
  • this code is giving "exited with code -1073741819" error when I am declaring main_window = new MainWindow; and when declaring main_window = new MainWindow(app) it is giving declaration error. – abhishek Apr 23 '12 at 19:10
  • This is the original answer which I cited verbosely. See what's the type of the argument to `MainWindow` class and remember that `app` variable is of type `QPointer`. – Piotr Dobrogost Apr 23 '12 at 19:23
1

You can use my open source library:

https://marketplace.qt.io/products/main-loop-wdt-for-qt-qml

It's a watchdog timer for the main qt loop, but I have a function for forced reboot, with different strategies: startdetached + exit, exec system call on Linux / macOS, and delayed restart (for example, exit and restart after 3 seconds)

0

This slight variation on Rubenvb's idea works with PyQt. clearSettings is the method that triggers the restart.

class GuiMain

    #Most of implementation missing

    def clearSettings(self):
        #Clearing the settings missing
        QApplication.exit(GuiMain.restart_code)

    restart_code = 1000

    @staticmethod
    def application_main():
        """
        The application's main function. 
        Create application and main window and run them.
        """
        while True:
            app = QApplication(sys.argv)
            window = GuiMain()
            window.show()
            ret = app.exec_()
            if ret != GuiMain.restart_code:
                break
            del window
            del app
Eike
  • 2,205
  • 17
  • 10
0

Here is the code:

main.cpp:

int main(int argc, char *argv[])
{
    int currentExitCode = 0;

    do {
     QApplication a(argc, argv);
     MainWindow w;
     w.show();
     currentExitCode = a.exec();
    } while( currentExitCode == MainWindow::EXIT_CODE_REBOOT );

    return currentExitCode;

}

mainwindow.h

    class MainWindow : public QMainWindow
    {
        Q_OBJECT

    public:
        explicit MainWindow(QWidget *parent = 0);
        static int const EXIT_CODE_REBOOT;//THIS IS THE IMPORTANT THING TO ADD TO YOUR CODE
        ~MainWindow();
    private slots:
        void slotReboot();//AND THIS ALSO

    //ALL THE OTHER VARIABLES
    }

The slotReboot() is the slot that will receive the signal of the QAction I'm going to show in the mainwindow.cpp

mainwindow.cpp

First initialize EXIT_CODE_REBOOT :

int const MainWindow::EXIT_CODE_REBOOT = -123456789;

and declare a QAction pointer:

QAction* actionReboot;

then in the MainWindow constructor:

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

     actionReboot = new QAction( this );
     actionReboot->setText( tr("Restart") );
     actionReboot->setStatusTip( tr("Restarts the application") );
     connect( actionReboot, SIGNAL (triggered()),this, SLOT (slotReboot()));
}

And finally you need to send the signal (in the part of your code you need), in this way:

actionReboot->trigger();

I did the code I showed following these instructions: How to make an application restartable - Qt Wiki

Angie Quijano
  • 4,167
  • 3
  • 25
  • 30
  • Although the above changes worked, the restarted app crashes sometimes and webkitwidget is not working properly in the restarted app. The solution suggested by @deepmax works fine for me. – Vinod S. Patil Dec 23 '16 at 08:47
0

I just used the method described above and I noticed that my application crashes on restart. ...then I switched the following lines of code:

if(app) delete app;
if(main_window) delete main_window;

to:

if(main_window) delete main_window;
if(app) delete app;

and it behaves OK. For some reason the window must be deleted first. Just a note for future readers.


EDIT: ...and a different approach for those who want a real process-restart: You can declare a myApp::Restart() method in your subclass of QApplication. The following version works OK on both MS-Windows & MacOS:

// Restart Application
void myApp::Restart(bool Abort)
{
    // Spawn a new instance of myApplication:
    QProcess proc;
#ifdef Q_OS_WIN
    proc.start(this->applicationFilePath());
#endif    

#ifdef Q_OS_MAC
    // In Mac OS the full path of aplication binary is:
    //    <base-path>/myApp.app/Contents/MacOS/myApp
    QStringList args;
    args << (this->applicationDirPath() + "/../../../myApp.app");
    proc.start("open", args);
#endif

    // Terminate current instance:
    if (Abort) // Abort Application process (exit immediattely)
        ::exit(0);
    else
        this->exit(0); // Exit gracefully by terminating the myApp instance
}
Fivos Vilanakis
  • 1,490
  • 12
  • 13