在Qt小部件中的黑暗主题?

sun*_*ata 12 qt pyqt qstyle qt5 pyqt5

背景

我正在构建一个PyQt5应用程序,我希望它有一个黑暗的主题.以前我曾经使用Android开发,我可以为整个应用程序设置一个黑暗的主题

是否在Qt中内置了一个黑暗的主题(适用于应用程序中的所有小部件,这是跨平台的)?

Ale*_*agh 20

不,但是你可以使用我在大多数平台上看起来都非常出色的相当全面的样式表(它的灵感来自KDE的Breeze主题,这是一个非常优雅的黑暗主题).这是(很难)从优秀的QDarkStylesheet中分出来的,我觉得在很多方面都存在主题问题,因此我根据自己的需要对其进行了大量修改并添加了一个轻量级的主题.

简单使用

主题的样本在这里.要在PyQt5中使用它,只需将以下行添加到项目中:

import sys
from PyQt5.QtCore import QFile, QTextStream
from PyQt5.QtWidgets import QApplication
import breeze_resources

app = QApplication(sys.argv)
file = QFile(":/dark.qss")
file.open(QFile.ReadOnly | QFile.Text)
stream = QTextStream(file)
app.setStyleSheet(stream.readAll())
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

动态样式表切换

在回复注释时,调整样式表以动态使用浅色或深色样式表的最简单方法是将其包装在函数中.然后,您可以将该函数用作Qt信号的插槽(警告:我主要使用C++开发,因此我的代码中可能存在信号/插槽机制的小错误).

def toggle_stylesheet(path):
    '''
    Toggle the stylesheet to use the desired path in the Qt resource
    system (prefixed by `:/`) or generically (a path to a file on
    system).

    :path:      A full path to a resource or file on system
    '''

    # get the QApplication instance,  or crash if not set
    app = QApplication.instance()
    if app is None:
        raise RuntimeError("No Qt Application found.")

    file = QFile(path)
    file.open(QFile.ReadOnly | QFile.Text)
    stream = QTextStream(file)
    app.setStyleSheet(stream.readAll())
Run Code Online (Sandbox Code Playgroud)

现在我们可以添加可以在信号/槽机制中使用此函数的通用应用程序逻辑(如果需要,使用lambda作为方便的包装器,以提供样式表转换器的路径):

# add logic for setting up application
app = QApplication(sys.argv)
# more logic for creating top-level widgets, application logic ...

parent = ...
light_btn = QPushButton("Toggle light.", parent)
light_btn.clicked.connect(lambda: toggle_stylesheet(":/light.qss"))

dark_btn = QPushButton("Toggle dark.", parent)
dark_btn.clicked.connect(lambda: toggle_stylesheet(":/dark.qss"))

# add to the layout, do other stuff
# ...

# end the Qt application
sys.exit(app.exec_())
Run Code Online (Sandbox Code Playgroud)

这允许用户动态地将使用PyQt5(或使用C++,Qt5中的类似逻辑)开发的应用程序的主题更改为浅色或深色主题.

免责声明:显然我是维护者.

  • 我尝试过的所有其他黑暗主题都缺少部件并且看起来不太好,有缺陷和黑客攻击,并且填充和布局过多.到目前为止,这是最好的.这说它不完美,但可能只需要稍微调整一下.带有活动停靠栏复选框的Dock列表具有与停靠栏名称重叠的复选框. (2认同)
  • @aoh 让我知道这是否解决了您的问题,它简单地解释了如何在运行时在明暗样式之间切换,并且要使用本机样式,您可以简单地调用 `app.setStyleSheet("")`。将这些绑定到 UI 中的信号将允许用户在运行时更改样式表,最好将他们喜欢的 UI 存储在配置文件中。 (2认同)
  • @AlexanderHuszagh肯定回答了我的问题,谢谢! (2认同)

Mik*_*e R 9

我试图将其应用到我基于 fbs 的应用程序,发现下面的内容可以轻松地让我通过将其应用到 AppContext 来设置应用程序的样式

