QListWidget的indexesMoved信号为何未触发?
问题原因与解决方案
核心问题1:indexesMoved信号未触发的原因
QListWidget设置InternalMove拖拽模式后,默认的拖拽移动逻辑是通过剪切+粘贴项实现的,并非调用模型的moveRows()方法,而indexesMoved信号只有在模型通过moveRows/moveColumns主动移动索引时才会触发,所以拖拽操作不会触发该信号。
核心问题2:遍历列表项的方式错误
你代码中self.clients_list.items(ClientListWidget)的写法是错误的,QListWidget的items()方法不接受参数,无法直接筛选自定义部件类型。正确的做法是通过索引遍历项,再获取对应的自定义部件。
修复方案
方案1:监听模型的rowsMoved信号替换indexesMoved
QListWidget的底层模型是QStandardItemModel,拖拽移动项时会触发模型的rowsMoved信号,我们可以监听这个信号来触发配置保存逻辑:
def lists_init(self): self.clients_list.setGeometry(QRect(10, 30, 230, 120)) # 原有填充列表的代码... self.clients_list.doubleClicked.connect(self.choose_client) self.clients_list.setDragDropMode(QAbstractItemView.InternalMove) # 替换indexesMoved为模型的rowsMoved信号 self.clients_list.model().rowsMoved.connect(self.widget_position_changed)
方案2:重写QListWidget的dropEvent
如果需要更精确地控制拖拽完成时机,也可以自定义QListWidget子类,重写dropEvent方法:
class CustomListWidget(QListWidget): def dropEvent(self, event): super().dropEvent(event) # 拖拽完成后触发配置保存 self.parent().widget_position_changed() # 在ChooseClientWindow的__init__中替换原有列表: self.clients_list = CustomListWidget(self.clients_group_box)
修正列表项遍历逻辑
把widget_position_changed方法里的遍历代码改成正确的方式:
def widget_position_changed(self): settings: dict[int, str] = {} for index in range(self.clients_list.count()): item = self.clients_list.item(index) # 获取自定义部件 widget = self.clients_list.itemWidget(item) if isinstance(widget, ClientListWidget): settings[index] = widget.name_label.text() json.dump(settings, open('settings.txt', 'w'), indent=4)
内容的提问来源于stack exchange,提问作者Konstantin Leontyev
相关产品推荐
相关产品推荐

