5

I've set up a system tray icon for my app and have attached a simple context menu to it. If I right click the icon to bring up the context menu it works fine. If I then click somewhere that loses the focus of the app (e.g. elsewhere on the task bar or on another app) the context menu is not removed and still triggers the correct action when clicked. If, however, I click on the main app the context menu disappears as expected.

Here's the relevant code for creating the tray icon and context menu -

actionExit = new QAction( "Exit", this );
connect( actionExit, SIGNAL( triggered() ), this, SLOT( ExitClient() ));

myTrayIconMenu = new QMenu( this );
myTrayIconMenu->addAction( actionExit );

trayIcon = new QSystemTrayIcon( icon, this );
trayIcon->setContextMenu( myTrayIconMenu );
connect( systrayIcon, SIGNAL( activated( QSystemTrayIcon::ActivationReason )), 
         this, SLOT( ToggleVisibility( QSystemTrayIcon::ActivationReason )));
trayIcon->show( );

Do I need to add my own code that tests for the app losing focus so that I can manually hide the context menu? I had assumed this functionality would be built in.

[The problem is occurring in Windows 7, compiling with Visual Studio 2010 Pro via Qt plug-in - I haven't tested under any other OS]

I noticed this in the API documentation -

Note: The system tray icon does not take ownership of the menu. You must ensure that it is deleted at the appropriate time by, for example, creating the menu with a suitable parent object.

If I use

myTrayIconMenu = new QMenu( );

instead of

myTrayIconMenu = new QMenu( this );

the context menu is removed when the app loses focus. But then I'll need to take care of manually deleting the context menu.

How have other people dealt with this situation?

NG_
  • 6,895
  • 7
  • 45
  • 67
Rok
  • 2,568
  • 4
  • 26
  • 28

4 Answers4

2

Implementing a QSystemTrayIcon in your QApplication derived class instead of some QWidget can fix this issue.

main.cpp:

int main(int argc, char *argv[])
{
    return TestApp(argc, argv).exec();
}

testApp.cpp:

TestApp::TestApp(int &argc, char **argv) :
    QApplication(argc, argv)
{
    quitAction = new QAction("quit", this);
    connect(quitAction, SIGNAL(triggered()), this, SLOT(quit()));
    systemTrayMenu = new QMenu("tray menu");
    systemTrayMenu->addAction(quitAction);

    trayIcon = new QSystemTrayIcon( this);
    trayIcon -> setToolTip("test app");
    connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
            this, SLOT(iconActivated(QSystemTrayIcon::ActivationReason)));
    trayIcon -> setContextMenu(systemTrayMenu);
    trayIcon -> show();
}
Colin.Z
  • 31
  • 3
0

Could you tell which compiler you are using? I think I used to have this problem too. Plus some other tray-icon related problems (menus that would only show shadows, menus that would get stuck beneath the taskbar, etc.)

Ever since I switched from Mingw32 to the Visual Studio 2008 compiler it hasn't been bothering me anymore. Maybe someone else can elaborate on this (since I am no expert on Windows development).

StanB123
  • 477
  • 5
  • 14
0

You could connect the aboutToHide() signal to the deleteLater() slot to handle the deletion of the menu

king_nak
  • 11,313
  • 33
  • 58
0

It looks like this issue will be solved in Qt 4.8.0 according to this bug

david
  • 1,311
  • 12
  • 32