Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Memory leak using QSystemTrayIcon
Forum Updated to NodeBB v4.3 + New Features

Memory leak using QSystemTrayIcon

Scheduled Pinned Locked Moved Unsolved General and Desktop
4 Posts 2 Posters 1.3k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • R Offline
    R Offline
    retmas
    wrote on last edited by retmas
    #1

    Hi
    I'm trying this simple code:
    .h

    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    public:
        explicit MainWindow(QWidget *parent = 0);
    };
    

    .cpp

    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
    {
        if(QSystemTrayIcon::isSystemTrayAvailable())
        {
            QSystemTrayIcon* trayIcon = new QSystemTrayIcon(this);
            trayIcon->setIcon(this->windowIcon());
            QMenu* contextMenu = new QMenu(this);
            contextMenu->addAction("Quit", this, SLOT(close()));
            trayIcon->setContextMenu(contextMenu);
            trayIcon->show();
        }
    }
    

    main.cpp

    int main(int argc, char *argv[])
    {
        QApplication app(argc, argv);
    
        QIcon appIcon(":/icons/app.svg");
        app.setWindowIcon(appIcon);
    
        MainWindow w;
        w.show();
        return app.exec();
    }
    

    Analyzing by valgrind form within Qt Creator, I get:

    4 bytes in 1 blocks are indirectly lost in loss record 33 of 6,632
    4 bytes in 1 blocks are indirectly lost in loss record 34 of 6,632
    64 bytes in 1 blocks are still reachable in loss record 4,289 of 6,632
    522 (64 direct, 458 indirect) bytes in 1 blocks are definitely lost in loss record 6,396 of 6,632

    (pointing to the line trayIcon->setContextMenu(contextMenu);)
    If I comment out the line with setContextMenu() call, there are no leaks shown.

    What am i doing wrong?

    1 Reply Last reply
    0
    • R Offline
      R Offline
      retmas
      wrote on last edited by retmas
      #2

      It seems the reason is not of QSystemTrayIcon, but of creating actions method. Rewrote .cpp for better look:

      MainWindow::MainWindow(QWidget *parent)
          : QMainWindow(parent)
      {
          QAction* quitAction = new QAction(tr("&Quit"), this);
          connect(quitAction, &QAction::triggered, qApp, &QApplication::quit);
      
          QMenu* contextMenu = new QMenu("Menu", this);
          contextMenu->addAction(quitAction);
      
          QSystemTrayIcon* trayIcon = new QSystemTrayIcon(this);
          trayIcon->setIcon(this->windowIcon());
          trayIcon->setContextMenu(contextMenu);
          trayIcon->show();
      }
      

      In that case valgrind shows no memory leaks. But if I write

      MainWindow::MainWindow(QWidget *parent)
          : QMainWindow(parent)
      {
          QMenu* contextMenu = new QMenu("Menu", this);
          contextMenu->addAction("Quit", qApp, &QApplication::quit);
      
          QSystemTrayIcon* trayIcon = new QSystemTrayIcon(this);
          trayIcon->setIcon(this->windowIcon());
          trayIcon->setContextMenu(contextMenu);
          trayIcon->show();
      }
      

      valgrind shows same leaks again.
      In that (second) case, doesn't QAction instance destroyed when QMenu does?

      1 Reply Last reply
      0
      • R Offline
        R Offline
        retmas
        wrote on last edited by retmas
        #3

        The same leak is reported if QMenu instance created before QAction, like in this code:

        MainWindow::MainWindow(QWidget *parent)
            : QMainWindow(parent)
        {
            QMenu* contextMenu = new QMenu("Menu", this);
            QAction* quitAction = new QAction(tr("&Quit"), this);
            connect(quitAction, &QAction::triggered, qApp, &QApplication::quit);
            contextMenu->addAction(quitAction);
        
            QSystemTrayIcon* trayIcon = new QSystemTrayIcon(this);
            trayIcon->setIcon(this->windowIcon());
            trayIcon->setContextMenu(contextMenu);
            trayIcon->show();
        }
        

        I just can not understand, is it a bug, or my incompetence, or ...

        1 Reply Last reply
        0
        • G Offline
          G Offline
          goldstar2154
          wrote on last edited by goldstar2154
          #4

          i have the same problem but dont have a solution)

          Upd:
          Hello again, i found solution. You need to call setContextMenu() BEFORE any addAction(), so your code from last example must look like:

          MainWindow::MainWindow(QWidget *parent)
              : QMainWindow(parent)
          {
              QMenu* contextMenu = new QMenu("Menu", this);
          
              QSystemTrayIcon* trayIcon = new QSystemTrayIcon(this);
              trayIcon->setIcon(this->windowIcon());
              trayIcon->setContextMenu(contextMenu);   // <---
          
              QAction* quitAction = new QAction(tr("&Quit"), this); 
              connect(quitAction, &QAction::triggered, qApp, &QApplication::quit);
              contextMenu->addAction(quitAction);   // <---
          
              trayIcon->show();
          }
          

          Why did it happens?
          I'm looked into source code of QSystemTrayIcon (qtbase/src/widgets/util/qsystemtrayicon.cpp) and see this:

          void QSystemTrayIcon::setContextMenu(QMenu *menu)
          {
              Q_D(QSystemTrayIcon);
              d->menu = menu;
              d->updateMenu_sys();
          }
          

          And i think d->updateMenu_sys() is a problem. If QMenu have actions when you call setContextMenu you get copies without ownership (or you lost ownership from existing actions). And that leads to memory leak.

          P.S. sorry for my poor english, i'm just a russian hacker bear student. Hope this information will help you.

          1 Reply Last reply
          0

          • Login

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • Users
          • Groups
          • Search
          • Get Qt Extensions
          • Unsolved