General Architecture Help
-
I've done a lot of small QML and Qt applications, but not I'm starting on a large project for my senior year. I've been trying to implement my application the way I want it but I keep messing up and noticing I have to re-architecture my entire program. I just need some help before I go any further developing and have to re do it all again.
I want my application to be one main window that is entirely defined by QML. I want it to not close when the main window is closed, but only when the system icon is clicked and exited. I know to do this I need to set viewer.setQuitOnLastWindowClosed(false), but this also means I have to subclass ": public QSystemTrayIcon".
So should I create a Qt Widgets Application with base class MainWindow? How can I subclass QSystemTrayIcon if it's a MainWindow? Do I always need "qtquick2applicationviewer" to view QML?
I feel like every example I find for Qt is versions out of date and I just can't seem to put a large project together without it falling apart because I can't seem to get the pieces working together.
-
You can use QMainWindow with a system tray icon. Overriding the closeEvent method is the key to keeping the application from exiting except through the system tray icon. I added code in to restore the window when the user clicks the system tray icon. I also added code to inform the user the first time that he or she exits the application that the application will continue running in the system tray.
Here's a sketch I made up, inspired by the System Tray Example.
MainWindow.hpp
@#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QSystemTrayIcon>
#include <QWidget>
#include <QMainWindow>
#include <QCloseEvent>
#include <QMenu>
#include <QAction>class MainWindow : public QMainWindow
{
Q_OBJECTpublic:
explicit MainWindow(QWidget* parent = NULL);void setIcon();
public slots:
void iconActivated(QSystemTrayIcon::ActivationReason reason);protected:
virtual void closeEvent(QCloseEvent* event);private:
QAction* restoreAction;
QAction* quitAction;QSystemTrayIcon* trayIcon; QMenu* trayIconMenu; bool userInformed;
};
#endif
@MainWindow.cpp
@#include "MainWindow.hpp"
#include <QApplication>
#include <QMessageBox>
#include <QVBoxLayout>MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent)
{
restoreAction = new QAction(tr("&Restore"), this);
connect(restoreAction, SIGNAL(triggered()), this, SLOT(showNormal()));quitAction = new QAction(tr("&Quit"), this);
connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));trayIconMenu = new QMenu(this);
trayIconMenu->addAction(restoreAction);
trayIconMenu->addSeparator();
trayIconMenu->addAction(quitAction);trayIcon = new QSystemTrayIcon(this);
trayIcon->setContextMenu(trayIconMenu);connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
this, SLOT(iconActivated(QSystemTrayIcon::ActivationReason)));const QIcon icon(":/images/heart.png");
trayIcon->setIcon(icon);
setWindowIcon(icon);QWidget* mainWidget = new QWidget();
QVBoxLayout* mainLayout = new QVBoxLayout(mainWidget);
// Add your widgets heresetCentralWidget(mainWidget);
trayIcon->show();
setWindowTitle(tr("Your App"));
resize(400, 300);
}void MainWindow::iconActivated(QSystemTrayIcon::ActivationReason reason)
{
switch (reason)
{
case QSystemTrayIcon::Trigger:
case QSystemTrayIcon::DoubleClick:
showNormal();
break;
default:
break;
}
}void MainWindow::closeEvent(QCloseEvent* event)
{
if (trayIcon->isVisible())
{
if (!userInformed)
{
QMessageBox::information(this, tr("Your App"),
tr("The application is still running in the system tray."));
userInformed = true;
}hide(); event->ignore();
}
}@main.cpp
@#include <QApplication>#include "MainWindow.hpp"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);QApplication::setQuitOnLastWindowClosed(false); MainWindow mainWindow; mainWindow.show(); return app.exec();
}
@