tckraomuqnt
tckraomuqnt

Reputation: 492

How to move cursor form first menu to next menu by pressing Right arrow Key once, Instead of Twice?

The following Code is to create a MenuBar in Pyqt5. Want to move the cursor from one menu to another menu by pressing Left/Right Arrow Keys. IF We press the Left Arrow key once, Cursor moves smoothly and focus on pervious Menu. But at the same time, if we press the Right Arrow Keys once, Cursor will not Move to the next menu. Instead of once, We press twice the time, to move the cursor from one menu to the next menu.

For Example: In my script, From, file menu, we press the right arrow keys twice the time, then only the next menu (Accounts menu) Will get focused and so on. But at the same time, if we press the Left arrow key once ( Accounts to file), the previous menu get focused.

My intention: If We press either the Right arrow key or the Left Arrow key once (Instead of twice press), the cursor will move to next or perivous menu. How to resolve it ?

import sys
import os

from PyQt5.QtWidgets import (QMainWindow,QApplication,
                            QWidget,
                            QMdiArea,QMdiSubWindow,
                            QMenuBar,QMenu,QAction,
                             QVBoxLayout,QTabWidget,QTabBar,QTreeView)

from PyQt5.QtCore import pyqtSignal,Qt
from PyQt5.QtGui import QIcon,QPixmap,QColor

def create_icon_by_color(color):
    pixmap = QPixmap(512,512)
    pixmap.fill(color)
    return QIcon(pixmap)

class ME_MainScreen(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Make Easy - Main Screen")
        self.setWindowState(Qt.WindowMaximized)
        self.setMinimumSize(1000,300)

        self.mdi = QMdiArea()
        self.mdi.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self.mdi.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)

        self.main_layout = QVBoxLayout()
        self.main_layout.addWidget(self.mdi)
        widget = QWidget()
        widget.setLayout(self.main_layout)
        self.setCentralWidget(widget)

        self.me_mainscreen_menubar_createActions()
        self.me_mainscreen_menubar_createMenus()



    def me_mainscreen_menubar_createActions(self):
        self.exitAct = QAction("E&xit", self, shortcut="Ctrl+Q",statusTip="Exit the application", triggered=self.close)

    def me_mainscreen_menubar_createMenus(self):
        # Create menu bar and add action
        self.me_mainscreen_menuBar = self.menuBar()
        self.me_mainscreen_menuBar.setObjectName("on_self.me_mainscreen_menuBar")

        self.menu_file          = self.me_mainscreen_menuBar.addMenu('&File')
        self.menu_accounts      = self.me_mainscreen_menuBar.addMenu('&Accounts')
        self.menu_inventory     = self.me_mainscreen_menuBar.addMenu('&Inventory')
        self.menu_manufacture   = self.me_mainscreen_menuBar.addMenu('&Manufacture')
        self.menu_payroll       = self.me_mainscreen_menuBar.addMenu('&PayRoll')
        self.menu_others        = self.me_mainscreen_menuBar.addMenu("&Others")
        self.menu_help          = self.me_mainscreen_menuBar.addMenu("&Help")

        self.menu_file_transcation  = self.menu_file.addMenu("&Transcation")
        self.menu_file_reports      = self.menu_file.addMenu("&Reports")
        self.menu_file_master       = self.menu_file.addMenu("Mast&er")
        self.menu_file_settings     = self.menu_file.addMenu("&Settings")
        self.menu_file.addSeparator()
        self.menu_file.addAction(self.exitAct)

        self.menu_accounts_transcation  = self.menu_accounts.addMenu("&Transcation")
        self.menu_accounts_reports      = self.menu_accounts.addMenu("&Reports")
        self.menu_accounts_master       = self.menu_accounts.addMenu("Mast&er")
        self.menu_accounts_settings     = self.menu_accounts.addMenu("&Settings")

        self.menu_inventory_transcation  = self.menu_inventory.addMenu("&Transcation")
        self.menu_inventory_reports      = self.menu_inventory.addMenu("&Reports")
        self.menu_inventory_master       = self.menu_inventory.addMenu("Mast&er")
        self.menu_inventory_settings     = self.menu_inventory.addMenu("&Settings")


def main():
    app = QApplication(sys.argv)
    _mainscreen = ME_MainScreen()
    app.setStyle("Fusion")
    _mainscreen.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

Upvotes: 1

Views: 462

Answers (1)

musicamante
musicamante

Reputation: 48231

The problem is that when the right arrow is pressed, QMenu checks if the current action is a submenu (action.menu() returns a QMenu or None) and eventually tries to open it. Since all the sub menus you added are empty, nothing happens until the arrow is pressed again.

A possible solution is to use the aboutToShow signal of the parent menu and connect it to a function that checks whether each action is a menu and if it has items, then eventually enable or disable it:

class ME_MainScreen(QMainWindow):
    # ...
    def me_mainscreen_menubar_createMenus(self):
        # ...
        self.menu_file.aboutToShow.connect(self.check_file_menu)

    def check_file_menu(self):
        for action in self.menu_file.actions():
            if action.menu():
                action.setEnabled(bool(action.menu().actions()))

In this way, if the sub menu has no action, it gets disabled (which is also a proper behavior, as if users see an enabled sub menu, they would assume that it contains some items), and keyboard navigation would work properly:

  • if there are no enabled items (all items are disabled), no item gets selected and the right arrow will switch to the next menu;
  • if there are enabled items, the first one will be highlighted;
  • if an highlighted item is a sub menu with actions (so, enabled), the right arrow will open it;
  • if the highlighted item is just a simple action, the right arrow will switch to the next menu;

Upvotes: 1

Related Questions