how to restart an application in qt?
You can use QProcess::startDetached
to run an instance of your application in a new process and detach from it. After that you should exit the application :
QProcess process;
process.startDetached("myApp",QStringList());
qApp->quit();
Here myApp
is the name of the executable file of the application. On Windows it can be myApp.exe
.
How to auto restart a Qt application when it crashes, within the same program?
Here's how you might do it using a single application that can act either as a monitor or as business logic. It's akin to Jon Harper's answer, except in code, not prose :)
Of Note
The monitor should not instantiate a
QApplication
norQGuiApplication
: it has no UI. Otherwise, redundant running process indicators will appear on some platforms (i.e. OS X, Win 10).The monitor/business logic selection is achieved via setting an environment variable in the called process.
Passing the monitor/business logic selection via command line arguments is problematic, as the command line switch would need to be filtered out -- doing that portably without running into corner cases is tricky.
The monitor process forwards the console I/O of the business logic process, as well as the return code.
// https://github.com/KubaO/stackoverflown/tree/master/questions/appmonitor-37524491
#include <QtWidgets>
#include <cstdlib>
#if defined(Q_OS_WIN32)
#include <windows.h>
#else
static void DebugBreak() { abort(); }
#endif
static int businessLogicMain(int &argc, char **argv) {
QApplication app{argc, argv};
qDebug() << __FUNCTION__ << app.arguments();
QWidget w;
QHBoxLayout layout{&w};
QPushButton crash{"Crash"}; // purposefully crash for testing
QPushButton quit{"Quit"}; // graceful exit, which doesn't need restart
layout.addWidget(&crash);
layout.addWidget(&quit);
w.show();
QObject::connect(&crash, &QPushButton::clicked, DebugBreak);
QObject::connect(&quit, &QPushButton::clicked, &QCoreApplication::quit);
return app.exec();
}
static char const kRunLogic[] = "run__business__logic";
static char const kRunLogicValue[] = "run__business__logic";
#if defined(Q_OS_WIN32)
static QString getWindowsCommandLineArguments() {
const wchar_t *args = GetCommandLine();
bool oddBackslash = false, quoted = false, whitespace = false;
// skip the executable name according to Windows command line parsing rules
while (auto c = *args) {
if (c == L'\\')
oddBackslash ^= 1;
else if (c == L'"')
quoted ^= !oddBackslash;
else if (c == L' ' || c == L'\t')
whitespace = !quoted;
else if (whitespace)
break;
else
oddBackslash = false;
args++;
}
return QString::fromRawData(reinterpret_cast<const QChar*>(args), lstrlen(args));
}
#endif
static int monitorMain(int &argc, char **argv) {
#if !defined(Q_OS_WIN32)
QStringList args;
args.reserve(argc-1);
for (int i = 1; i < argc; ++i)
args << QString::fromLocal8Bit(argv[i]);
#endif
QCoreApplication app{argc, argv};
QProcess proc;
auto onFinished = [&](int retcode, QProcess::ExitStatus status) {
qDebug() << status;
if (status == QProcess::CrashExit)
proc.start(); // restart the app if the app crashed
else
app.exit(retcode); // no restart required
};
QObject::connect(&proc, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), onFinished);
auto env = QProcessEnvironment::systemEnvironment();
env.insert(kRunLogic, kRunLogicValue);
proc.setProgram(app.applicationFilePath()); // logic and monitor are the same executable
#if defined(Q_OS_WIN32)
SetErrorMode(SEM_NOGPFAULTERRORBOX); // disable Windows error reporting
proc.setNativeArguments(getWindowsCommandLineArguments()); // pass command line arguments natively
env.insert("QT_LOGGING_TO_CONSOLE", "1"); // ensure that the debug output gets passed along
#else
proc.setArguments(args);
#endif
proc.setProcessEnvironment(env);
proc.setProcessChannelMode(QProcess::ForwardedChannels);
proc.start();
return app.exec();
}
int main(int argc, char **argv) {
if (qgetenv(kRunLogic) != kRunLogicValue)
return monitorMain(argc, argv);
else
return qunsetenv(kRunLogic), businessLogicMain(argc, argv);
}
How do I restart my pyqt application?
Let's say you are in MainWindow. Define in the __init__
MainWindow.EXIT_CODE_REBOOT = -12345678 # or whatever number not already taken
Your slot restart()
should contain:
qApp.exit( MainWindow.EXIT_CODE_REBOOT )
and your main
:
currentExitCode = MainWindow.EXIT_CODE_REBOOT
while currentExitCode == MainWindow.EXIT_CODE_REBOOT:
a = QApplication(sys.argv)
w = MainWindow()
w.show()
currentExitCode = a.exec_()
return currentExitCode
[1] https://wiki.qt.io/How_to_make_an_Application_restartable
EDIT: Minimal working example
Instead of a signal/slot, I just re-implemented the keyPressedEvent
method.
import sys
from PyQt4 import QtGui
from PyQt4.QtCore import Qt
class MainWindow(QtGui.QMainWindow):
EXIT_CODE_REBOOT = -123
def __init__(self,parent=None):
QtGui.QMainWindow.__init__(self, parent)
def keyPressEvent(self,e):
if (e.key() == Qt.Key_R):
QtGui.qApp.exit( MainWindow.EXIT_CODE_REBOOT )
if __name__=="__main__":
currentExitCode = MainWindow.EXIT_CODE_REBOOT
while currentExitCode == MainWindow.EXIT_CODE_REBOOT:
a = QtGui.QApplication(sys.argv)
w = MainWindow()
w.show()
currentExitCode = a.exec_()
a = None # delete the QApplication object
How to restart a qt application after crashing?
create another qt application that runs your application.
#include <QApplication>
#include "QProcess"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QProcess aProcess;
QString exe = "Your process name with exact path";
QByteArray myOut;
while(1)
{
aProcess.start(exe);
//aProcess.waitForStarted();
//myOut = aProcess.readAllStandardOutput();
//printf("%s",myOut.constData());
aProcess.waitForFinished(-1);
//QString output(aProcess.readAllStandardOutput());
myOut = aProcess.readAllStandardOutput();
printf("%s",myOut.constData());
}
return a.exec();
}
this program will restart your app when it crashed or closed
How to reboot PyQt5 application
The logic is to end the eventloop and launch the application an instant before it closes:
import sys
from PyQt5 import QtCore, QtWidgets
def restart():
QtCore.QCoreApplication.quit()
status = QtCore.QProcess.startDetached(sys.executable, sys.argv)
print(status)
def main():
app = QtWidgets.QApplication(sys.argv)
print("[PID]:", QtCore.QCoreApplication.applicationPid())
window = QtWidgets.QMainWindow()
window.show()
button = QtWidgets.QPushButton("Restart")
button.clicked.connect(restart)
window.setCentralWidget(button)
sys.exit(app.exec_())
if __name__ == "__main__":
main()
Related Topics
Using C Function from Other Package in Rcpp
Boost.Python Not Supporting Parallelism
How to Get the Mouse Position in a Console Program
How to Download a File with Winhttp in C/C++
C++ Project Compiled with Modern Compiler, But Linked Against Outdated Libstdc++
Comparing Character Arrays and String Literals in C++
How to Solve -------Undefined Reference to '_Chkstk_Ms'-------On Mingw
How to Call on a Function Found on Another File
C++ Priority_Queue with Lambda Comparator Error
Why "Initializer-String for Array of Chars Is Too Long" Compiles Fine in C & Not in C++
Why Does My Program Hang When Opening a Mkfifo-Ed Pipe
How to Write to Middle of a File in C++
Can a Single Member of a Class Template Be Partially Specialized
How to Use a Timer in C++ to Force Input Within a Given Time
Does This Type of Memory Get Allocated on the Heap or the Stack