Search code examples
pythonpyqtpyqt5qmenuqkeysequence

Right justify QKeySequence in PyQt QAction Menu


How I can right justify the QKeySequence in PyQt5?

copy_absolute_path_action = (
    create_action(self, _("Copy Absolute Path"), QKeySequence(
        get_shortcut('explorer', 'copy absolute path')),
                  triggered=self.copy_absolute_path))
copy_relative_path_action = (
    create_action(self, _("Copy Relative Path"), QKeySequence(
        get_shortcut('explorer', 'copy relative path')),
                  triggered=self.copy_relative_path))
copy_file_clipboard_action = (
    create_action(self, _("Copy File to Clipboard"),
                  QKeySequence(get_shortcut('explorer', 'copy file')),
                  icon=ima.icon('editcopy'),
                  triggered=self.copy_file_clipboard))
save_file_clipboard_action = (
    create_action(self, _("Paste File from Clipboard"),
                  QKeySequence(get_shortcut('explorer', 'paste file')),
                  icon=ima.icon('editpaste'),
                  triggered=self.save_file_clipboard))

enter image description here

I want the key shortcuts to be right justified and the rest unchanged.

Thanks in advance


Solution

  • In this case the solution is to implement a QProxyStyle:

    from PyQt5 import QtCore, QtGui, QtWidgets
    
    class MenuProxyStyle(QtWidgets.QProxyStyle):
        def drawControl(self, element, option, painter, widget=None):
            shortcut = ""
            if element == QtWidgets.QStyle.CE_MenuItem:
                vals = option.text.split("\t")
                if len(vals) == 2:
                    text, shortcut = vals
                    option.text = text
            super(MenuProxyStyle, self).drawControl(element, option, painter, widget)
            if shortcut:
                margin = 10 # QStyleHelper::dpiScaled(5)
                self.proxy().drawItemText(painter, option.rect.adjusted(margin, 0, -margin, 0), 
                    QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter,
                    option.palette, option.state & QtWidgets.QStyle.State_Enabled, 
                    shortcut, QtGui.QPalette.Text)
    
    class MainWindow(QtWidgets.QMainWindow):
        def __init__(self, parent=None):
            super(MainWindow, self).__init__(parent)
    
            menu = QtWidgets.QMenu("File", self)
            self._proxy = MenuProxyStyle(menu.style())
            menu.setStyle(self._proxy)
            self.menuBar().addMenu(menu)
    
            # create icons
            data = [("Copy Absolute Path", "Ctrl+Alt+C"),
                     ("Copy Relative Path", "Ctrl+Shift+C"),
                     ("Copy File to Clipboard", "Ctrl+C")]
    
            for text, shortcut in data:
                action = QtWidgets.QAction(self, 
                    text=text, 
                    shortcut=QtGui.QKeySequence(shortcut))
                menu.addAction(action)
    
    if __name__ == '__main__':
        import sys
        app = QtWidgets.QApplication(sys.argv)
        w = MainWindow()
        w.resize(640, 480)
        w.show()
        sys.exit(app.exec_())
    

    enter image description here