2

I'm looking for a way to control the direction that sub-menus are opened from in a QMenu. The default behavior is to open to the right, unless there isn't enough screen real estate, then open to the left.

If you have a menu that's on the far right of the screen, (example: chrome's settings wrench), if you have several nested menus, the default behavior causes them to ping back and forth between opening from the left and opening from the right, which is a maddening user experience .

What I'd like is a way to tell QMenu to always open submenus to the LEFT; there is definitely not a direct control for this in QMenu, but Qt often has a lot of magical 'application' or 'global' settings for platform-specific behavior. I was wondering if anyone knew!

I have done this before in C# using ToolStripMenu, so I know that some toolkits have this ability.

Community
  • 1
  • 1
guyincognito
  • 203
  • 3
  • 6

1 Answers1

3

There is one option I can think of. You can set a particular menu's direction via setLayoutDirection(QtCore.Qt.RightToLeft) and it will always expand to left if there is space.

Though, I must say, it doesn't look pretty when the top level menus aligned left to right, where as sub-menus are right to left. At least, not on my Windows 7:

import sys
from PyQt4 import QtGui, QtCore

app = QtGui.QApplication(sys.argv)
main = QtGui.QMainWindow()
menubar = QtGui.QMenuBar()

menus = []
submenus = {}
for x in range(10):
    # top menus
    menu = QtGui.QMenu('Top %d' % x)
    menus.append(menu)

    # set direction
    menu.setLayoutDirection(QtCore.Qt.RightToLeft)

    # add to menubar
    menubar.addMenu(menu)

    for y in range(5):
        # a sub-menu
        submenu = QtGui.QMenu('Level 1 - %d' % y)

        # some dummy actions
        submenu.addAction('Level 2 - 1')
        submenu.addAction('Level 2 - 2')

        # keep reference
        submenus[(x,y)] = submenu
        # add to the top menu
        menu.addMenu(submenu)

main.setMenuBar(menubar)
main.show()

sys.exit(app.exec_())

enter image description here

Avaris
  • 35,883
  • 7
  • 81
  • 72
  • This is almost a neat solution, but it does not fully work for me on Linux. The top-level menu opens to the left, but submenus don't - not even when I apply `setLayoutDirection` to them. – ekhumoro Jan 06 '12 at 17:38
  • @ekhumoro: That is interesting. I tested this on Ubuntu. Regardless of how I set direction, they all behaved `LeftToRight`. I even set the direction of `QApplication` to `RightToLeft`, which should propagate to the children and it does, but no luck. Maybe Linux overrides this depending on the locale? Though I am not sure, since I am not much of a Linux user... – Avaris Jan 06 '12 at 18:52
  • This is the best solution I could get to work in a cross-platform way. It doesn't show the icons on the LHS the way C# does, but it does give the correct behavior otherwise. – guyincognito May 21 '12 at 23:30