Qt 小部件背景从 Linux 到 Windows 不同

Posted

技术标签:

【中文标题】Qt 小部件背景从 Linux 到 Windows 不同【英文标题】:Qt widget background differs from Linux to Windows 【发布时间】:2014-07-29 09:37:05 【问题描述】:

我即将实现一个跨平台的 Qt 程序。我有一个不明白的问题:当程序在 Windows 上执行时,某些小部件的背景颜色错误。首先,我用 C++ 编写了程序,结果完全相同,所以我认为这不是 Python 特有的问题。

我将我的代码简化为一个显示“错误”的简单程序。我不确定是哪个小部件导致它,所以我只是简单地包含了实际程序中使用的所有元素。

这是它在 Linux 上的样子:

这是背景错误的 Windows 渲染:

代码如下:

import sys
from PyQt4.QtGui import QApplication, QMainWindow, QVBoxLayout, QTabWidget, QWidget, \
                        QGroupBox, QVBoxLayout, QScrollArea, QFrame, QHBoxLayout, \
                        QGridLayout, QLabel

class MainWindow(QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        mainWidget = QWidget(self)
        layout = QVBoxLayout(mainWidget)
        self.setCentralWidget(mainWidget)
        self.tabWidget = QTabWidget(self)
        layout.addWidget(self.tabWidget)
        self.scorePage = ScorePage()
        self.tabWidget.addTab(self.scorePage, 'Some Tab')
        self.scorePage.reload()

class GameWidget(QWidget):
    def __init__(self):
        super(GameWidget, self).__init__()
        layout = QGridLayout(self)
        boogerLabel = QLabel(self)
        boogerLabel.setText('Some Text')
        layout.addWidget(boogerLabel, 0, 0)

class ScorePage(QWidget):
    def __init__(self):
        super(ScorePage, self).__init__()
        layout = QVBoxLayout(self)
        self.scoreBox = QGroupBox(self)
        self.scoreBoxLayout = QVBoxLayout(self.scoreBox)
        layout.addWidget(self.scoreBox)
        self.scoreBoxScroll = QScrollArea(self.scoreBox)
        self.scoreBoxScroll.setFrameShape(QFrame.NoFrame)
        self.scoreBoxLayout.addWidget(self.scoreBoxScroll)
        self.scoreBoxWidget = QWidget(self)

    def reload(self):
        self.scoreBoxWidget.deleteLater()
        self.scoreBoxWidget = QWidget(self)
        self.scoreBoxWidgetLayout = QHBoxLayout(self.scoreBoxWidget)
        newGame = GameWidget()
        self.scoreBoxWidgetLayout.addWidget(newGame)
        self.scoreBoxScroll.setWidget(self.scoreBoxWidget)
        self.scoreBoxWidget.setAutoFillBackground(False)

def main(argv):
    app = QApplication(sys.argv, True)
    mainWindow = MainWindow()
    mainWindow.show()
    sys.exit(app.exec_())

if __name__ == "__main__":
    main(sys.argv)

如何获取和设置正确的背景颜色(来自 QGroupBox 的颜色)?

在此先感谢您提供的所有帮助!

【问题讨论】:

假定的问题在哪里?不同平台的样式不同,所以这是意料之中的。 问题是我程序中的所有其他小部件都没有不同的背景颜色,而是选项卡小部件之一(Qlabels、QCheckBoxes 等)。这更像是一个外观问题,但行为有点奇怪:当小部件不是通过调用 reload() 函数而是由构造函数添加时,设置了“正确的”背景颜色。所以我认为这是由于我的实施,并且可以以某种方式修复。我不认为这是预期的行为。如果没有为 scoreBoxWidget 设置 setAutoFillBackground(False),我也会在 Linux 上得到“错误”的颜色。 【参考方案1】:

嘿,前段时间我遇到了类似的问题,我通过添加不同于默认样式的 windows 样式解决了这个问题:

这是我的主要示例,可以根据需要进行操作:

def main(argv):
    app = QApplication(sys.argv, True)
    from platform import system
    if system() == "Windows":
        app.setStyle(QStyleFactory.create("windows"))
    mainWindow = MainWindow()
    mainWindow.show()
    sys.exit(app.exec_())

QStyleFactory 在 QtGui 中,所以你必须扩展你的导入

【讨论】:

感谢您的回答 :-) 应用您提出的更改后,问题不再可见,但我认为它只是掩盖了问题但并没有解决它......只要更现代的风格(如'windowsvista'),问题是一样的。我认为错误的背景颜色会消失,因为“windows”样式使用的颜色较少…… 是的,它仍然只是解决方法。就我而言,我只能建议编写自己的样式。 我的问题是除此之外的每个小部件都正确显示。所以我认为这是由于我所做的实现并且可以以某种方式修复......【参考方案2】:

我终于弄清楚是什么原因造成的。它是 QScrollArea 的背景(可能与我的 Linux 安装中的 QTabWidget 使用相同,所以我没有看到它)。

只需将 QScrollArea 的背景定义为透明即可解决:

self.scoreBoxScroll.setStyleSheet('QScrollArea  background-color: transparent; ')

【讨论】:

以上是关于Qt 小部件背景从 Linux 到 Windows 不同的主要内容,如果未能解决你的问题,请参考以下文章

在 Qt Stacked Widget 的特定小部件中更改背景颜色

具有完全透明背景的 qt 小部件

Qt半透明背景导致子小部件在父小部件中“印记”

如何让 qt 设计器自定义 QOpenGLWidget 小部件背景透明?

QT qmake 小写我的自定义小部件名称

Qt“直通”或“容器”小部件