<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>Python GUIs - qpalette</title><link href="https://www.pythonguis.com/" rel="alternate"/><link href="https://www.pythonguis.com/feeds/qpalette.tag.atom.xml" rel="self"/><id>https://www.pythonguis.com/</id><updated>2020-11-24T09:00:00+00:00</updated><subtitle>Create GUI applications with Python and Qt</subtitle><entry><title>How to Use System Default Colors in Qt Stylesheets — Access your user's color scheme to keep your app looking native</title><link href="https://www.pythonguis.com/faq/setstylesheet-get-colour-from-default-scheme/" rel="alternate"/><published>2020-11-24T09:00:00+00:00</published><updated>2020-11-24T09:00:00+00:00</updated><author><name>Martin Fitzpatrick</name></author><id>tag:www.pythonguis.com,2020-11-24:/faq/setstylesheet-get-colour-from-default-scheme/</id><summary type="html">I'm trying to set the background color of a widget to a "default" system color using &lt;code&gt;setStyleSheet()&lt;/code&gt;. I don't want to hard-code a specific color, because if the user changes their color scheme it could look weird or unreadable. Is there a set of default colors provided by the chosen color scheme?</summary><content type="html">
            &lt;blockquote&gt;
&lt;p&gt;I'm trying to set the background color of a widget to a "default" system color using &lt;code&gt;setStyleSheet()&lt;/code&gt;. I don't want to hard-code a specific color, because if the user changes their color scheme it could look weird or unreadable. Is there a set of default colors provided by the chosen color scheme?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This comes up often when you start customizing the appearance of your widgets. Hard-coding colors like &lt;code&gt;#ffffff&lt;/code&gt; or &lt;code&gt;lightgray&lt;/code&gt; into your stylesheets works fine on &lt;em&gt;your&lt;/em&gt; machine, but the moment someone with a dark theme or a custom color scheme runs your app, things can look out of place &amp;mdash; or worse, unreadable.&lt;/p&gt;
&lt;p&gt;The good news is that Qt gives you access to the system's current color palette, so you can pull colors directly from the user's active theme and use them wherever you need.&lt;/p&gt;
&lt;h2 id="the-qpalette-your-gateway-to-system-colors"&gt;The &lt;code&gt;QPalette&lt;/code&gt;: Your Gateway to System Colors&lt;/h2&gt;
&lt;p&gt;Every Qt application has a &lt;strong&gt;palette&lt;/strong&gt; &amp;mdash; a &lt;code&gt;QPalette&lt;/code&gt; object that holds all the colors the system (or the current style) uses to draw widgets. This includes things like the default window background, text color, button color, highlighted text, and more.&lt;/p&gt;
&lt;p&gt;You can access the application's palette at any time like this:&lt;/p&gt;
&lt;div class="code-block"&gt;
&lt;span class="code-block-language code-block-python"&gt;python&lt;/span&gt;
&lt;pre&gt;&lt;code class="python"&gt;palette = self.palette()
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Or from anywhere in your application:&lt;/p&gt;
&lt;div class="code-block"&gt;
&lt;span class="code-block-language code-block-python"&gt;python&lt;/span&gt;
&lt;pre&gt;&lt;code class="python"&gt;from PyQt6.QtWidgets import QApplication

palette = QApplication.instance().palette()
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The palette organizes colors into &lt;strong&gt;roles&lt;/strong&gt;. Each role describes what a color is used for. Some commonly useful roles include:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Role&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;QPalette.ColorRole.Window&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Default background color for windows&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;QPalette.ColorRole.WindowText&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Default text color&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;QPalette.ColorRole.Base&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Background color for text entry widgets&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;QPalette.ColorRole.AlternateBase&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Alternate background color (e.g., for alternating row colors in lists)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;QPalette.ColorRole.Button&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Background color for buttons&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;QPalette.ColorRole.Highlight&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Background color for selected items&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;QPalette.ColorRole.HighlightedText&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Text color for selected items&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="getting-a-color-from-the-palette"&gt;Getting a Color from the Palette&lt;/h2&gt;
&lt;p&gt;To retrieve a specific color, call &lt;code&gt;.color()&lt;/code&gt; on the palette and pass in the role you want:&lt;/p&gt;
&lt;div class="code-block"&gt;
&lt;span class="code-block-language code-block-python"&gt;python&lt;/span&gt;
&lt;pre&gt;&lt;code class="python"&gt;from PyQt6.QtGui import QPalette

