QCheckBox 的背景颜色在用户检查时与 python 代码设置它检查时不同
Background color of QCheckBox differs when checked by user vs when python code sets it checked
问题总结:
上面三个复选框中的两个有复选标记。其中一个值是使用 Python 代码 self.setwithPythoncode.setChecked(True)
设置的,而另一个值是在应用处于 运行.
时通过用户单击框来设置的
实际结果:
在用户选中的复选框中,复选框小部件部分的背景是蓝色的,但在 python 代码中设置的背景是普通的(或白色的)。
期望的结果:
当我以编程方式设置背景时,如何更改代码以使背景看起来与用户设置时相同,即在实际框中具有蓝色背景。
讨论:
顺便说一句,如果我两次选中 "set with Python code" 按钮,一次取消选中并再次选中它,则会出现蓝色背景。
我尝试过的:
我还没有找到 属性 的 QCheckBox 或 QAbstractButton 来控制可检查方块的背景。我在 Designer 属性列表中找不到任何明显的复选框。
这是Python代码。
from PyQt5.QtWidgets import QApplication
from PyQt5 import QtWidgets, uic
class X(QtWidgets.QTableWidget):
def __init__(self, ui_file):
super(X, self).__init__()
uic.loadUi(ui_file, self)
self.setwithPythoncode.setChecked(True)
if __name__== '__main__':
app = QApplication([''])
window = X("test_check_boxes.ui")
window.show()
app.exec_()
这里是test_check_boxes.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Form</class>
<widget class="QWidget" name="Form">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>217</width>
<height>201</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<widget class="QCheckBox" name="setbyuserclicking">
<property name="geometry">
<rect>
<x>10</x>
<y>122</y>
<width>161</width>
<height>18</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>30</width>
<height>0</height>
</size>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="autoFillBackground">
<bool>false</bool>
</property>
<property name="text">
<string>Set by user clicking</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
<widget class="QCheckBox" name="notsetanywhere">
<property name="geometry">
<rect>
<x>10</x>
<y>18</y>
<width>141</width>
<height>18</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>30</width>
<height>0</height>
</size>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string>Not set anywhere</string>
</property>
</widget>
<widget class="QCheckBox" name="setwithPythoncode">
<property name="geometry">
<rect>
<x>10</x>
<y>70</y>
<width>181</width>
<height>18</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>30</width>
<height>0</height>
</size>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string>Set with Python code</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</widget>
<resources/>
<connections/>
</ui>
经过一些测试,我发现这可能与以下事实有关:当您调用 setChecked(True)
时,QApplication 仍未激活。
您可以通过在 stateChanged
槽中调用 setChecked(True)
来检查。在这种情况下,该应用程序已经处于活动状态,因此可以按预期工作。
class CheckDemo(QWidget):
def __init__(self, parent = None):
super(CheckDemo, self).__init__(parent)
self.layout = QHBoxLayout()
self.b1 = QCheckBox("Button1", self)
self.b2 = QCheckBox("Button2", self)
self.b3 = QCheckBox("Button3", self)
self.b1.setChecked(False)
self.b2.setChecked(False)
self.b3.setChecked(False)
self.layout.addWidget(self.b1)
self.layout.addWidget(self.b2)
self.layout.addWidget(self.b3)
self.setLayout(self.layout)
self.setWindowTitle("checkbox demo")
self.b2.stateChanged.connect(self.stateSlot)
self.show()
def stateSlot(self, state):
self.b3.setChecked(True)
不过我找到了三种解决此问题的方法。
1.更改 PyQt 版本
如果您使用的是最新版本 5.13.2
,您可以将其回滚到 5.10.1
,您的代码将正常工作。
2。使用 QTimer
这样做会延迟 setChecked
调用。这使 QApplication 有时间处于活动状态。问题是,取决于你的电脑,代码等。它可能无法正常工作,给你带来困难。
class CheckDemo(QWidget):
def __init__(self, parent = None):
super().__init__(parent)
self.layout = QHBoxLayout()
self.b1 = QCheckBox("Button1", self)
self.b2 = QCheckBox("Button2", self)
self.b3 = QCheckBox("Button3", self)
self.layout.addWidget(self.b1)
self.layout.addWidget(self.b2)
self.layout.addWidget(self.b3)
self.b1.setChecked(False)
self.b2.setChecked(False)
self.b3.setChecked(False)
self.setLayout(self.layout)
self.setWindowTitle("checkbox demo")
QTimer.singleShot(500, lambda: self.b2.setChecked(True)) #Here
def main():
app = QApplication(sys.argv)
customWidget = CheckDemo()
app.setTargetObject(ex)
customWidget.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
3。自定义 QApplication subclass
您可以在 event
方法中捕获 QEvent.ApplicationActivate 并从 class.
中调用 initialize
方法
class MyApp(QApplication):
def __init__(self, args):
super().__init__(args)
self.application_first_time_active = True# You need to know when is the first time application was activated
self.target_object = None
def setTargetObject(self, obj):
self.target_object = obj
def event(self, event):
if event.type() == QEvent.ApplicationActivated and self.application_first_time_active:
self.target_object.initialize()
self.application_first_time_active = False
return super().event(event)
class CheckDemo(QWidget):
def __init__(self, parent = None):
super().__init__(parent)
self.layout = QHBoxLayout()
self.b1 = QCheckBox("Button1", self)
self.b2 = QCheckBox("Button2", self)
self.b3 = QCheckBox("Button3", self)
self.layout.addWidget(self.b1)
self.layout.addWidget(self.b2)
self.layout.addWidget(self.b3)
self.b1.setChecked(False)
self.b2.setChecked(False)
self.b3.setChecked(False)
self.setLayout(self.layout)
self.setWindowTitle("checkbox demo")
def initialize(self):
self.b2.setChecked(True)
def main():
app = MyApp(sys.argv)
customWidget = CheckDemo()
app.setTargetObject(customWidget)# Fixed
customWidget.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
我想说这可能是最新 qt 版本的错误。我会向您推荐 opening an issue QtCompany。
问题总结:
上面三个复选框中的两个有复选标记。其中一个值是使用 Python 代码 self.setwithPythoncode.setChecked(True)
设置的,而另一个值是在应用处于 运行.
实际结果: 在用户选中的复选框中,复选框小部件部分的背景是蓝色的,但在 python 代码中设置的背景是普通的(或白色的)。
期望的结果: 当我以编程方式设置背景时,如何更改代码以使背景看起来与用户设置时相同,即在实际框中具有蓝色背景。
讨论: 顺便说一句,如果我两次选中 "set with Python code" 按钮,一次取消选中并再次选中它,则会出现蓝色背景。
我尝试过的: 我还没有找到 属性 的 QCheckBox 或 QAbstractButton 来控制可检查方块的背景。我在 Designer 属性列表中找不到任何明显的复选框。
这是Python代码。
from PyQt5.QtWidgets import QApplication
from PyQt5 import QtWidgets, uic
class X(QtWidgets.QTableWidget):
def __init__(self, ui_file):
super(X, self).__init__()
uic.loadUi(ui_file, self)
self.setwithPythoncode.setChecked(True)
if __name__== '__main__':
app = QApplication([''])
window = X("test_check_boxes.ui")
window.show()
app.exec_()
这里是test_check_boxes.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Form</class>
<widget class="QWidget" name="Form">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>217</width>
<height>201</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<widget class="QCheckBox" name="setbyuserclicking">
<property name="geometry">
<rect>
<x>10</x>
<y>122</y>
<width>161</width>
<height>18</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>30</width>
<height>0</height>
</size>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="autoFillBackground">
<bool>false</bool>
</property>
<property name="text">
<string>Set by user clicking</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
<widget class="QCheckBox" name="notsetanywhere">
<property name="geometry">
<rect>
<x>10</x>
<y>18</y>
<width>141</width>
<height>18</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>30</width>
<height>0</height>
</size>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string>Not set anywhere</string>
</property>
</widget>
<widget class="QCheckBox" name="setwithPythoncode">
<property name="geometry">
<rect>
<x>10</x>
<y>70</y>
<width>181</width>
<height>18</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>30</width>
<height>0</height>
</size>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string>Set with Python code</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</widget>
<resources/>
<connections/>
</ui>
经过一些测试,我发现这可能与以下事实有关:当您调用 setChecked(True)
时,QApplication 仍未激活。
您可以通过在 stateChanged
槽中调用 setChecked(True)
来检查。在这种情况下,该应用程序已经处于活动状态,因此可以按预期工作。
class CheckDemo(QWidget):
def __init__(self, parent = None):
super(CheckDemo, self).__init__(parent)
self.layout = QHBoxLayout()
self.b1 = QCheckBox("Button1", self)
self.b2 = QCheckBox("Button2", self)
self.b3 = QCheckBox("Button3", self)
self.b1.setChecked(False)
self.b2.setChecked(False)
self.b3.setChecked(False)
self.layout.addWidget(self.b1)
self.layout.addWidget(self.b2)
self.layout.addWidget(self.b3)
self.setLayout(self.layout)
self.setWindowTitle("checkbox demo")
self.b2.stateChanged.connect(self.stateSlot)
self.show()
def stateSlot(self, state):
self.b3.setChecked(True)
不过我找到了三种解决此问题的方法。
1.更改 PyQt 版本
如果您使用的是最新版本 5.13.2
,您可以将其回滚到 5.10.1
,您的代码将正常工作。
2。使用 QTimer
这样做会延迟 setChecked
调用。这使 QApplication 有时间处于活动状态。问题是,取决于你的电脑,代码等。它可能无法正常工作,给你带来困难。
class CheckDemo(QWidget):
def __init__(self, parent = None):
super().__init__(parent)
self.layout = QHBoxLayout()
self.b1 = QCheckBox("Button1", self)
self.b2 = QCheckBox("Button2", self)
self.b3 = QCheckBox("Button3", self)
self.layout.addWidget(self.b1)
self.layout.addWidget(self.b2)
self.layout.addWidget(self.b3)
self.b1.setChecked(False)
self.b2.setChecked(False)
self.b3.setChecked(False)
self.setLayout(self.layout)
self.setWindowTitle("checkbox demo")
QTimer.singleShot(500, lambda: self.b2.setChecked(True)) #Here
def main():
app = QApplication(sys.argv)
customWidget = CheckDemo()
app.setTargetObject(ex)
customWidget.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
3。自定义 QApplication subclass
您可以在 event
方法中捕获 QEvent.ApplicationActivate 并从 class.
initialize
方法
class MyApp(QApplication):
def __init__(self, args):
super().__init__(args)
self.application_first_time_active = True# You need to know when is the first time application was activated
self.target_object = None
def setTargetObject(self, obj):
self.target_object = obj
def event(self, event):
if event.type() == QEvent.ApplicationActivated and self.application_first_time_active:
self.target_object.initialize()
self.application_first_time_active = False
return super().event(event)
class CheckDemo(QWidget):
def __init__(self, parent = None):
super().__init__(parent)
self.layout = QHBoxLayout()
self.b1 = QCheckBox("Button1", self)
self.b2 = QCheckBox("Button2", self)
self.b3 = QCheckBox("Button3", self)
self.layout.addWidget(self.b1)
self.layout.addWidget(self.b2)
self.layout.addWidget(self.b3)
self.b1.setChecked(False)
self.b2.setChecked(False)
self.b3.setChecked(False)
self.setLayout(self.layout)
self.setWindowTitle("checkbox demo")
def initialize(self):
self.b2.setChecked(True)
def main():
app = MyApp(sys.argv)
customWidget = CheckDemo()
app.setTargetObject(customWidget)# Fixed
customWidget.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
我想说这可能是最新 qt 版本的错误。我会向您推荐 opening an issue QtCompany。