【问题标题】:how to restart my own qt application?如何重新启动我自己的 qt 应用程序?
【发布时间】:2011-07-05 00:38:47
【问题描述】:

我只是问自己如何重新启动我自己的 qt 应用程序?

谁能给我举个例子?

【问题讨论】:

标签: c++ qt qt4 application-restart


【解决方案1】:

要重新启动应用程序,请尝试:

#include <QApplication>
#include <QProcess>

...

// restart:
qApp->quit();
QProcess::startDetached(qApp->arguments()[0], qApp->arguments());

【讨论】:

  • 这很好用,除了多余的第一个参数,所以我编辑了答案以从参数列表中删除程序名称。谢谢!
  • 如果您在调用 qApp->quit() 时位于 qt 小部件内,执行是否会在此处停止,导致 QProcess::startDEtached 未被调用?
  • 请注意,如果qApp-&gt;quit(); 会导致系统崩溃,或者至少迫使用户硬重启它。在这种情况下,建议使用其他可以保证终止进程的方法。
  • 我建议将第二个参数更改为包含从第二个开始的元素,否则程序名称会出现两次:QString program = qApp->arguments()[0]; QStringList arguments = qApp->arguments().mid(1); qApp->退出(); QProcess::startDetached(程序,参数); (见我的答案版本)。
【解决方案2】:

我正在采用其他答案解决方案,但更好。不需要指针,但在do { ... } while( ... ); 构造的while 语句之后需要;

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;
}

【讨论】:

  • +1 但也许你应该提到应用程序应该调用QCoreApplication::exit(1000) 来实际重新启动。
  • 这在 PyQt 上不起作用。请参阅此要点:gist.github.com/anonymous/5146031
  • @Job 对不起,我在Qt 4.8Qt 5.0 的文档中都没有看到。
  • @rubenvb 你没看我的要点吧?我确实将这个想法翻译成 Python。
  • 此解决方案是一种变通方法,并且具有先决条件。如果应用程序有全局或静态变量,这些变量不会重新初始化,而是真正重新启动。
【解决方案3】:

假设 1337 是你的重启代码:

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);

【讨论】:

    【解决方案4】:

    要重新启动正在运行的 Qt 应用程序(至少在 Qt 5.15.2 中),您可以执行以下操作:

    #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);
    

    【讨论】:

      【解决方案5】:

      在没有子类化的情况下重新启动真正的进程:

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

      像前面的例子一样为 Mac OS 编辑。

      重新开始通话

      QCoreApplication::exit(-1);
      

      在你的代码中。

      【讨论】:

      • 这似乎是所有答案中最合乎逻辑的。但我猜你会让这两个可执行文件一起运行一小段时间,对吧?
      • 这很好用!不幸的是,它没有传递它在创建时收到的相同命令行参数。我在开始调用中添加了 QCoreApplication::arguments() 来解决这个问题。
      【解决方案6】:

      查看 qtcentre.org 上的 How to restart an application 线程,muisei 提供了此代码

      #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;
      }
      

      【讨论】:

      • 1.您不应该在delete 之前检查NULL,2. 您可以在循环内声明QPointers,然后您根本不必删除它们(作为智能指针等等),3. 您根本不需要指针,4.你有一个语法错误(检查我的答案)。
      • 当我声明 main_window = new MainWindow; 时,此代码给出“退出代码 -1073741819”错误;并且在声明 main_window = new MainWindow(app) 时,它给出了声明错误。
      • 这是我详细引用的原始答案。查看MainWindow 类的参数类型并记住app 变量的类型为QPointer&lt;QApplication&gt;
      【解决方案7】:

      我刚刚使用了上面描述的方法,我注意到我的应用程序在重启时崩溃了。 ...然后我切换了以下代码行:

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

      到:

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

      它的行为正常。由于某种原因,必须先删除该窗口。 仅供未来读者参考。


      编辑: ...对于那些想要真正重新启动进程的人来说,还有一种不同的方法:您可以在 QApplication 的子类中声明一个 myApp::Restart() 方法。以下版本在 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
      }
      

      【讨论】:

      • 删除 nullptr;没问题,不用检查
      • 感谢@oaulm,这是正确的(我只是根据上面 Piotr Dobrogost 发布的原始代码发表评论)
      【解决方案8】:

      Rubenvb 想法的这种细微变化适用于 PyQt。 clearSettings是触发重启的方法。

      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
      

      【讨论】:

        【解决方案9】:

        代码如下:

        ma​​in.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;
        
        }
        

        ma​​inwindow.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
            }
        

        slotReboot() 是接收QAction 信号的插槽,我将在 mainwindow.cpp 中显示

        ma​​inwindow.cpp

        首先初始化EXIT_CODE_REBOOT

        int const MainWindow::EXIT_CODE_REBOOT = -123456789;
        

        并声明一个QAction 指针:

        QAction* actionReboot;
        

        然后在MainWindow 构造函数中:

        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()));
        }
        

        最后你需要发送信号(在你需要的代码部分),以这种方式:

        actionReboot->trigger();
        

        我按照以下说明完成了我展示的代码:How to make an application restartable - Qt Wiki

        【讨论】:

        • 虽然上述更改有效,但重新启动的应用程序有时会崩溃,并且 webkitwidget 在重新启动的应用程序中无法正常工作。 @deepmax 建议的解决方案对我来说很好。
        【解决方案10】:

        你可以使用我的开源库:

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

        它是主qt循环的看门狗定时器,但我有一个强制重启的功能,有不同的策略:startdetached + exit,在Linux / macOS上执行系统调用,延迟重启(例如,退出并在3后重启秒)

        【讨论】:

          猜你喜欢
          • 2013-02-18
          • 2014-08-27
          • 2021-07-13
          • 2022-07-13
          • 2016-06-13
          • 2011-05-15
          • 1970-01-01
          • 1970-01-01
          • 2012-02-07
          相关资源
          最近更新 更多