Hello,
I am making an application which will use the system tray. At first, when the application starts, a splash screen appears, then the tray icon shows without the main QWidget dialog showing. Everything is fine... until when the icon is right-clicked and the context menu shows. The problem is, the menu doesn't dissapear when it loses focus, unless the open dialog receives the focus. Here is main.cpp:
#include <QApplication>
#include <QtGui>
#include "app.h"
//
//
int main(int argc, char ** argv)
{
QPixmap pixmap
(":/app/splash.png");
splash
= new QSplashScreen (pixmap, Qt
::X11BypassWindowManagerHint | Qt
::FramelessWindowHint | Qt
::CustomizeWindowHint | Qt
::WindowStaysOnTopHint);
splash->show();
splash
->showMessage
(QObject::tr("Loading:") + " " + QObject::tr("Setting application variables"), Qt
::AlignRight | Qt
::AlignTop, Qt
::black);
qApp->processEvents();
splash
->showMessage
(QObject::tr("Loading:") + " " + QObject::tr("Checking for system tray"), Qt
::AlignRight | Qt
::AlignTop, Qt
::black);
while(!QSystemTrayIcon::isSystemTrayAvailable()) { //Check presence of system tray if(QMessageBox::critical(0,
QObject::tr("app"),
QObject::tr("Failed to add icon to the tray. Either your operating system doesn't have a system tray, or it has not been loaded yet. Currently, a system tray is required to run this program. Would you like to retry?"),
QMessageBox::Yes |
QMessageBox::No) == QMessageBox::No) { return 1;
}
}
qApp->processEvents();
splash
->showMessage
(QObject::tr("Loading:") + " " + QObject::tr("Preloading main window"), Qt
::AlignRight | Qt
::AlignTop, Qt
::black);
app win;
win.show();
qApp->processEvents();
splash->close();
delete splash;
return app.exec();
}
#include <QApplication>
#include <QtGui>
#include "app.h"
//
QSplashScreen *splash = 0;
//
int main(int argc, char ** argv)
{
QApplication app( argc, argv );
QPixmap pixmap(":/app/splash.png");
splash = new QSplashScreen (pixmap, Qt::X11BypassWindowManagerHint | Qt::FramelessWindowHint | Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint);
splash->show();
splash->showMessage(QObject::tr("Loading:") + " " + QObject::tr("Setting application variables"), Qt::AlignRight | Qt::AlignTop, Qt::black);
qApp->processEvents();
splash->showMessage(QObject::tr("Loading:") + " " + QObject::tr("Checking for system tray"), Qt::AlignRight | Qt::AlignTop, Qt::black);
while(!QSystemTrayIcon::isSystemTrayAvailable()) { //Check presence of system tray
if(QMessageBox::critical(0, QObject::tr("app"), QObject::tr("Failed to add icon to the tray. Either your operating system doesn't have a system tray, or it has not been loaded yet. Currently, a system tray is required to run this program. Would you like to retry?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) {
return 1;
}
}
qApp->processEvents();
splash->showMessage(QObject::tr("Loading:") + " " + QObject::tr("Preloading main window"), Qt::AlignRight | Qt::AlignTop, Qt::black);
app win;
win.show();
qApp->processEvents();
splash->close();
delete splash;
return app.exec();
}
To copy to clipboard, switch view to plain text mode
Here is app.cpp:
#include <QtCore>
#include <QtGui>
#include "app.h"
//
app
::app(QWidget * parent, Qt
::WFlags f
) {
setupUi(this);
createActions();
createTrayIcon();
trayIcon->show();
}
if(QSystemTrayIcon::supportsMessages()) { //Use the bubble only if the system supports it trayIcon->showMessage(title, message, icon, millisecondsTimeoutHint);
} //This function is a failsafe of the default systray showMessage();
else {
QMessageBox::information(this, title, message
);
//Otherwise, use a good old message box }
}
void app
::closeEvent(QCloseEvent *event
) { //Prevent the user from entirely exiting the program when he just closes the dialog event->ignore();
}
void app::setDialogVisible() {
isVisible()?hide():show(); //Quick way of showing/hiding dialog
}
switch (reason) {
setDialogVisible();
break;
}
break;
}
break;
}
default: {
;
}
}
}
void app::createTrayIcon() {
trayIconMenu
= new QMenu(this);
trayIconMenu->addAction(showDialogAction);
trayIconMenu->addAction(maximizeAction);
trayIconMenu->addAction(restoreAction);
trayIconMenu->addSeparator();
trayIconMenu->addAction(quitAction);
trayIcon->setContextMenu(trayIconMenu);
trayIcon
->setIcon
(QIcon(":app/app.png"));
}
void app::createActions() { //Create the tray icon's context menu
showDialogAction
= new QAction(tr
("Show/hide window..."),
this);
connect(showDialogAction, SIGNAL(triggered()), this, SLOT(setDialogVisible()));
maximizeAction
= new QAction(tr
("Ma&ximize"),
this);
connect(maximizeAction, SIGNAL(triggered()), this, SLOT(showMaximized()));
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()));
}
#include <QtCore>
#include <QtGui>
#include "app.h"
//
app::app(QWidget * parent, Qt::WFlags f)
: QWidget(parent, f)
{
setupUi(this);
createActions();
createTrayIcon();
trayIcon->show();
connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(iconActivated(QSystemTrayIcon::ActivationReason)));
}
void app::showMessage(const QString & title, const QString & message, QSystemTrayIcon::MessageIcon icon, int millisecondsTimeoutHint) {
if(QSystemTrayIcon::supportsMessages()) { //Use the bubble only if the system supports it
trayIcon->showMessage(title, message, icon, millisecondsTimeoutHint);
} //This function is a failsafe of the default systray showMessage();
else {
QMessageBox::information(this, title, message); //Otherwise, use a good old message box
}
}
void app::closeEvent(QCloseEvent *event) { //Prevent the user from entirely exiting the program when he just closes the dialog
QSettings TMIP(this);
event->ignore();
}
void app::setDialogVisible() {
isVisible()?hide():show(); //Quick way of showing/hiding dialog
}
void app::iconActivated(QSystemTrayIcon::ActivationReason reason) {
switch (reason) {
case QSystemTrayIcon::Trigger: {
setDialogVisible();
break;
}
case QSystemTrayIcon::DoubleClick:{
break;
}
case QSystemTrayIcon::MiddleClick: {
break;
}
default: {
;
}
}
}
void app::createTrayIcon() {
trayIconMenu = new QMenu(this);
trayIconMenu->addAction(showDialogAction);
trayIconMenu->addAction(maximizeAction);
trayIconMenu->addAction(restoreAction);
trayIconMenu->addSeparator();
trayIconMenu->addAction(quitAction);
trayIcon = new QSystemTrayIcon(this);
trayIcon->setContextMenu(trayIconMenu);
trayIcon->setIcon(QIcon(":app/app.png"));
}
void app::createActions() { //Create the tray icon's context menu
showDialogAction = new QAction(tr("Show/hide window..."), this);
connect(showDialogAction, SIGNAL(triggered()), this, SLOT(setDialogVisible()));
maximizeAction = new QAction(tr("Ma&ximize"), this);
connect(maximizeAction, SIGNAL(triggered()), this, SLOT(showMaximized()));
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()));
}
To copy to clipboard, switch view to plain text mode
Finally, here is app.h:
#ifndef APP_H
#define APP_H
//
#include "ui_app.h"
#include <QSystemTrayIcon>
#include <QWidget>
//
class app
: public QWidget,
public Ui
::app{
Q_OBJECT
public:
app
( QWidget * parent
= 0, Qt
::WFlags f
= 0 );
protected:
private slots:
void setDialogVisible();
private:
void createTrayIcon();
void createActions();
};
#endif
#ifndef APP_H
#define APP_H
//
#include "ui_app.h"
#include <QSystemTrayIcon>
#include <QWidget>
//
class QSettings;
class QAction;
class QMenu;
class app : public QWidget, public Ui::app
{
Q_OBJECT
public:
app( QWidget * parent = 0, Qt::WFlags f = 0 );
void showMessage(const QString & title, const QString & message, QSystemTrayIcon::MessageIcon icon = QSystemTrayIcon::Information, int millisecondsTimeoutHint = 10000);
protected:
void closeEvent(QCloseEvent *event);
private slots:
void setDialogVisible();
void iconActivated(QSystemTrayIcon::ActivationReason reason);
private:
void createTrayIcon();
void createActions();
QAction *showDialogAction;
QAction *maximizeAction;
QAction *restoreAction;
QAction *quitAction;
QSystemTrayIcon *trayIcon;
QMenu *trayIconMenu;
};
#endif
To copy to clipboard, switch view to plain text mode
I am using Ubuntu 7.10 with Qt 4.3.3. I based this off the trayicon example in the Qt Docs. The Qt example, when compiled, works perfectly as it should. On the Windows platform, the context menu also works as it should.
If I could get any help, I would be really grateful. So thanks in advance
~codeslicer
Bookmarks