Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Theme customization #54

Closed
alexitx opened this issue Jan 4, 2022 · 13 comments
Closed

Theme customization #54

alexitx opened this issue Jan 4, 2022 · 13 comments
Assignees
Labels
enhancement New feature or request question Further information is requested

Comments

@alexitx
Copy link

alexitx commented Jan 4, 2022

I like this theme because it's simpler and lighter, but is or will there be a way to easily customize it? Perhaps the generated stylesheets can still have placeholders which are formatted on load after the user of the library passes the wanted customizations.

Mainly the default accent color and maybe the borders and padding of widgets. QFrame and QGroupBox for example have border and padding even with the frame set to NoFrame which makes grouping widgets a bit cluttered. Otherwise manually applying a stylesheet after qdarktheme creates issues with spacing and borders near scrollbars.

@5yutan5 5yutan5 self-assigned this Jan 4, 2022
@5yutan5
Copy link
Owner

5yutan5 commented Jan 4, 2022

Hi, thanks for the idea! Unfortunately, there is no way to easily customize stylesheets currently. You need to hack generated stylesheets. But I'm interested in it.

Perhaps the generated stylesheets can still have placeholders which are formatted on load after the user of the library passes the wanted customizations.

Yes, it is easy to add another placeholders. Do you have any ideas what kind of placeholders we should include?

I have an another idea to improve QFrame style. A smart way was introduced with stackoverflow. (QT Stylesheet for HLine/VLine color). This way can also be used for NoFrame.

Sample code
import sys

from PyQt5.QtWidgets import QApplication, QFrame, QGridLayout, QLabel, QMainWindow, QWidget

import qdarktheme

app = QApplication(sys.argv)
# Widgets
main_win = QMainWindow()
panel_frame = QFrame()
box_frame = QFrame()
no_frame = QFrame()
# Setup widgets
panel_frame.setFrameShape(QFrame.Panel)
box_frame.setFrameShape(QFrame.Box)
no_frame.setFrameShape(QFrame.NoFrame)
# Layout
layout = QGridLayout()
layout.addWidget(QLabel("Panel"), 0, 0)
layout.addWidget(QLabel("Box"), 0, 1)
layout.addWidget(QLabel("NoFrame"), 0, 2)
layout.addWidget(panel_frame, 1, 0)
layout.addWidget(box_frame, 1, 1)
layout.addWidget(no_frame, 1, 2)
central_widget = QWidget()
central_widget.setLayout(layout)
main_win.setCentralWidget(central_widget)
# Setup style
stylesheet = qdarktheme.load_stylesheet()
custom_stylesheet = """
QFrame {
    border: 1px solid gray;
    padding: 1px;
    border-radius: 4px;
}
/* NoFrame */
QFrame[frameShape="0"] {
    border: none;
    padding: 0;
}
/* Panel */
QFrame[frameShape="2"] {
    background-color: gray
}
"""
app.setStyleSheet(stylesheet + custom_stylesheet)

main_win.show()
app.exec()

Frames_Qt5

But this code is not working in Qt6. Maybe this is bug of Qt6. So we need to use custom property(See qt documentation).

Sample code
import sys

from PySide6.QtWidgets import QApplication, QFrame, QGridLayout, QLabel, QMainWindow, QWidget

import qdarktheme

app = QApplication(sys.argv)
# Widgets
main_win = QMainWindow()
panel_frame = QFrame()
box_frame = QFrame()
no_frame = QFrame()
# Setup widgets
panel_frame.setFrameShape(QFrame.Panel)
box_frame.setFrameShape(QFrame.Box)
no_frame.setFrameShape(QFrame.NoFrame)
# Setup custom property
panel_frame.setProperty("shape", "panel")
no_frame.setProperty("shape", "no_frame")
# Layout
layout = QGridLayout()
layout.addWidget(QLabel("Panel"), 0, 0)
layout.addWidget(QLabel("Box"), 0, 1)
layout.addWidget(QLabel("NoFrame"), 0, 2)
layout.addWidget(panel_frame, 1, 0)
layout.addWidget(box_frame, 1, 1)
layout.addWidget(no_frame, 1, 2)
central_widget = QWidget()
central_widget.setLayout(layout)
main_win.setCentralWidget(central_widget)
# Setup style
stylesheet = qdarktheme.load_stylesheet()
custom_stylesheet = """
QFrame {
    border: 1px solid gray;
    padding: 1px;
    border-radius: 4px;
}
/* NoFrame */
QFrame[shape="no_frame"] {
    border: none;
    padding: 0;
}
/* Panel */
QFrame[shape="panel"] {
    background-color: gray
}
/* Override QFrame style */
QLabel {
    border: none;
}
"""
app.setStyleSheet(stylesheet + custom_stylesheet)

