【发布时间】:2011-07-05 00:38:47
【问题描述】:
我只是问自己如何重新启动我自己的 qt 应用程序?
谁能给我举个例子?
【问题讨论】:
-
你说的“重启”是什么意思?
-
@JeremiahWillcock 在这种情况下你能用多少种方式来解释“重启”?
标签: c++ qt qt4 application-restart
我只是问自己如何重新启动我自己的 qt 应用程序?
谁能给我举个例子?
【问题讨论】:
标签: c++ qt qt4 application-restart
要重新启动应用程序,请尝试:
#include <QApplication>
#include <QProcess>
...
// restart:
qApp->quit();
QProcess::startDetached(qApp->arguments()[0], qApp->arguments());
【讨论】:
qApp->quit(); 会导致系统崩溃,或者至少迫使用户硬重启它。在这种情况下,建议使用其他可以保证终止进程的方法。
我正在采用其他答案解决方案,但更好。不需要指针,但在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;
}
【讨论】:
QCoreApplication::exit(1000) 来实际重新启动。
假设 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);
【讨论】:
要重新启动正在运行的 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);
【讨论】:
在没有子类化的情况下重新启动真正的进程:
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);
在你的代码中。
【讨论】:
查看 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;
}
【讨论】:
delete 之前检查NULL,2. 您可以在循环内声明QPointers,然后您根本不必删除它们(作为智能指针等等),3. 您根本不需要指针,4.你有一个语法错误(检查我的答案)。
MainWindow 类的参数类型并记住app 变量的类型为QPointer<QApplication>。
我刚刚使用了上面描述的方法,我注意到我的应用程序在重启时崩溃了。 ...然后我切换了以下代码行:
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
}
【讨论】:
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
【讨论】:
代码如下:
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
}
slotReboot() 是接收QAction 信号的插槽,我将在 mainwindow.cpp 中显示
mainwindow.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
【讨论】:
你可以使用我的开源库:
https://marketplace.qt.io/products/main-loop-wdt-for-qt-qml
它是主qt循环的看门狗定时器,但我有一个强制重启的功能,有不同的策略:startdetached + exit,在Linux / macOS上执行系统调用,延迟重启(例如,退出并在3后重启秒)
【讨论】: