1

I have the following code adapted from here which works by right justifying shortcuts in QMenu. It works well when no StyleSheet is applied.

enter image description here

but when I add the line app.setStyleSheet(qdarkstyle.load_stylesheet_pyqt5()) it never works. enter image description here

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)
            return 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.menuBar().addMenu(menu)

        # create icons
        data = [("Absolute", "Ctrl+Alt+C"),
                 ("Relative", "Ctrl+Shift+C"),
                 ("Copy", "Ctrl+C")]

        for text, shortcut in data:
            action = QtWidgets.QAction(self)
            action.setText(text+"\t"+shortcut)
            menu.addAction(action)

if __name__ == '__main__':
    import sys, qdarkstyle
    app = QtWidgets.QApplication(sys.argv)
    app.setStyle(MenuProxyStyle())
    app.setStyleSheet(qdarkstyle.load_stylesheet_pyqt5())

    w = MainWindow()
    w.resize(640, 480)
    w.show()
    sys.exit(app.exec_())

I would like to know how to combine QStyle with QStyleSheet?

Khalil Al Hooti
  • 4,207
  • 5
  • 23
  • 40

1 Answers1

3

Qt StyleSheet and QProxyStyle are different layers and can not be combined, when the Qt Style Sheet is established, a QStyleSheetStyle object is created that does not allow it to be overwritten, so you will observe that no method of the QProxyStyle is invoked.

So the solution is to establish the same functionality only using Qt Style Sheet, so you should modify the style sheet provided by qdarkstyle, in this case you will use the qstylizer library.

If you have python2 then you must install using:

pip install qstylizer

If you use python3 you can not use the library directly since it has a bug because it uses unicode that no longer exists in python3, but I have a fork that solves it that you can install using:

pip install git+https://github.com/eyllanesc/qstylizer.git

Considering the above, the solution is:

# ...

if __name__ == "__main__":
    import sys
    import qdarkstyle
    import qstylizer.parser

    app = QtWidgets.QApplication(sys.argv)

    qss = qstylizer.parser.parse(qdarkstyle.load_stylesheet_pyqt5())
    qss.QMenu.item.padding.setValue("4px 4px 4px 4px;")
    app.setStyleSheet(qss.toString())

    w = MainWindow()
    w.resize(640, 480)
    w.show()
    sys.exit(app.exec_())
Khalil Al Hooti
  • 4,207
  • 5
  • 23
  • 40
eyllanesc
  • 235,170
  • 19
  • 170
  • 241