Reputation: 492
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
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:
Upvotes: 1