palette = self.palette()
color = palette.color(QPalette.ColorRole.AlternateBase)
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This gives you a &lt;code&gt;QColor&lt;/code&gt; object. To use it in a stylesheet, you can convert it to a string with &lt;code&gt;.name()&lt;/code&gt;, which returns a hex color code like &lt;code&gt;#e7e7e7&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block"&gt;
&lt;span class="code-block-language code-block-python"&gt;python&lt;/span&gt;
&lt;pre&gt;&lt;code class="python"&gt;color_hex = color.name()  # e.g. "#e7e7e7"
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h2 id="using-palette-colors-in-stylesheets"&gt;Using Palette Colors in Stylesheets&lt;/h2&gt;
&lt;p&gt;Now you can combine these pieces to build a stylesheet that uses the system's own colors:&lt;/p&gt;
&lt;div class="code-block"&gt;
&lt;span class="code-block-language code-block-python"&gt;python&lt;/span&gt;
&lt;pre&gt;&lt;code class="python"&gt;palette = self.palette()
alt_base = palette.color(QPalette.ColorRole.AlternateBase).name()
self.line_edit.setStyleSheet(
    f"QLineEdit {{ background: {alt_base}; }}"
)
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Because you're reading the color from the palette at runtime, the stylesheet will always match the user's current color scheme &amp;mdash; whether they're using a light theme, a dark theme, or something completely custom.&lt;/p&gt;
&lt;h2 id="a-complete-working-example"&gt;A Complete Working Example&lt;/h2&gt;
&lt;p&gt;Here's a small application that demonstrates reading several palette colors and applying one to a &lt;code&gt;QLineEdit&lt;/code&gt; background. It also displays a few of the current system colors so you can see what's available.&lt;/p&gt;
&lt;div class="code-block"&gt;
&lt;span class="code-block-language code-block-python"&gt;python&lt;/span&gt;
&lt;pre&gt;&lt;code class="python"&gt;import sys

from PyQt6.QtGui import QPalette
from PyQt6.QtWidgets import (
    QApplication,
    QFormLayout,
    QLabel,
    QLineEdit,
    QVBoxLayout,
    QWidget,
)

class MainWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("System Palette Colors")

        layout = QVBoxLayout()
        self.setLayout(layout)

        # Create a QLineEdit styled with the system's AlternateBase color.
        palette = self.palette()
        alt_base = palette.color(QPalette.ColorRole.AlternateBase).name()

        self.line_edit = QLineEdit()
        self.line_edit.setPlaceholderText(
            f"Background set to AlternateBase ({alt_base})"
        )
        self.line_edit.setStyleSheet(
            f"QLineEdit {{ background: {alt_base}; }}"
        )
        layout.addWidget(self.line_edit)

        # Show a reference of current palette colors.
        form = QFormLayout()
        layout.addLayout(form)

        roles = {
            "Window": QPalette.ColorRole.Window,
            "WindowText": QPalette.ColorRole.WindowText,
            "Base": QPalette.ColorRole.Base,
            "AlternateBase": QPalette.ColorRole.AlternateBase,
            "Button": QPalette.ColorRole.Button,
            "Highlight": QPalette.ColorRole.Highlight,
            "HighlightedText": QPalette.ColorRole.HighlightedText,
        }

        for name, role in roles.items():
            color = palette.color(role)
            color_hex = color.name()
            swatch = QLabel(f"  {color_hex}  ")
            swatch.setStyleSheet(
                f"background: {color_hex}; "
                f"color: {'white' if color.lightness() &amp;lt; 128 else 'black'}; "
                f"padding: 4px; "
                f"border: 1px solid gray;"
            )
            form.addRow(name, swatch)

app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec())
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Run this and you'll see your &lt;code&gt;QLineEdit&lt;/code&gt; with a background that matches the system's alternate base color, along with a set of color swatches showing the current palette values. If you change your system theme and run it again, the colors will update automatically.&lt;/p&gt;
&lt;h2 id="an-alternative-skip-the-stylesheet-entirely"&gt;An Alternative: Skip the Stylesheet Entirely&lt;/h2&gt;
&lt;p&gt;If you only need to change the background (or foreground) color of a single widget, you can skip stylesheets altogether and modify the widget's palette directly:&lt;/p&gt;
&lt;div class="code-block"&gt;
&lt;span class="code-block-language code-block-python"&gt;python&lt;/span&gt;
&lt;pre&gt;&lt;code class="python"&gt;palette = self.line_edit.palette()
palette.setColor(
    QPalette.ColorRole.Base,
    palette.color(QPalette.ColorRole.AlternateBase),
)
self.line_edit.setPalette(palette)
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This sets the &lt;code&gt;QLineEdit&lt;/code&gt;'s own &lt;code&gt;Base&lt;/code&gt; color (which controls its background) to the system's &lt;code&gt;AlternateBase&lt;/code&gt; color &amp;mdash; no stylesheet needed. This approach is lighter-weight and avoids some of the quirks that stylesheets can introduce with certain styles.&lt;/p&gt;
&lt;h2 id="handling-colors-with-alpha-transparency"&gt;Handling Colors with Alpha Transparency&lt;/h2&gt;
&lt;p&gt;Some palette colors include an alpha (transparency) component. The &lt;code&gt;.name()&lt;/code&gt; method returns only the RGB hex value by default (e.g., &lt;code&gt;#e7e7e7&lt;/code&gt;), discarding any transparency information. If you need to preserve alpha, pass &lt;code&gt;QColor.NameFormat.HexArgb&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block"&gt;
&lt;span class="code-block-language code-block-python"&gt;python&lt;/span&gt;
&lt;pre&gt;&lt;code class="python"&gt;from PyQt6.QtGui import QColor

color = palette.color(QPalette.ColorRole.Highlight)
color_with_alpha = color.name(QColor.NameFormat.HexArgb)  # e.g. "#ff3daee9"
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;You can use this in stylesheets with the &lt;code&gt;rgba()&lt;/code&gt; function instead, which tends to be more readable:&lt;/p&gt;
&lt;div class="code-block"&gt;
&lt;span class="code-block-language code-block-python"&gt;python&lt;/span&gt;
&lt;pre&gt;&lt;code class="python"&gt;color = palette.color(QPalette.ColorRole.Highlight)
rgba = f"rgba({color.red()}, {color.green()}, {color.blue()}, {color.alpha()})"
self.widget.setStyleSheet(f"background: {rgba};")
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;For most palette colors the alpha is fully opaque (&lt;code&gt;255&lt;/code&gt;), so &lt;code&gt;.name()&lt;/code&gt; alone will work perfectly well.&lt;/p&gt;
&lt;h2 id="when-to-use-each-approach"&gt;When to Use Each Approach&lt;/h2&gt;
&lt;p&gt;Both approaches &amp;mdash; stylesheets with palette colors and direct palette modification &amp;mdash; have their place:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Stylesheets with palette colors&lt;/strong&gt; are great when you need to combine system colors with other stylesheet features like borders, padding, or pseudo-state selectors (&lt;code&gt;:hover&lt;/code&gt;, &lt;code&gt;:pressed&lt;/code&gt;, etc.).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Direct palette modification&lt;/strong&gt; is simpler when all you need is a background or text color change on a specific widget, and you don't need any other stylesheet features.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Whichever approach you choose, reading from the palette means your app will stay consistent with the user's desktop theme &amp;mdash; and that's a much better experience than hard-coded colors that clash with everything else on screen.&lt;/p&gt;
            &lt;p&gt;For an in-depth guide to building Python GUIs with PyQt6 see my book, &lt;a href="https://www.mfitzp.com/pyqt6-book/"&gt;Create GUI Applications with Python &amp; Qt6.&lt;/a&gt;&lt;/p&gt;
            </content><category term="pyqt6"/><category term="stylesheets"/><category term="colors"/><category term="qpalette"/><category term="theming"/><category term="python"/><category term="qt"/><category term="qt6"/></entry></feed>