0
votes

I want to change a Button's background color and text color without changing/resetting the whole style.

Currently, I'm using this:

dl_btt.setStyleSheet("background-color: green; color: white")

But that changes the whole style of the button:

enter image description here

Since the default style looks like this:

enter image description here

I would like to have something like this:

enter image description here

So, if I were to change OS, I want it to use default style and only change the background color.

Can I do this without manually replicating the style?

EDIT:

@Controlix Thank you for pointing me in the right direction. However, I can't seem to be able to change the background color.

I'm only able to change the border and text color using:

dl_btt = DownloadButton(self, "Skini")

#dl_btt.setStyleSheet("background-color: green; color: white")
#dl_btt.setPalette(QtGui.QPalette(QtCore.Qt.green))

palette = dl_btt.palette()

role = dl_btt.foregroundRole()
palette.setColor(role, QtGui.QColor('white'))

role = dl_btt.backgroundRole()
palette.setColor(role, QtGui.QColor('green'))

dl_btt.setAutoFillBackground(True)
dl_btt.setPalette(palette)

Which gives me this result:

enter image description here

Searching gave me same or similar snippets of code that don't do what I expected it to do.

EDIT 2:

I gave up on this search and used style sheets, rebuilding the styles as I see fit.

I'm still wondering though... Is it possible, in PyQt, to replicate native style while changing only certain part of a widget?

EDIT 3

I tried:

    palette = dl_btt.palette()
    role = dl_btt.foregroundRole()
    palette.setColor(role, QtGui.QColor('white'))

    role = dl_btt.buttonRole()
    palette.setColor(role, QtGui.QColor('green'))

    dl_btt.setAutoFillBackground(True)
    dl_btt.setPalette(palette)

But I got this error:

AttributeError: 'DownloadButton' object has no attribute 'buttonRole'

How can I access the button role? How is it called?

Just in case you need it, here is the DownloadButton class:

class DownloadButton(QtGui.QPushButton):
    def __init__(self, master, *args, **kwargs):
        super(DownloadButton, self).__init__(*args, **kwargs)
        self.master = master

    def mousePressEvent(self, ev):
        self.master.startDownload()
2
Change it with QPalette not with the StyleSheetControlix
The QPalette has a button role. I think that should work.justengel
Seems there isn't a button role. Or I can't find one at least..Božo Stojković

2 Answers

0
votes

I tried this which is working. I have set the buttons styles in the UI section. if I want to change only the color of a button the following works.

The following works though not an elegant way :

        btns = ['self.hBeamBtn','self.lBeamBtn','self.allTestBtn','self.prnStatusBtn']
        for btn in btns:
            if  str(btn_name) == str(btn):
                styl = btn+'.setStyleSheet("font: bold;background-color: red;font-size: 12px;height: 28px;width: 80px;")'
                eval(styl)
0
votes

Here is a silly but working way to do it:

    def change_button_color(button, color):
        """change_button_color

            Change a button's color
        :param button: target button
        :type button: QPushButton
        :param color: new color (any format)
        :type color: str
        :return: None
        """
        style_sheet = button.styleSheet()
        pairs = [pair.replace(' ', '') for pair in style_sheet.split(';') if pair]

        style_dict = {}
        for pair in pairs:
            key, value = pair.split(':')
            style_dict[key] = value

        style_dict['background-color'] = color
        style_sheet = '{}'.format(style_dict)

        chars_to_remove = ('{', '}', '\'')
        for char in chars_to_remove:
            style_sheet = style_sheet.replace(char, '')
        style_sheet = style_sheet.replace(',', ';')

        button.setStyleSheet(style_sheet)