0

我有一个我在 Qt6 中使用的 GUI 的小例子,它在切换调色板颜色时出现问题(从深色主题切换到浅色主题)。当我将更改应用于 QPalette 以更改文本颜色时,它们仅在窗口处于非活动状态时才起作用。奇怪的是,如果我从样式表中删除字体系列规范,那么颜色更改就会正常工作。这一切都在 Qt5 中运行良好,没有任何混乱。

  1. 加载时,GUI 看起来不错
  2. 单击“更改主题”按钮后,它看起来很好,只是我使用 Palette 更改的文本颜色设置不起作用(它仍然是黑色)
  3. 如果我单击我的桌面或其他窗口以使我的 GUI 处于非活动状态,它将显示正确的文本颜色(红色)

光工作,黑暗 , 破碎,黑暗 工作

欢迎任何解决方法建议(使颜色和字体都始终正常工作),但我很想知道我在这里实际上做错了什么,以及为什么它曾经在 Qt5 中有效而在 Qt6 中无效!谢谢!

from PyQt6 import QtWidgets
from PyQt6.QtGui import QPalette, QColor, QFont

APP = QtWidgets.QApplication([])


class UiMain(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        self.setObjectName("MainWindow")
        central_widget = QtWidgets.QWidget(self)
        self.setCentralWidget(central_widget)
        tabs = QtWidgets.QTabWidget(central_widget)
        vertical_layout_26 = QtWidgets.QVBoxLayout(central_widget)
        vertical_layout_26.addWidget(tabs)
        search_tab = QtWidgets.QWidget()
        tabs.addTab(search_tab, "")
        tabs.setTabText(tabs.indexOf(search_tab), "Search")
        filter_group_box = QtWidgets.QGroupBox(search_tab)
        filter_group_box.setTitle("Filters")
        self.theme_btn = QtWidgets.QPushButton()
        self.theme_btn.setText("Change Theme")
        searchbar_layout = QtWidgets.QHBoxLayout(search_tab)
        searchbar_layout.addWidget(QtWidgets.QLabel("asdf"))
        searchbar_layout.addWidget(filter_group_box)
        searchbar_layout.addWidget(self.theme_btn)


class View(UiMain):
    def __init__(self):
        super().__init__()
        self.theme_btn.clicked.connect(self.change_theme)  # noqa

        # Create Palettes
        self.light_palette = QPalette()
        self.dark_palette = QPalette()
        self.dark_palette.setColor(QPalette.ColorRole.WindowText, QColor("red"))

        # # This didn't help
        # self.dark_palette.setColor(QPalette.ColorGroup.Active, QPalette.ColorRole.WindowText, QColor("red"))  

        # Create Stylesheets
        self.style_light = """
            * {font-family: 'Noto Sans';}  /* REMOVING THIS LINE AVOIDS THE ISSUE, BUT THEN FONTS ARE WRONG INITIALLY */
            QMainWindow {background-color: white;}
            """
        self.style_dark = """
            * {font-family: 'Noto Sans';} 
            QMainWindow {background-color: gray;}
            """

        # Set initial theme
        self.dark = False
        APP.setPalette(self.light_palette)
        APP.setStyleSheet(self.style_light)

        self.show()

    def change_theme(self):
        """Allow user to switch between dark and light theme"""
        if self.dark:
            self.dark = False
            APP.setPalette(self.light_palette)
            APP.setStyleSheet(self.style_light)
        else:
            self.dark = True
            APP.setPalette(self.dark_palette)
            APP.setStyleSheet(self.style_dark)


if __name__ == '__main__':

    gui = View()
    APP.exec()
4

1 回答 1

0

我也使用 PySide6(在 Windows 和 Linux 上都出现)遇到了这个问题。

就我而言,问题是在我对样式表进行任何操作后使用 QApplication.setPalette 更改调色板会导致样式表无法正确应用于现有窗口/对象或其子对象。删除窗口并创建一个新窗口按预期工作。

这个问题(在我的情况下)可以使用以下内容来查看。应用程序的调色板将显示我的调色板中的文本颜色,但窗口的调色板显示默认的黑色文本颜色。

# Change theme
my_app.setStyleSheet(new_stylesheet)
my_app.setStyle(new_style)
my_app.setPalette(new_palette)

# self is a QMainWindow that was open when the theme was changed
print(QApplication.palette().color(QPalette.Text).name())
print(self.palette().color(QPalette.Text).name())

我不知道这是否是一个错误,但我能够在不创建新窗口实例的情况下通过手动(和递归)将调色板应用到我现有的窗口及其子项来解决它,方法是使用以下函数

def change_palette_recursive(root: QWidget, palette: QPalette):
    root.setPalette(palette)
    for child in root.children():
        if isinstance(child, QWidget):
            change_palette_recursive(child, palette)

这应该在更改主题后调用。它可能需要在每个打开的窗口上调用(除非它是另一个打开的窗口的子窗口)。

change_theme()
change_palette_recursive(existing_window, QApplication.palette())

我通常会认为这种事情是不好的形式,但这是我(迄今为止)发现的唯一有效的东西。

于 2022-01-24T06:08:55.230 回答