Implementei uma lista opcional por meio do QListWidget e descobri que, se quiser alterar o estado da caixa de seleção, só posso alterá-lo clicando na caixa de seleção.
Mas eu também queria mudar o estado da caixa de seleção clicando no Item, então conectei o sinal ItemClicked do QListWidget a uma nova função de slot para implementá-lo.
Mais tarde descobri que o estado da caixa de seleção associada ao Item só pode ser alterado clicando no Item, e não na caixa de seleção em si.
Estou curioso para saber o que está acontecendo nesse processo e o que devo fazer para atingir meu objetivo, que é que o estado da caixa de seleção possa ser alterado clicando na caixa de seleção ou no próprio item. Golpe é o meu código:
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)
Isso é causado pelo fato de que, ao tentar alternar a caixa de seleção do item, ele também está sendo clicado, então o estado da verificação é alterado duas vezes .
Você pode verificar isso conectando-se ao
itemChanged
sinal:Ao clicar no indicador de verificação, o sinal é emitido duas vezes, a primeira vez com o novo estado de verificação e a segunda com o estado anterior, definido pela sua função.
Uma solução possível é tornar o item não verificável pelo usuário:
Infelizmente, isso tem a desvantagem de impossibilitar a alternância de estado usando o teclado.
Como alternativa, você pode usar um delegado personalizado e fazê-lo ignorar a liberação do botão esquerdo do mouse sempre que isso acontecer dentro do retângulo do indicador de verificação. Neste caso você não deve alterar as flags dos itens conforme explicado acima.
Ou simplesmente use
itemPressed
em vez deitemClicked
:encontrado aqui