You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 18:13:23