如何使用QListWidget响应内部拖放操作?

Chr*_* B. 8 qt qt4 pyqt pyqt4

我有一个Qt4应用程序(使用PyQt绑定),其中包含a QListWidget,初始化如下:

class MyList(QtGui.QListWidget):
    def __init__(self):
        QtGui.QListWidget.__init__(self)
        self.setDragDropMode(self.InternalMove)
Run Code Online (Sandbox Code Playgroud)

我可以添加项目,这允许我拖放以重新排序列表.但是如何在用户重新排序列表时收到通知?我尝试dropMimeData(self, index, data, action)在类中添加一个方法,但它永远不会被调用.

Cha*_*ani 13

我有一个更简单的方法.:)

您实际上可以使用myList->model()- 来访问listwidget的内部模型,并且从那里可以获得许多信号.

如果您只关心拖放,请连接到layoutChanged.如果你有移动按钮(通常用remove + add实现)也可以连接rowsInserted.

如果你想知道什么感动了,rowsMoved可能会更好layoutChanged.


Tre*_*out 7

我只是不得不处理这个,这是一个痛苦的屁股,但这是做什么:

您必须eventFilterListWidget子类上安装一个,然后观察该ChildRemoved事件.此事件包括移动和移除,因此它应该用于通过拖放在列表中重新排列项目.

我用C++编写Qt,但这是一个pythonification版本:

class MyList(QtGui.QListWidget):
    def __init__(self):
        QtGui.QListWidget.__init__(self)
        self.setDragDropMode(self.InternalMove)
        self.installEventFilter(self)

    def eventFilter(self, sender, event):
        if (event.type() == QEvent.ChildRemoved):
            self.on_order_changed()
        return False # don't actually interrupt anything

    def on_order_changed(self):
        # do magic things with our new-found knowledge
Run Code Online (Sandbox Code Playgroud)

如果您有其他类包含此列表,您可能希望在那里移动事件过滤器方法.希望这会有所帮助,我知道在解决这个问题之前,我必须与之斗争一天.


Cas*_*Cas 5

我发现Trey Stout的答案确实有效,但是当列表顺序没有实际改变时,我显然得到了事件.我转向Chani的答案,它确实按照要求工作但没有代码我花了一些时间在python中实现.

我以为我会分享代码片段以帮助未来的访问者:

class MyList(QListWidget):
    def __init__(self):
        QListWidget.__init__(self)
        self.setDragDropMode(self.InternalMove)
        list_model = self.model()
        list_model.layoutChanged.connect(self.on_layout_changed)

    def on_layout_changed(self):
        print "Layout Changed"
Run Code Online (Sandbox Code Playgroud)

这是在PySide中测试的,但是没有理由在PyQt中不起作用.