5

I'm trying to add ToolTips on MenuBar Items using the tool properties but it didn't work... But on labels, pushbuttons and other widgets it seems to work pretty fine. Can anyone help me with this?

ΦXocę 웃 Пepeúpa ツ
  • 47,427
  • 17
  • 69
  • 97
  • I made an MCVE to reproduce your claim. Tooltips for items and menus in menubar didn't work with Windows/Qt 5.13 nor with cygwin/X11/Qt 5.9. – Scheff's Cat Mar 02 '20 at 07:45
  • Found a similar question in QtForum: [(Solved) setToolTip in QAction menu](https://forum.qt.io/topic/6821/solved-settooltip-in-qaction-menu). It adds the tooltips by custom code via a derived menu bar. – Scheff's Cat Mar 02 '20 at 07:47
  • 1
    Put your code example , your attempt ... – Nikola Lukic Mar 02 '20 at 07:57
  • 1
    You can use `setToolTipsVisible(true);` see [here](https://stackoverflow.com/questions/21725119/why-wont-qtooltips-appear-on-qactions-within-a-qmenu). – florisla Dec 18 '20 at 14:12

1 Answers1

4

Due to the lack of an MCVE, I prepared my own and was able to reproduce the issue of OP. (I tested with Windows/VS2017/Qt 5.13 and in cygwin/X11/Qt 5.9.)

Researching the web, I found a similar Q/A in the Qt Forum:

(Solved) setToolTip in QAction menu.

As I already had an MCVE, I tried that solution and got it working (in Windows/VS2017/Qt 5.13).

testQMenuBarToolTip.cc:

// Qt header:
#include <QtWidgets>

/// menu bar with tooltips
class MenuBar: public QMenuBar {
  public:
    explicit MenuBar(QWidget *pQParent = nullptr): QMenuBar(pQParent) { }
    virtual ~MenuBar() = default;
    MenuBar(const MenuBar&) = delete;
    MenuBar& operator=(const MenuBar&) = delete;

  protected:
    virtual bool event(QEvent *pQEvent) override;
};

bool MenuBar::event(QEvent *pQEvent)
{
  // keep behavior of base class
  bool ret = QMenuBar::event(pQEvent);
  // check whether this is a help event
  if (pQEvent->type() == QEvent::ToolTip) {
    const QHelpEvent *const pQHelpEvent = (const QHelpEvent*)pQEvent;
    const QAction *pQAction = activeAction();
    if (pQAction && !pQAction->toolTip().isEmpty()) {
      QToolTip::showText(pQHelpEvent->globalPos(), pQAction->toolTip());
      return ret;
    }
  }
  QToolTip::hideText();
  return ret;
}

/// menu with tooltips
class Menu: public QMenu {
  public:
    explicit Menu(const QString &title, QWidget *pQParent = nullptr):
      QMenu(title, pQParent)
    { }
    explicit Menu(QWidget *pQParent = nullptr): QMenu(pQParent) { }
    virtual ~Menu() = default;
    Menu(const Menu&) = delete;
    Menu& operator=(const Menu&) = delete;

  protected:
    virtual bool event(QEvent *pQEvent) override;
};

bool Menu::event(QEvent *pQEvent)
{
  // keep behavior of base class
  bool ret = QMenu::event(pQEvent);
  // check whether this is a help event
  if (pQEvent->type() == QEvent::ToolTip) {
    const QHelpEvent *const pQHelpEvent = (const QHelpEvent*)pQEvent;
    const QAction *pQAction = activeAction();
    if (pQAction && !pQAction->toolTip().isEmpty()) {
      QToolTip::showText(pQHelpEvent->globalPos(), pQAction->toolTip());
      return ret;
    }
  }
  QToolTip::hideText();
  return ret;
}

// main application
int main(int argc, char **argv)
{
  qDebug() << "Qt Version:" << QT_VERSION_STR;
  QApplication app(argc, argv);
  // setup GUI
  QMainWindow qWinMain;
  qWinMain.resize(320, 240);
  qWinMain.setWindowTitle("Test QMenuBar with ToolTips");
  MenuBar qMenuBar;
  QAction qCmdFile("File");
  qCmdFile.setToolTip("provides file commands.");
  Menu qMenuFile;
  QAction qCmdExit("Quit");
  qCmdExit.setToolTip("closes application.");
  qMenuFile.addAction(&qCmdExit);
  qCmdFile.setMenu(&qMenuFile);
  qMenuBar.addAction(&qCmdFile);
  qWinMain.setMenuBar(&qMenuBar);
#if 0 // comparison with toolbar
  QToolBar qToolBar;
  qToolBar.addAction(&qCmdExit);
  qWinMain.addToolBar(&qToolBar);
#endif // 0
  qWinMain.show();
  // runtime loop
  return app.exec();
}

testQMenuBarToolTip.pro:

SOURCES = testQMenuBarToolTips.cc

QT += widgets

Output: (Windows 10, VS2017, Qt 5.13)

Snapshot of testQMenuBarToolTips (Mouse over menu bar item) Snapshot of testQMenuBarToolTips (Mouse over menu item)

Built and tested in cygwin64 with:

$ qmake-qt5 

$ make && ./testQMenuBarToolTips
g++ -c -fno-keep-inline-dllexport -D_GNU_SOURCE -pipe -O2 -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -I. -isystem /usr/include/qt5 -isystem /usr/include/qt5/QtWidgets -isystem /usr/include/qt5/QtGui -isystem /usr/include/qt5/QtCore -I. -I/usr/lib/qt5/mkspecs/cygwin-g++ -o testQMenuBarToolTips.o testQMenuBarToolTips.cc
g++  -o testQMenuBarToolTips.exe testQMenuBarToolTips.o   -lQt5Widgets -lQt5Gui -lQt5Core -lGL -lpthread 
Qt Version: 5.9.4

Output: (cygwin64, X11, g++, Qt 5.9)

Snapshot of testQMenuBarToolTips (Mouse over menu bar item) Snapshot of testQMenuBarToolTips (Mouse over menu item)

Notes:

  • I applied some fine-tuning to the answer I copied from (e.g. adding missing return statements).

  • While fiddling with my sample, I realized the same issue with the sub-menu and copy/paste programmed the solution for QMenu as well.

Scheff's Cat
  • 19,528
  • 6
  • 28
  • 56
  • I'm sorry for my late response but i got to postpone my work on this project for a while... But eventually I tried it and it worked. But now I'm facing a new problem if I use this method which is how shall I add actions for this submenus... Like for example closing application –  Mar 13 '20 at 06:43
  • @temp _how shall I add actions for this submenus_: That's simple - you have to connect to the [QAction::triggered](https://doc.qt.io/qt-5/qaction.html#triggered) signal. Alternatively, you can use [QMenu::addAction()](https://doc.qt.io/qt-5/qmenu.html#addAction-6) and provide the signal handler (in Qt terms: signal slot) immediately. (It returns the pointer to created action which can be used to set the tool tip afterwards.) Have a look at [SO: how to create menu in statusbar in qt like PC start menu](https://stackoverflow.com/a/44451423/7478597) to see examples for both methods. – Scheff's Cat Mar 13 '20 at 07:27
  • thank you for your help you've been a great help for me –  Mar 13 '20 at 07:56