Qt 小部件的深色主题?

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

背景

我正在构建一个 PyQt5 应用程序,我想要一个深色主题。之前我从事过 Android 开发工作,其中有一个可以为整个应用程序设置的深色主题

问题

Qt 中是否内置了深色主题(适用于应用程序中的所有小部件,并且是跨平台的)?

qt pyqt qt5 pyqt5 qstyle
7个回答
74
投票

不,但你可以使用我相当全面的样式表,它在大多数平台上看起来都很棒(它的灵感来自 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())

动态样式表切换

响应评论,调整样式表以动态使用浅色或深色样式表的最简单方法是将其包装在函数中。然后,您可以将该函数用作 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())

现在我们可以添加通用应用程序逻辑,可以在信号/槽机制中使用此函数(如果需要,使用 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_())

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

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


37
投票

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

from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication
from PyQt5.QtGui import QPalette, QColor


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.black)
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)

这样做的好处是它不引入外部依赖项。如果您对上述更改感兴趣,我创建了一个带有深色主题的示例 PyQt5 应用程序。这是截图:

Qt dark theme


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

您可以使用 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

看起来棒极了,无法对 Michael Herrmann 的帖子发表评论表示感谢,但还是投了赞成票。

之前:

之后:

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


3
投票

在我的书签中找到。我不记得原始来源了。

QApplication::setStyle(QStyleFactory::create("Fusion"));
QPalette p;
p = qApp->palette();
p.setColor(QPalette::Window, QColor(53,53,53));
p.setColor(QPalette::Button, QColor(53,53,53));
p.setColor(QPalette::Highlight, QColor(142,45,197));
p.setColor(QPalette::ButtonText, QColor(255,255,255));
qApp->setPalette(p);

附注如有必要,可以通过 QSS 进行调整。


3
投票

我建议你使用 qt-material 包,它有漂亮的深色主题。它很容易使用,只需将其安装为 Python 包并添加以下行:

from qt_material import apply_stylesheet

...

app = QtWidgets.QApplication(sys.argv)
window = QtWidgets.QMainWindow()

# setup stylesheet
apply_stylesheet(app, theme='dark_teal.xml')

文档在这里:https://pypi.org/project/qt-material/


3
投票

PyQtDark主题

pip3 install pyqtdarktheme

https://pyqtdarktheme.readthedocs.io/en/stable/how_to_use.html
https://pypi.org/project/pyqtdarktheme/


pyqtdarktheme
让生活更轻松。

qdarktheme.setup_theme("auto")

它可以动态跟随操作系统黑暗模式。


0
投票

在Qt 6.5(PyQt6)中,有一个适当的内置方法来获取系统浅色/深色主题。

如果您只想让您的小部件遵循系统设置,您可以将应用程序样式设置为“融合”,然后让 Qt 完成其余的工作。请注意,如果您有样式表或使用自定义颜色,这可能会让东西看起来很糟糕。

with QApplication(sys.argv) as qapp:
    qapp.setApplicationName("My Awesome App")
    qapp.setStyle('fusion')

    w = MainUIWindow()
    w.show()

    sys.exit(qapp.exec())

有关更多信息以及有关如何更好地控制该过程的一些建议,我建议查看这个答案有关 Windows 11 深色模式的相关文章

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