From a6845d4552e31d8d37307a89b4b3a6dcd6c596c7 Mon Sep 17 00:00:00 2001 From: Travis Hunter Date: Fri, 7 Apr 2023 08:57:12 -0600 Subject: [PATCH] Running the gui via QtRocket class instead of directly from main(). Intention is to have the gui run in its own thread, and be an interface to QtRocket component (which is the application), rather than the application itself --- QtRocket.cpp | 68 ++++++++++++++++++++++++++++++++++++++++++++-- QtRocket.h | 19 +++++++++++-- gui/MainWindow.cpp | 7 +++-- gui/MainWindow.h | 12 +++++--- main.cpp | 67 +++++++++++++++++++++------------------------ 5 files changed, 125 insertions(+), 48 deletions(-) diff --git a/QtRocket.cpp b/QtRocket.cpp index caef6ff..a2e7871 100644 --- a/QtRocket.cpp +++ b/QtRocket.cpp @@ -1,17 +1,81 @@ #include "QtRocket.h" +#include "gui/MainWindow.h" +#include +#include +#include + +#include + + +// Initialize static member data QtRocket* QtRocket::instance = nullptr; +std::mutex QtRocket::mtx; +bool QtRocket::initialized = false; + + +// The gui worker thread +void guiWorker(int argc, char* argv[], int& ret) +{ + QApplication a(argc, argv); + a.setWindowIcon(QIcon(":/qtrocket.png")); + + // Start translation component. + // TODO: Only support US English at the moment. Anyone want to help translate? + QTranslator translator; + const QStringList uiLanguages = QLocale::system().uiLanguages(); + for (const QString &locale : uiLanguages) + { + const QString baseName = "qtrocket_" + QLocale(locale).name(); + if (translator.load(":/i18n/" + baseName)) + { + a.installTranslator(&translator); + break; + } + } + + // Go! + MainWindow w(QtRocket::getInstance()); + w.show(); + ret = a.exec(); + +} QtRocket* QtRocket::getInstance() { - if(!instance) + if(!initialized) { - instance = new QtRocket(); + init(); } return instance; } +void QtRocket::init() +{ + std::lock_guard lck(mtx); + if(!initialized) + { + instance = new QtRocket(); + initialized = true; + } +} + QtRocket::QtRocket() { logger = utils::Logger::getInstance(); + running = false; +} + +int QtRocket::run(int argc, char* argv[]) +{ + // Really should only start this thread once + if(!running) + { + running = true; + int ret = 0; + std::thread guiThread(guiWorker, argc, argv, std::ref(ret)); + guiThread.join(); + return ret; + } + return 0; } diff --git a/QtRocket.h b/QtRocket.h index 33e5216..30c57e4 100644 --- a/QtRocket.h +++ b/QtRocket.h @@ -1,8 +1,11 @@ #ifndef QTROCKET_H #define QTROCKET_H +#include +#include +#include + #include "utils/Logger.h" -#include "gui/MainWindow.h" /** * @brief The QtRocket class is the master controller for the QtRocket application. @@ -13,15 +16,25 @@ class QtRocket { public: static QtRocket* getInstance(); + + utils::Logger* getLogger() { return logger; } + + // This will return when the main window returns; + // If called multiple times, subsequent calls, will simply + // immediately return with value 0 + int run(int argc, char* argv[]); private: QtRocket(); + static void init(); + + std::atomic_bool running; + static bool initialized; + static std::mutex mtx; static QtRocket* instance; utils::Logger* logger; - - }; #endif // QTROCKET_H diff --git a/gui/MainWindow.cpp b/gui/MainWindow.cpp index d7fecc7..9c0e1b3 100644 --- a/gui/MainWindow.cpp +++ b/gui/MainWindow.cpp @@ -10,9 +10,10 @@ #include #include -MainWindow::MainWindow(QWidget *parent) - : QMainWindow(parent) - , ui(new Ui::MainWindow) +MainWindow::MainWindow(QtRocket* _qtRocket, QWidget *parent) + : QMainWindow(parent), + ui(new Ui::MainWindow), + qtRocket(_qtRocket) { ui->setupUi(this); } diff --git a/gui/MainWindow.h b/gui/MainWindow.h index 767356f..afd33a7 100644 --- a/gui/MainWindow.h +++ b/gui/MainWindow.h @@ -1,8 +1,11 @@ -#ifndef QTROCKET_H -#define QTROCKET_H +#ifndef MAINWINDOW_H +#define MAINWINDOW_H #include +#include "QtRocket.h" + + QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } QT_END_NAMESPACE @@ -12,7 +15,7 @@ class MainWindow : public QMainWindow Q_OBJECT public: - MainWindow(QWidget *parent = nullptr); + MainWindow(QtRocket* _qtRocket, QWidget *parent = nullptr); ~MainWindow(); private slots: @@ -24,5 +27,6 @@ private slots: private: Ui::MainWindow* ui; + QtRocket* qtRocket; }; -#endif // QTROCKET_H +#endif // MAINWINDOW_H diff --git a/main.cpp b/main.cpp index 3b3b466..7e3d40c 100644 --- a/main.cpp +++ b/main.cpp @@ -1,12 +1,38 @@ +#include "QtRocket.h" +#include "utils/Logger.h" + +int main(int argc, char *argv[]) +{ + + // Instantiate logger + utils::Logger* logger = utils::Logger::getInstance(); + logger->setLogLevel(utils::Logger::DEBUG); + // instantiate QtRocket + QtRocket* qtrocket = QtRocket::getInstance(); + + // Run QtRocket. This'll start the GUI thread and block until the user + // exits the program + int retVal = qtrocket->run(argc, argv); + logger->debug("Returning"); + return retVal; +} + + + +/* + * This was the old main when it directly started the QtGui. It worked. The new way of + * starting the gui through QtRocket->run() also seems to work, but I'm leaving this here for + * now in case there are unforeseen issues with starting the gui in a separate thread via + * QtRocket::run() + * + #include "gui/MainWindow.h" #include #include #include -#include - -void worker(int argc, char* argv[], int& ret) +int main(int argc, char* argv[]) { QApplication a(argc, argv); a.setWindowIcon(QIcon(":/qtrocket.png")); @@ -28,37 +54,6 @@ void worker(int argc, char* argv[], int& ret) // Go! MainWindow w; w.show(); - ret = a.exec(); - -} - -int main(int argc, char *argv[]) -{ - /* - QApplication a(argc, argv); - a.setWindowIcon(QIcon(":/qtrocket.png")); - - // Start translation component. - // TODO: Only support US English at the moment. Anyone want to help translate? - QTranslator translator; - const QStringList uiLanguages = QLocale::system().uiLanguages(); - for (const QString &locale : uiLanguages) - { - const QString baseName = "qtrocket_" + QLocale(locale).name(); - if (translator.load(":/i18n/" + baseName)) - { - a.installTranslator(&translator); - break; - } - } - - // Go! - //MainWindow w; - //w.show(); - //return a.exec(); - */ - int ret = 0; - std::thread guiThread(worker, argc, argv, std::ref(ret)); - guiThread.join(); - return ret; + return a.exec(); } +*/