我通过QListWidget实现了一个可选列表,然后我发现如果我想改变复选框的状态,我只能通过点击复选框来改变。
但我也想通过点击Item来切换复选框状态,所以我将QListWidget的ItemClicked信号连接到一个新的槽函数来实现。
后来我发现与该项目关联的复选框的状态只能通过单击该项目来更改,而不能通过单击复选框本身来更改。
我很好奇这个过程中发生了什么,以及我应该做什么来实现我的目标,即可以通过单击复选框或项目本身来切换复选框的状态。打击是我的代码:
class Item(QListWidgetItem):
def __init__(self):
super().__init__()
# self.setFlags(Qt.ItemFlag.ItemIsUserCheckable | Qt.ItemFlag.ItemIsSelectable | Qt.ItemFlag.ItemIsEnabled)
self.setCheckState(Qt.CheckState.Unchecked)
self.setToolTip("double click edit")
class MainWindow(QWidget):
def __init__(self):
super().__init__()
layout = QVBoxLayout()
self.add_btn = QPushButton("add")
self.select_all = QPushButton("select all")
self.del_btn = QPushButton("delete")
btn_layout = QHBoxLayout()
btn_layout.addWidget(self.select_all)
btn_layout.addWidget(self.add_btn)
btn_layout.addWidget(self.del_btn)
self.list_widget = QListWidget()
self.list_widget.setSelectionMode(QListWidget.SelectionMode.ContiguousSelection)
self.list_widget.setAlternatingRowColors(True)
layout.addLayout(btn_layout)
layout.addWidget(self.list_widget)
self.setLayout(layout)
self.add_btn.clicked.connect(self.addItem)
# self.list_widget.itemClicked.connect(self.itemClickedEvent)
def addItem(self):
item = Item()
item.setText("test")
self.list_widget.addItem(item)
def itemClickedEvent(self, item: QListWidgetItem):
pass
if item.checkState() == Qt.CheckState.Checked:
item.setCheckState(Qt.CheckState.Unchecked)
else:
item.setCheckState(Qt.CheckState.Checked)
这是因为,当尝试切换该项目的复选框时,它也被单击,因此检查状态实际上更改了两次。
您可以通过连接信号来验证这一点
itemChanged
:当您单击检查指示器时,信号会发出两次,第一次是新的检查状态,第二次是以前的状态,由您的函数设置。
一个可能的解决方案是使该项目不可由用户检查:
不幸的是,这样做的缺点是无法使用键盘切换状态。
作为替代方案,您可以使用自定义委托,并使其忽略在检查指示符矩形内发生的鼠标左键释放。在这种情况下,您不得按照上面的说明更改项目标志。
或者简单地使用
itemPressed
而不是itemClicked
:在这里找到