class AppContext(ApplicationContext):
    def run(self):
        self.main_window.show()
        return self.app.exec_()

    @cached_property
    def main_window(self):
        return MainWindow(self)

    if theme_selection == 'Dark':
        QApplication.setStyle("Fusion")
        #
        # # Now use a palette to switch to dark colors:
        dark_palette = QPalette()
        dark_palette.setColor(QPalette.Window, QColor(53, 53, 53))
        dark_palette.setColor(QPalette.WindowText, Qt.white)
        dark_palette.setColor(QPalette.Base, QColor(35, 35, 35))
        dark_palette.setColor(QPalette.AlternateBase, QColor(53, 53, 53))
        dark_palette.setColor(QPalette.ToolTipBase, QColor(25, 25, 25))
        dark_palette.setColor(QPalette.ToolTipText, Qt.white)
        dark_palette.setColor(QPalette.Text, Qt.white)
        dark_palette.setColor(QPalette.Button, QColor(53, 53, 53))
        dark_palette.setColor(QPalette.ButtonText, Qt.white)
        dark_palette.setColor(QPalette.BrightText, Qt.red)
        dark_palette.setColor(QPalette.Link, QColor(42, 130, 218))
        dark_palette.setColor(QPalette.Highlight, QColor(42, 130, 218))
        dark_palette.setColor(QPalette.HighlightedText, QColor(35, 35, 35))
        dark_palette.setColor(QPalette.Active, QPalette.Button, QColor(53, 53, 53))
        dark_palette.setColor(QPalette.Disabled, QPalette.ButtonText, Qt.darkGray)
        dark_palette.setColor(QPalette.Disabled, QPalette.WindowText, Qt.darkGray)
        dark_palette.setColor(QPalette.Disabled, QPalette.Text, Qt.darkGray)
        dark_palette.setColor(QPalette.Disabled, QPalette.Light, QColor(53, 53, 53))
        QApplication.setPalette(dark_palette)
    elif theme_selection == 'Light':
        QApplication.setStyle("")
        pass
    else:
        pass
Run Code Online (Sandbox Code Playgroud)

您可以使用 Qsettings 保存对哪种模式的首选项,并在启动时恢复。

if settings.contains("theme_selection"):
    # there is the key in QSettings
    print('Checking for theme preference in config')
    theme_selection = settings.value('theme_selection')
    print('Found theme_selection in config:' + theme_selection)
else:
    if not is_mac():
        print('theme_selection not found in config. Using default Darkmode')
        settings.setValue('theme_selection', 'Dark')
        theme_selection = settings.value('theme_selection')
    elif is_mac():
        print('theme_selection not found in config. Using default Lightmode')
        settings.setValue('theme_selection', 'Light')
        theme_selection = settings.value('theme_selection')
    pass
Run Code Online (Sandbox Code Playgroud)

看起来棒极了,无法对迈克尔·赫尔曼的帖子发表评论表示感谢,但还是投了赞成票。

前: 启用深色调色板模式之前的样子

后: 启用调色板模式

中间部分是 xterm.js,这就是为什么它现在仍然是白色的,因为它不是 QT 风格的东西。


Mic*_*ann 5

Qt中没有内置黑暗主题。但是您可以使用以下代码轻松地自己创建一个:

from PyQt5.QtWidgets import QApplication
from PyQt5.QtGui import QPalette

app = QApplication([])
# Force the style to be the same on all OSs:
app.setStyle("Fusion")

# Now use a palette to switch to dark colors:
palette = QPalette()
palette.setColor(QPalette.Window, QColor(53, 53, 53))
palette.setColor(QPalette.WindowText, Qt.white)
palette.setColor(QPalette.Base, QColor(25, 25, 25))
palette.setColor(QPalette.AlternateBase, QColor(53, 53, 53))
palette.setColor(QPalette.ToolTipBase, Qt.white)
palette.setColor(QPalette.ToolTipText, Qt.white)
palette.setColor(QPalette.Text, Qt.white)
palette.setColor(QPalette.Button, QColor(53, 53, 53))
palette.setColor(QPalette.ButtonText, Qt.white)
palette.setColor(QPalette.BrightText, Qt.red)
palette.setColor(QPalette.Link, QColor(42, 130, 218))
palette.setColor(QPalette.Highlight, QColor(42, 130, 218))
palette.setColor(QPalette.HighlightedText, Qt.black)
app.setPalette(palette)
Run Code Online (Sandbox Code Playgroud)

这样做的好处是它没有引入外部依赖关系。如果您对以上更改的外观感兴趣,我创建了一个带有深色主题的示例PyQt5应用。这是屏幕截图:

Qt黑暗主题

  • 谢谢你的回答!我不确定它是否适用于 Qt 的所有版本,但我必须添加 `QToolTip::setPalette(palette);` 才能使设置在工具提示上生效。 (2认同)
  • 如果您使用 PyQt6,则需要添加“ColorRole”以从“QPalette”获取常量:“QPalette.ColorRole.Window” (2认同)