Search code examples
pythoncssqtpyqtstylesheet

How to apply CSS Style to QMenu via an entire MainWIndow


Running the example code below creates a single button window. Clicking up the button brings up a pull-down menu.

enter image description here

When CSS 'appStyle' is applied to menu directly it seems to be working well:

menu.setStyleSheet(appStyle)

But when the same CSS 'appStyle' is assigned to the entire window using:

view.setStyleSheet(appStyle)

nothing happens (just comment out the menu.setStyleSheet(appStyle) to see it). It would be great if the CSS stylesheet would be once for an entire view and not for each menu or every widget separately. How to achieve it?

bgColor='#1F1F1F'
appStyle="""
QMenu {{  font-size:10pt; selection-background-color: #ffaa00; selection-color: black; background-color: #7A7A7A; border-style: solid; border: 0px solid #EBEBEB; border-radius: 0; color: #EBEBEB; padding: 0px 0px 0px 0px; }}
QMenu:on  {{padding-top: 0px; padding-left: 0px; background-color: #7A7A7A; selection-background-color: #ffaa00; color: #EBEBEB; border-radius: 0;}}
QMenu QAbstractItemView  {{ border: 0px solid black; background-color: #7A7A7A; color: #EBEBEB; border-radius: 0; }}
QMenu:hover {{ border: 0px solid #ffa02f; }}
QMenu::drop-down  {{ border-radius: 0px; background-color: #7A7A7A; color: #EBEBEB; }}""".format(bgColor) 


from PyQt4.QtCore import *
from PyQt4.QtGui import *

class Window(QMainWindow):
    def __init__(self):
        super(Window, self).__init__() 
        button=QToolButton(self)
        button.setText('Click Here')

        menu=QMenu()
        menu.addAction("Action01")
        menu.addAction("Action02")
        menu.addAction("Action03")

        separator=menu.addAction("")
        separator.setSeparator(True)

        subMenu=menu.addMenu('SubMenu')
        subMenu.addAction("SubAction01")
        subMenu.addAction("SubAction02")
        subMenu.addAction("SubAction03")   

        button.setMenu(menu)
        button.setPopupMode(QToolButton.InstantPopup)
        menu.setStyleSheet(appStyle)   


app=QApplication(sys.argv)    
view=Window() 
view.setStyleSheet(appStyle)
view.show()
sys.exit(app.exec_())

Solution

  • Pass an instance of view self on QMenu declaration. So, instead of:

    menu=QMenu()
    

    do:

    menu=QMenu(self)
    

    Now when a stylesheet is applied to a main window its stylesheet is propagated down its children - a menu and button instances in this case.

    enter image description here

    The working code is below:

    bgColor='#1F1F1F'
    appStyle="""
    QToolButton {{border: 0px solid #0F0F0F; background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #7A7A7A, stop: 1 #0F0F0F); color: #EBEBEB}}
    QMenu QAbstractItemView  {{ border: 0px solid black; background-color: #7A7A7A; color: #EBEBEB; border-radius: 0; }}
    QMenu {{  font-size:10pt; selection-background-color: #ffaa00; selection-color: black; background-color: #7A7A7A; border-style: solid; border: 0px solid #EBEBEB; border-radius: 0; color: #EBEBEB; padding: 0px 0px 0px 0px; }}
    QMenu:on  {{padding-top: 0px; padding-left: 0px; background-color: #7A7A7A; selection-background-color: #ffaa00; color: #EBEBEB; border-radius: 0;}}
    QMenu:hover {{ border: 0px solid #ffa02f; }}
    QMenu::drop-down  {{ border-radius: 0px; background-color: #7A7A7A; color: #EBEBEB; }}""".format(bgColor) 
    
    class Window(QMainWindow):
        def __init__(self):
            super(Window, self).__init__() 
            button=QToolButton(self)
            button.setText('Click Here')
    
            menu=QMenu(self)
            menu.addAction("Action01")
            menu.addAction("Action02")
            menu.addAction("Action03")
    
            separator=menu.addAction("")
            separator.setSeparator(True)
    
            subMenu=menu.addMenu('SubMenu')
            subMenu.addAction("SubAction01")
            subMenu.addAction("SubAction02")
            subMenu.addAction("SubAction03")   
    
            button.setMenu(menu)
            button.setPopupMode(QToolButton.InstantPopup)
    
    app=QApplication(sys.argv)
    view=Window() 
    view.setStyleSheet(appStyle)
    view.show()
    sys.exit(app.exec_())