25

In Qt, if I right-click on a toolbar the menu will be shown that allows me to hide the toolbar. I need to disable this functionality because I don't want the toolbar to possible to hide. Is there a way to do this?

Daniel Hedberg
  • 5,677
  • 4
  • 36
  • 61
Sergey Skoblikov
  • 5,811
  • 6
  • 40
  • 49

6 Answers6

36

I was able to set the ContextMenuPolicy directly on the toolbar (not the main window), as long as I used either Qt::PreventContextMenu or Qt::ActionsContextMenu. Prevent eliminated the context menu and made right-click have no effect on the toolbar, while Actions made a nice context menu composed of the actions already in my toolbar. Qt::NoContextMenu didn't seem to have any effect.

toolbar->setContextMenuPolicy(Qt::PreventContextMenu);

Nolan Amy
  • 10,785
  • 5
  • 34
  • 45
  • 8
    This works, but you have to be aware that you're only preventing the context menu to appear for this one tool bar. If the user triggers the context menu anywhere else (like on another tool bar or a dock widget title bar), he will still be able to hide your "unhidable" tool bar. – Thorbjørn Lindeijer Oct 29 '14 at 20:57
17

Use setContextMenuPolicy (Qt::NoContextMenu) for the main window of the toolbar.

Ariya Hidayat
  • 12,523
  • 3
  • 46
  • 39
  • 5
    I mistyped and corrected it. NoContextMenu should be for the main window, not the toolbar. – Ariya Hidayat Mar 17 '09 at 22:52
  • 3
    Strange.. why does setting it on the QToolBar itself not work? – paulm Feb 11 '13 at 12:43
  • 5
    Interestingly, if you set `contextMenuPolicy` of the toolbar to `NoContextMenu`, the context menu still appears. **BUT** if you set it to `CustomContextMenu` and don't implement a custom context menu function, no context menu appears... strange. – waddlesplash Oct 05 '13 at 22:02
13

There are several ways to achieve this without having to alter the contextMenu functionality. See the following 3 PySide examples:

1. Disable the toggleViewAction of the QToolBar:

UnhidableToolBar = QToolBar()
UnhidableToolBar.toggleViewAction().setEnabled(False)

2. Connect to the visibilityChanged signal:

toolbar.visibilityChanged.connect(lambda: toolbar.setVisible(True))

3. Subclass QToolBar and use the hideEvent:

class UnhideableQToolBar(QToolBar):
    def hideEvent(self, event):
        self.setVisibile(True)

Recommendation:

While 2 & 3 are pretty dirty, solution 1 shows the toolbar in the context menu like a QDockWidget that has the feature DockWidgetClosable set. So either use solution 1 or if you want to remove the action have a look at Steven's answer.

johnson
  • 3,729
  • 3
  • 31
  • 32
11

Override QMainWindow::createPopupMenu() e.g.

QMenu* MyApp::createPopupMenu()
{
  QMenu* filteredMenu = QMainWindow::createPopupMenu();
  filteredMenu->removeAction( mUnhidableToolBar->toggleViewAction() );
  return filteredMenu;
}

Note that the other answers that suggest disabling the context menu will only work if you want to disable hiding/showing of all toolbars and all dock widgets.

Steven
  • 423
  • 3
  • 8
  • Nice, clean answer. Tip: You can avoid keeping track of all added toolbars by searching for `QToolbar` children in `createPopupMenu`. Looking in direct children of the `QMainWindow` only seems to work. – Alex Goldberg Apr 04 '17 at 06:15
4

Inherit QToolbar and reimplement contextMenuEvent().

  • 1
    Just to contribute with the answer (5 years later): you can avoid the inheritance by installing a filter event, and retaining the event (return true): http://qt-project.org/doc/qt-5/eventsandfilters.html#event-filters – cbuchart Apr 30 '14 at 08:03
  • This answer would really benefit from an example. – Xeberdee Apr 10 '18 at 07:19
0

The simplest thing to do is:

self.toolbar.toggleViewAction().setVisible(False)

Unlike self.toolbar.toggleViewAction().setEnabled(False), which still shows the disabled popup if you're right-clicking the toolbar for any reason.

Vaidøtas I.
  • 544
  • 7
  • 23