Results 1 to 6 of 6

Thread: NEED HELP: QSystemTrayIcon QMenu doesn't dissapear

  1. #1
    Join Date
    Feb 2008
    Posts
    153
    Thanks
    40
    Thanked 8 Times in 5 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Question NEED HELP: QSystemTrayIcon QMenu doesn't dissapear

    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:

    Qt Code:
    1. #include <QApplication>
    2. #include <QtGui>
    3. #include "app.h"
    4. //
    5. QSplashScreen *splash = 0;
    6. //
    7. int main(int argc, char ** argv)
    8. {
    9. QApplication app( argc, argv );
    10. QPixmap pixmap(":/app/splash.png");
    11. splash = new QSplashScreen (pixmap, Qt::X11BypassWindowManagerHint | Qt::FramelessWindowHint | Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint);
    12. splash->show();
    13. splash->showMessage(QObject::tr("Loading:") + " " + QObject::tr("Setting application variables"), Qt::AlignRight | Qt::AlignTop, Qt::black);
    14. qApp->processEvents();
    15. splash->showMessage(QObject::tr("Loading:") + " " + QObject::tr("Checking for system tray"), Qt::AlignRight | Qt::AlignTop, Qt::black);
    16. while(!QSystemTrayIcon::isSystemTrayAvailable()) { //Check presence of system tray
    17. 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) {
    18. return 1;
    19. }
    20. }
    21. qApp->processEvents();
    22. splash->showMessage(QObject::tr("Loading:") + " " + QObject::tr("Preloading main window"), Qt::AlignRight | Qt::AlignTop, Qt::black);
    23. app win;
    24. win.show();
    25. qApp->processEvents();
    26. splash->close();
    27. delete splash;
    28. return app.exec();
    29. }
    To copy to clipboard, switch view to plain text mode 

    Here is app.cpp:

    Qt Code:
    1. #include <QtCore>
    2. #include <QtGui>
    3. #include "app.h"
    4. //
    5. app::app(QWidget * parent, Qt::WFlags f)
    6. : QWidget(parent, f)
    7. {
    8. setupUi(this);
    9. createActions();
    10. createTrayIcon();
    11. trayIcon->show();
    12. connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(iconActivated(QSystemTrayIcon::ActivationReason)));
    13. }
    14.  
    15. void app::showMessage(const QString & title, const QString & message, QSystemTrayIcon::MessageIcon icon, int millisecondsTimeoutHint) {
    16. if(QSystemTrayIcon::supportsMessages()) { //Use the bubble only if the system supports it
    17. trayIcon->showMessage(title, message, icon, millisecondsTimeoutHint);
    18. } //This function is a failsafe of the default systray showMessage();
    19. else {
    20. QMessageBox::information(this, title, message); //Otherwise, use a good old message box
    21. }
    22. }
    23. void app::closeEvent(QCloseEvent *event) { //Prevent the user from entirely exiting the program when he just closes the dialog
    24. QSettings TMIP(this);
    25. event->ignore();
    26. }
    27.  
    28. void app::setDialogVisible() {
    29. isVisible()?hide():show(); //Quick way of showing/hiding dialog
    30. }
    31.  
    32. void app::iconActivated(QSystemTrayIcon::ActivationReason reason) {
    33. switch (reason) {
    34. case QSystemTrayIcon::Trigger: {
    35. setDialogVisible();
    36. break;
    37. }
    38. case QSystemTrayIcon::DoubleClick:{
    39. break;
    40. }
    41. case QSystemTrayIcon::MiddleClick: {
    42. break;
    43. }
    44. default: {
    45. ;
    46. }
    47. }
    48. }
    49.  
    50. void app::createTrayIcon() {
    51. trayIconMenu = new QMenu(this);
    52. trayIconMenu->addAction(showDialogAction);
    53. trayIconMenu->addAction(maximizeAction);
    54. trayIconMenu->addAction(restoreAction);
    55. trayIconMenu->addSeparator();
    56. trayIconMenu->addAction(quitAction);
    57. trayIcon = new QSystemTrayIcon(this);
    58. trayIcon->setContextMenu(trayIconMenu);
    59. trayIcon->setIcon(QIcon(":app/app.png"));
    60. }
    61.  
    62. void app::createActions() { //Create the tray icon's context menu
    63. showDialogAction = new QAction(tr("Show/hide window..."), this);
    64. connect(showDialogAction, SIGNAL(triggered()), this, SLOT(setDialogVisible()));
    65. maximizeAction = new QAction(tr("Ma&ximize"), this);
    66. connect(maximizeAction, SIGNAL(triggered()), this, SLOT(showMaximized()));
    67. restoreAction = new QAction(tr("&Restore"), this);
    68. connect(restoreAction, SIGNAL(triggered()), this, SLOT(showNormal()));
    69. quitAction = new QAction(tr("&Quit"), this);
    70. connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
    71. }
    To copy to clipboard, switch view to plain text mode 

    Finally, here is app.h:

    Qt Code:
    1. #ifndef APP_H
    2. #define APP_H
    3. //
    4. #include "ui_app.h"
    5. #include <QSystemTrayIcon>
    6. #include <QWidget>
    7. //
    8. class QSettings;
    9. class QAction;
    10. class QMenu;
    11. class app : public QWidget, public Ui::app
    12. {
    13. Q_OBJECT
    14. public:
    15. app( QWidget * parent = 0, Qt::WFlags f = 0 );
    16. void showMessage(const QString & title, const QString & message, QSystemTrayIcon::MessageIcon icon = QSystemTrayIcon::Information, int millisecondsTimeoutHint = 10000);
    17. protected:
    18. void closeEvent(QCloseEvent *event);
    19. private slots:
    20. void setDialogVisible();
    21. void iconActivated(QSystemTrayIcon::ActivationReason reason);
    22. private:
    23. void createTrayIcon();
    24. void createActions();
    25.  
    26. QAction *showDialogAction;
    27. QAction *maximizeAction;
    28. QAction *restoreAction;
    29. QAction *quitAction;
    30.  
    31. QSystemTrayIcon *trayIcon;
    32. QMenu *trayIconMenu;
    33. };
    34. #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
    Last edited by codeslicer; 10th February 2008 at 02:46.

  2. #2
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: NEED HELP: QSystemTrayIcon QMenu doesn't dissapear

    Does this happen on all platforms?

    BTW, using labels and goto's is considered bad practice/coding/design. You can easily do that with a boolean function and a while loop.

  3. #3
    Join Date
    Feb 2008
    Posts
    153
    Thanks
    40
    Thanked 8 Times in 5 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Lightbulb Re: NEED HELP: QSystemTrayIcon QMenu doesn't dissapear

    Oh right, I forgot.

    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.

    I'll replace the goto stuff with a while() loop, but why is goto bad?

  4. #4
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: NEED HELP: QSystemTrayIcon QMenu doesn't dissapear

    A label is where a "goto" goes. In your example, retryTrayIcon is a label.
    They are bad because they make the code unreadable, are very likely to cause errors and also make the code harder to maintain.

    The only difference between your app and the Qt Systray example is that you start up with your application hidden. Try, just for testing, to show it, in main.cpp. See if you're experiencing the same behavior.

  5. The following user says thank you to marcel for this useful post:

    codeslicer (10th February 2008)

  6. #5
    Join Date
    Feb 2008
    Posts
    153
    Thanks
    40
    Thanked 8 Times in 5 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: NEED HELP: QSystemTrayIcon QMenu doesn't dissapear

    Hmm, weird. In my original source code, adding or subtracting the win.show() didn't make a difference. But I made a seperate project removing extra commands and it worked. I'll look around, and if I can't find it, I'll upload a zipped copy of my source code. Thanks though

  7. #6
    Join Date
    Feb 2008
    Posts
    153
    Thanks
    40
    Thanked 8 Times in 5 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: NEED HELP: QSystemTrayIcon QMenu doesn't dissapear

    I got it! It was QDevelop's fault. Apparently, when I ran the executable by using the debug button, the menu wouldn't lose focus. However, when I opened that binary, everything worked!!!

    This is truly strange Is it because QDevelop or the debugger is changing the ownership of the menu?

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.