main_win.show()
app.exec()

Frames_Qt6

By including these custom properties into template stylesheets, we can easily change the style with setProperty(). QGroupBox could be improved as well.

Otherwise manually applying a stylesheet after qdarktheme creates issues with spacing and borders near scrollbars.

Can you provide a minimal code example that replicate this issue?

@5yutan5 5yutan5 added enhancement New feature or request question Further information is requested labels Jan 4, 2022
@5yutan5
Copy link
Owner

5yutan5 commented Jan 4, 2022

But this code is not working in Qt6. Maybe this is bug of Qt6.

I found a bug report in Qt Bug Tracker.
https://bugreports.qt.io/browse/QTBUG-98928?filter=-4&jql=text%20~%20%22qframe%22%20order%20by%20created%20DESC

@alexitx
Copy link
Author

alexitx commented Jan 5, 2022

Regarding placeholders, I'm not sure which will be useful to include, so the more the better? But since I'm looking for ways to style grouped and nested widgets (QPushButtons inside QFrame or QTextEdit/QPlainTextEdit together with buttons inside a QFrame using a layout) it makes sense to be able to remove the borders of most widgets to get a cleaner look, set background color, padding, scrollbar spacing (right of the content, left of the scrollbar, if that's possible) and accent colors for slider grooves, progress bars, enabled/disabled states, etc.

I have an another idea to improve QFrame style. A smart way was introduced with stackoverflow. (QT Stylesheet for HLine/VLine color). This way can also be used for NoFrame.

This or just plain css classes seems interesting and should do the job. But I'm fine with waiting for upstream fix since the Python bindings for Qt6 are still relatively new and have missing features.

Otherwise manually applying a stylesheet after qdarktheme creates issues with spacing and borders near scrollbars.

Can you provide a minimal code example that replicate this issue?

I came across a few issues with the borders of QPlainTextEdit and QScrollArea when removing the borders and padding of the parent widget. Here is a quick example:

QPlainTextEdit
import sys
import qdarktheme
from PySide6 import QtCore, QtGui, QtWidgets

class MainWindow(QtWidgets.QMainWindow):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        central_widget = QtWidgets.QWidget(self)

        text_area = QtWidgets.QPlainTextEdit(central_widget)
        text_area.setFrameShape(QtWidgets.QFrame.Shape.NoFrame)
        for i in range(20):
            text_area.appendPlainText(f'Line {i}')
        self.text_area = text_area

        central_widget_layout = QtWidgets.QVBoxLayout(central_widget)
        central_widget_layout.addWidget(self.text_area)
        central_widget.setLayout(central_widget_layout)
        self.central_widget = central_widget
        self.central_widget_layout = central_widget_layout
        self.setCentralWidget(self.central_widget)

def main():
    app = QtWidgets.QApplication(sys.argv)
    stylesheet = qdarktheme.load_stylesheet('dark')
    custom_stylesheet = '''
        QFrame {
            padding: 0;
            border: none;
        }
    '''
    app.setStyleSheet(stylesheet + custom_stylesheet)
    mw = MainWindow()
    mw.show()
    sys.exit(app.exec())

if __name__ == '__main__':
    main()

produces a missing border around the scrollbar:

QPlainTextEdit_2

QScrollArea
import sys
import qdarktheme
from PySide6 import QtCore, QtGui, QtWidgets

class MainWindow(QtWidgets.QMainWindow):

  def __init__(self, *args, **kwargs):
      super().__init__(*args, **kwargs)

      central_widget = QtWidgets.QWidget(self)

      scroll_area = QtWidgets.QScrollArea(central_widget)
      scroll_area.setWidgetResizable(True)
      scroll_area.setFrameShape(QtWidgets.QFrame.Shape.NoFrame)
      scroll_area_contents = QtWidgets.QWidget(scroll_area)
      scroll_area_contents_layout = QtWidgets.QVBoxLayout(scroll_area_contents)
      scroll_area_contents.setLayout(scroll_area_contents_layout)
      scroll_area.setWidget(scroll_area_contents)

      self.labels = []
      for i in range(20):
          label = QtWidgets.QLabel(scroll_area_contents, text=f'Label {i}')
          self.labels.append(label)
          scroll_area_contents_layout.addWidget(label)

      self.scroll_area = scroll_area
      self.scroll_area_contents = scroll_area_contents
      self.scroll_area_contents_layout = scroll_area_contents_layout

      central_widget_layout = QtWidgets.QVBoxLayout(central_widget)
      central_widget_layout.addWidget(self.scroll_area)
      central_widget.setLayout(central_widget_layout)
      self.central_widget = central_widget
      self.central_widget_layout = central_widget_layout
      self.setCentralWidget(self.central_widget)

def main():
  app = QtWidgets.QApplication(sys.argv)
  stylesheet = qdarktheme.load_stylesheet('dark')
  custom_stylesheet = '''
      QFrame {
          padding: 0;
          border: none;
      }
      QScrollArea {
          border: 1px solid #fff;
      }
  '''
  app.setStyleSheet(stylesheet + custom_stylesheet)
  mw = MainWindow()
  mw.show()
  sys.exit(app.exec())

if __name__ == '__main__':
  main()

produces missing corners of the border:

QScrollArea_2

I'm not 100% sure if I'm not doing something wrong or it's the platform/version of Qt or something else though. Could also be the selector affecting all QFrames.
Running Windows 10 x64, PySide 6.2.2.1, Qt 6.2.2

@5yutan5
Copy link
Owner

5yutan5 commented Jan 5, 2022

Thanks for your some ideas.

I'm looking for ways to style grouped and nested widgets (QPushButtons inside QFrame or QTextEdit/QPlainTextEdit together with buttons inside a QFrame using a layout) it makes sense to be able to remove the borders of most widgets to get a cleaner look

I think this can basically be solve with property selector. I found a solution to use property selector in Qt6. It seems that the frameShape property values are different between Qt5 and Qt6.

Panel style
import sys

from PySide6.QtWidgets import QApplication, QFrame, QGridLayout, QLabel, QMainWindow, QWidget

import qdarktheme

app = QApplication(sys.argv)
# Widgets
main_win = QMainWindow()
panel_frame = QFrame()
box_frame = QFrame()
no_frame = QFrame()
# Setup widgets
panel_frame.setFrameShape(QFrame.Panel)
box_frame.setFrameShape(QFrame.Box)
no_frame.setFrameShape(QFrame.NoFrame)
# Layout
layout = QGridLayout()
layout.addWidget(QLabel("Panel"), 0, 0)
layout.addWidget(QLabel("Box"), 0, 1)
layout.addWidget(QLabel("NoFrame"), 0, 2)
layout.addWidget(panel_frame, 1, 0)
layout.addWidget(box_frame, 1, 1)
layout.addWidget(no_frame, 1, 2)
central_widget = QWidget()
central_widget.setLayout(layout)
main_win.setCentralWidget(central_widget)
# Setup style
stylesheet = qdarktheme.load_stylesheet()
custom_stylesheet = """
QFrame {
    border: 1px solid gray;
    padding: 1px;
    border-radius: 4px;
}
/* NoFrame, Qt5 is "0" */
QFrame[frameShape="NoFrame"] {
    border: none;
    padding: 0;
}
/* Panel, Qt5 is "2" */
QFrame[frameShape="Panel"] {
    background-color: gray
}
"""
app.setStyleSheet(stylesheet + custom_stylesheet)

main_win.show()
app.exec()

QPushButton and QGroupBox have the similar properties for flat style. The flat style of QPushButton has already been included in qdarktheme. You can check using QPushButton.setFlat(). Widgets that inherit from QFrame, such as QTextEdit and QTableView, can use NoFrame. Therefore in this case, I think placeholder is no need. It can be included into a template stylesheet.
But this style will not update itself automatically when the value of a property referenced from the stylesheet changes. We need to unpolish and polish the style.
https://wiki.qt.io/Dynamic_Properties_and_Stylesheets

# After change the style
widget.style().unpolish(widget)
widget.style().polish(widget)

set background color, padding, scrollbar spacing (right of the content, left of the scrollbar, if that's possible) and accent colors for slider grooves, progress bars, enabled/disabled states, etc.

These may need placeholders. I think these are very good options, and accent colors and padding are especially useful.

I came across a few issues with the borders of QPlainTextEdit and QScrollArea when removing the borders and padding of the parent widget.

This is the stylesheet problems.

QFrame {
   padding: 0;
   border: none;
}

border: none remove the border display area as default. qdarktheme has a style sheet that displays a colored border when highlighting. If QPlainTextEdit display the colored border in this state, it will overlap other widgets because there is no place to display the border. Therefore, you need to prepare a space in advance to display the border when highlighting. Remove border: none and add border-color: transparent; to QFrame selector.
However, another problem arises. There is a container widget for the scrollbar below the QScrollBar in the QScrollArea. This container widget edges are sharp. This means that the corners of the container widget will be displayed above the border.
demodemo_big

This can be removed with the following code.

QPlainTextEdit > .QWidget {
    background-color: transparent;
}

And the second issue is similar to the first issue. scroll_area_contents edges are sharp. So you need to add border-color: transparent; to scroll_area_contents. QScrollArea already has parent container widget. Therefore, you need to add qss as following.

/* scroll_area > QScrollArea widget container(built-in class) > scroll_area_contents */
QScrollArea > .QWidget > .QWidget {
    background-color: transparent;
}

Here is the fixed codes.

QPlainTextEdit
import sys

from PySide6 import QtCore, QtGui, QtWidgets

import qdarktheme


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        central_widget = QtWidgets.QWidget(self)

        text_area = QtWidgets.QPlainTextEdit(central_widget)
        text_area.setFrameShape(QtWidgets.QFrame.Shape.NoFrame)
        for i in range(20):
            text_area.appendPlainText(f"Line {i}")
        self.text_area = text_area

        central_widget_layout = QtWidgets.QVBoxLayout(central_widget)
        central_widget_layout.addWidget(self.text_area)
        central_widget.setLayout(central_widget_layout)
        self.central_widget = central_widget
        self.central_widget_layout = central_widget_layout
        self.setCentralWidget(self.central_widget)


def main():
    app = QtWidgets.QApplication(sys.argv)
    stylesheet = qdarktheme.load_stylesheet("dark")
    custom_stylesheet = """
        QFrame {
            padding: 0;
            border-color: transparent;
        }
        QPlainTextEdit > .QWidget {
            background-color: transparent;
        }
    """
    app.setStyleSheet(stylesheet + custom_stylesheet)
    mw = MainWindow()
    mw.show()
    sys.exit(app.exec())


if __name__ == "__main__":
    main()
QScrollArea
import sys

from PySide6 import QtCore, QtGui, QtWidgets

import qdarktheme


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        central_widget = QtWidgets.QWidget(self)

        scroll_area = QtWidgets.QScrollArea()
        scroll_area.setWidgetResizable(True)
        scroll_area.setFrameShape(QtWidgets.QFrame.Shape.NoFrame)
        scroll_area_contents = QtWidgets.QWidget(scroll_area)
        scroll_area_contents_layout = QtWidgets.QVBoxLayout(scroll_area_contents)
        scroll_area_contents.setLayout(scroll_area_contents_layout)
        scroll_area.setWidget(scroll_area_contents)

        self.labels = []
        for i in range(20):
            label = QtWidgets.QLabel(scroll_area_contents, text=f"Label {i}")
            self.labels.append(label)
            scroll_area_contents_layout.addWidget(label)

        self.scroll_area = scroll_area
        self.scroll_area_contents = scroll_area_contents
        self.scroll_area_contents_layout = scroll_area_contents_layout

        central_widget_layout = QtWidgets.QVBoxLayout(central_widget)
        central_widget_layout.addWidget(self.scroll_area)
        central_widget.setLayout(central_widget_layout)
        self.central_widget = central_widget
        self.central_widget_layout = central_widget_layout
        self.setCentralWidget(self.central_widget)


def main():
    app = QtWidgets.QApplication(sys.argv)
    stylesheet = qdarktheme.load_stylesheet("dark")
    custom_stylesheet = """
        QFrame {
            padding: 0;
            border-color: transparent;
        }
        QScrollArea {
            border: 1px solid #fff;
        }
        QScrollArea > .QWidget {
            background-color: transparent;
        }
        /* scroll_area > QScrollArea widget container(built-in class) > scroll_area_contents */
        QScrollArea > .QWidget > .QWidget {
            background-color: transparent;
        }
    """
    app.setStyleSheet(stylesheet + custom_stylesheet)
    mw = MainWindow()
    mw.show()
    sys.exit(app.exec())


if __name__ == "__main__":
    main()

I will try to add this fix to qdarktheme.

This was referenced Jan 5, 2022
@alexitx
Copy link
Author

alexitx commented Jan 5, 2022

I think this can basically be solve with property selector. I found a solution to use property selector in Qt6. It seems that the frameShape property values are different between Qt5 and Qt6.

If the property selector values are consistent for all Qt 5.* and 6.* versions it shouldn't be difficult to support them. As I'm currently focusing on Qt6, I'll try to report any inconsistent behaviour that I find.

Widgets that inherit from QFrame, such as QTextEdit and QTableView, can use NoFrame. Therefore in this case, I think placeholder is no need. It can be included into a template stylesheet.
But this style will not update itself automatically when the value of a property referenced from the stylesheet changes. We need to unpolish and polish the style.

That's great, I'll keep it in mind.

If QPlainTextEdit display the colored border in this state, it will overlap other widgets because there is no place to display the border. Therefore, you need to prepare a space in advance to display the border when highlighting. Remove border: none and add border-color: transparent; to QFrame selector.
However, another problem arises. There is a container widget for the scrollbar below the QScrollBar in the QScrollArea. This container widget edges are sharp. This means that the corners of the container widget will be displayed above the border.

I see. I'm still not fully familiar with what child widgets there are and which color & border properties are set by default. But thanks for providing working examples!
There also shouldn't be a need for me to set padding: 0 and border: none globally for every QFrame when I can apply it along with NoFrame shape to QFrame widgets that are only used as simple containers.

@5yutan5
Copy link
Owner

5yutan5 commented Jan 8, 2022

Hi @alexitx. I have created a new PR(#66) that fixes this issue. Can you check it?

@alexitx
Copy link
Author

alexitx commented Jan 8, 2022

Looks good so far. The only small issue I noticed is that frameless widgets still have invisible border that creates 1 pixel gap, where without the theme there's no border at all.

QFrame NoFrame
import sys
import qdarktheme
from PySide6 import QtWidgets

app = QtWidgets.QApplication(sys.argv)
qdarktheme_stylesheet = qdarktheme.load_stylesheet('dark')
custom_stylesheet = '''
    /* Uncomment to emulate the default behaviour */
    /*
    QFrame[frameShape="NoFrame"] {
        border: none;
    }
    */

    #button_1,
    #button_2,
    #button_3 {
        padding: 4px;
        color: #fff;
        background-color: #606060;
        border: none;
    }

    #container {
        background-color: #ff6060;
    }
'''
app.setStyleSheet(qdarktheme_stylesheet + custom_stylesheet)

main_window = QtWidgets.QMainWindow()
central_widget = QtWidgets.QWidget(main_window)
central_widget_layout = QtWidgets.QVBoxLayout(central_widget)
central_widget_layout.setContentsMargins(10, 10, 10, 10)

container = QtWidgets.QFrame(central_widget, objectName='container')
container.setFrameShape(QtWidgets.QFrame.Shape.NoFrame)
container_layout = QtWidgets.QVBoxLayout(container)
container_layout.setContentsMargins(0, 0, 0, 0)

button_1 = QtWidgets.QPushButton(central_widget, text='QPushButton 1', objectName='button_1')
button_1.setFlat(True)
button_2 = QtWidgets.QPushButton(central_widget, text='QPushButton 2', objectName='button_2')
button_2.setFlat(True)
button_3 = QtWidgets.QPushButton(central_widget, text='QPushButton 3', objectName='button_3')
button_3.setFlat(True)

container_layout.addWidget(button_1)
container_layout.addWidget(button_2)
container_layout.addWidget(button_3)
container.setLayout(container_layout)

central_widget_layout.addWidget(container)
central_widget.setLayout(central_widget_layout)
main_window.setCentralWidget(central_widget)
main_window.show()
sys.exit(app.exec())

Image 1 - QFrame with NoFrame frame shape (no theme)
Image 2 - QFrame with NoFrame frame shape (qdarktheme)
Image 3 - QFrame with NoFrame frame shape and manually set border: none (qdarktheme)

01 02 03

I think the 3rd image is the expected result, as it also retains the same window size, because there is no border.

Another example on a flat QPushButton with its border color set to #ffff00:

Image 1 - Flat QPushButton with border-color: #ffff00 (no theme)
Image 2 - Flat QPushButton with border-color: #ffff00 (qdarktheme
Image 3 - Flat QPushButton with border-color: #ffff00 and manually set border: none (qdarktheme)

04 05 06

@5yutan5
Copy link
Owner

5yutan5 commented Jan 9, 2022

border: none is dangerous because it may break the style.
I only removed QFrame border with .QFrame selector only matching instances of QFrame.(#66)

qdarktheme cannot remove flat QPushButton border because QPushButton.setCheckable(True) uses the hilight border.

QPushButton.checkable = True
import sys

from PySide6 import QtWidgets

import qdarktheme

app = QtWidgets.QApplication(sys.argv)
qdarktheme_stylesheet = qdarktheme.load_stylesheet("dark")
custom_stylesheet = """
    #button_1,
    #button_2,
    #button_3 {
        padding: 4px;
        color: #fff;
        background-color: #606060;
        border: none;
    }

    #container {
        background-color: #ff6060;
    }
"""
app.setStyleSheet(qdarktheme_stylesheet + custom_stylesheet)

main_window = QtWidgets.QMainWindow()
central_widget = QtWidgets.QWidget(main_window)
central_widget_layout = QtWidgets.QVBoxLayout(central_widget)
central_widget_layout.setContentsMargins(10, 10, 10, 10)

container = QtWidgets.QFrame(central_widget, objectName="container")
container.setFrameShape(QtWidgets.QFrame.Shape.NoFrame)
container_layout = QtWidgets.QVBoxLayout(container)
container_layout.setContentsMargins(0, 0, 0, 0)

for i in range(1, 4):
    button = QtWidgets.QPushButton(
        central_widget,
        text=f"QPushButton {i}",
        objectName=f"button_{i}",
        flat=True,
        checkable=True,
    )
    container_layout.addWidget(button)
container.setLayout(container_layout)

central_widget_layout.addWidget(container)
central_widget.setLayout(central_widget_layout)
main_window.setCentralWidget(central_widget)
main_window.show()
sys.exit(app.exec())

left: set the line of border: none;
right: comment out the line of border: none;
demo_big

The QPushButtons of qdarktheme need the border even when style is flat.
I think we need to change the base style of button if you want to remove flat QPushButton border.

@5yutan5
Copy link
Owner

5yutan5 commented Jan 9, 2022

I think it's a good way to have the button style follow Google material design.
In Google material design, border is no need because button toggle uses background color instead of a border.

text-button(flat) > States | Google material design

image

@alexitx
Copy link
Author

alexitx commented Jan 9, 2022

border: none is dangerous because it may break the style.
I only removed QFrame border with .QFrame selector only matching instances of QFrame.(#66)

qdarktheme cannot remove flat QPushButton border because QPushButton.setCheckable(True) uses the hilight border.

Yeah, I didn't think of checkable QPushButton and other widgets that might use the border as highlight. Mainly because I'm used to testing against the default style without a theme.

I think it's a good way to have the button style follow Google material design.
In Google material design, border is no need because button toggle uses background color instead of a border.

That sounds good, but it's up to you to decide wether to change a lot of the core style of the theme.

The QPushButtons of qdarktheme need the border even when style is flat.
I think we need to change the base style of button if you want to remove flat QPushButton border.

Actually now that I think, I didn't need to change the style of the QPushButtons in the first example. I was trying to show the container (QFrame with object name #container) still having transparent 1 pixel border even with NoFrame set.

If you remove the block #button_1, #button_2, #button_3 ... and only comment/uncomment the first block with the selector QFrame[frameShape="NoFrame"] it demonstrates the example fine.

The flat QPushButton is fine even if the border is present, because frames used as containers shouldn't have contrasting background color likes in my example. Or if that is a possibility later on when the user can customize color properties, then the border color of flat QPushButtons can be set to the background color of the button, instead of transparent in base.qss#L406, unless there is a reason for that, which I'm not aware of.

@5yutan5
Copy link
Owner

5yutan5 commented Jan 9, 2022

the border color of flat QPushButtons can be set to the background color of the button, instead of transparent in base.qss#L406, unless there is a reason for that, which I'm not aware of.

The background color of the flat QPushButton is set to transparent. Therefore, the border color must also be set to transparent. Flat QPushButton color should always match the color of the widget behind it, so I think transparent is the best choice.

@5yutan5
Copy link
Owner

5yutan5 commented Jan 9, 2022

Oh, I'm sorry. I changed the background color of flat QPushButton to transparent in base.qss | PR #66.

@5yutan5
Copy link
Owner

5yutan5 commented Nov 1, 2022

This issue resolved on #187.

@5yutan5 5yutan5 closed this as completed Nov 1, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants