在 qt StyleSheets 中使用变量

问题描述 投票:0回答:7

是否有可能为 .qss 文件中的十六进制/RGB 数字提供变量名称。为了呃

myColor = #FFCC08
QPushButton { background-color: myColor;}

这样我就可以在样式表顶部定义变量,并在需要的地方使用变量名称,而不是使用十六进制代码。另外,如果我需要更改颜色,那么我必须在一处进行更改,它将反映在整个文件中。

我也搜索了Saas,但不知道它如何在qt中使用。

谢谢:)

qt qtstylesheets
7个回答
23
投票

你可以很容易地构建自己的小型 Sass:

1.创建一个包含变量定义的文本文件。使用像这样的简单格式:

@myColor  = #FFDDEE
@myColor2 = #112233 
@myWidth  = 20px

2.在qss文件中使用变量名:

QPushButton { 
    background-color: @myColor; 
    min-width: @myWidth;
}

3.打开这两个文件,并针对定义文件中的每个变量,使用定义文件中的值(字符串)更改其在 qss 文件中的出现位置。这是一个简单的字符串替换。

4.在应用程序中应用预处理后的qss。

这是最简单的解决方案。您可以在应用程序外部更改定义文件和 qss 文件并应用它,而无需重新编译代码。


7
投票

使用纯 Qt 样式表根本无法实现您想要完成的任务。

您可以通过在 C++ 代码中修改和重新加载样式表来实现类似的效果,例如:

QString myColor = "#FFCC08";
QString styleSheet = "QPushButton { background-color: %1;}";
...
myWidget->setStyleSheet( styleSheet.arg(myColor) );

不幸的是,这有几个缺点(无法在设计器中预览、更改代码而不是样式表),但它已经尽可能接近您想要使用 Qt 实现的目标了。


3
投票

实现此目的的另一种方法是使用动态属性。这可以让您轻松地将多个属性分配给一个对象或一组对象,有点像将 css 类分配给一个对象。 https://wiki.qt.io/Dynamic_Properties_and_Stylesheets

例如,在 UI 文件中,您可以添加值为“myStyle1”的字符串动态属性“colorStyle”。

你的样式表看起来像:

QPushButton[colorStyle='myStyle1'] {
    background-color: #FFCC08;
    ... any other style changes...
}

如果您全局设置它,您分配“myStyle1”的任何 QPushButton 都将遵循样式表。


1
投票

这是使用 sass 的解决方案。首先,安装 python 绑定:

pip install sass

然后,使用它:

import sys
import sass
app = QApplication(sys.argv)

# Create your sass style sheet (you can also write this in a file and load the file)
style = '''
$bg-dark: #292929;

QPushButton {
color: red;
background-color: $bg-dark;
}
'''.encode('utf-8')

# Compile Sass to CSS
style = sass.compile_string(style).decode()

# And set it to your app
app.setStyleSheet(style)

0
投票

我有类似但不同的问题。就我而言,我想将窗口大小连接到 QCheckBoxIndicator。由于 css 已经使用了 {},下面的代码将无法工作。

        self.checkBoxYes.setStyleSheet('''
        QCheckBox::indicator {
        width: {sz} px;
        height: {sz} px;
        }
        '''.format(sz=rel_sz))

但是,可以使用下面的旧格式字符串来实现解决方法:

def resizeEvent(self, a0) -> None:
    rel_wdth = self.width() // 20
    rel_hgh = self.height() // 10
    rel_sz = str(min(rel_hgh, rel_wdth))
    self.checkBoxYes.setStyleSheet('''
        QCheckBox::indicator {
        width: %s px;
        height: %s px;
        }
        ''' %(rel_sz, rel_sz))
    return super().resizeEvent(a0)

0
投票

您可以在Python中使用字符串连接。很容易实现。

 self.setStyleSheet("""QPushButton { %s;}""" % (myColor))


0
投票

根据@Pucor的回答,我创建了这个函数来自动化该过程并避免创建两个文件:

def load_style(path : str):
    exc = Exception('Invalid syntax')
    style = ''
    with open(path, 'r') as file:
        root_block = 0
        saved_vars = {}
        for line in file:
            if ':root' in line:
                root_block = 1
            if '{' in line:
                if root_block == 1:
                    root_block = 2
                else:
                    raise exc
            if '}' in line:
                if root_block != 2:
                    raise exc
                else:
                    style = file.read()
                    break
            if root_block == 2:
                split = line.split(':')
                match split:
                    case  [key, value]:
                        saved_vars[key.strip()] = value.strip()
                    case _:
                        raise exc
    pattern = re.compile('@(' + '|'.join(sorted(saved_vars, key= len, reverse=True)).strip('|') + ')')
    style = pattern.sub(lambda match: saved_vars[match.group(1)], style)
    return style

请注意,该函数并不是万无一失的,因为它取决于最后按程序制作的正则表达式捕获组,而我尚未深入测试..

用途:

在你的stylesheet.qss中:

:root{
    primary: #1a1f1f
    primary-dark: #101010
    primary-light: #353535
    secondary: #2a82da
    secondary-dark: #163f68
}
QWidget{
    border: 0px;
    background-color: @primary;
    color: white;
}

解析器将首先将所有“变量”存储在 :root 块内,然后替换文件其余部分中以 @ 开头的每个引用变量。

要在您的应用程序中使用它:

style = load_style('stylesheet.qss')
app.setStyleSheet(style)

我知道代码很混乱且难以阅读

© www.soinside.com 2019 - 2024. All rights reserved.