【问题标题】:How to get the item created from dropEvent on a qlistwidget如何获取从 qlistwidget 上的 dropEvent 创建的项目
【发布时间】:2017-03-01 18:35:25
【问题描述】:

所以我正在尝试使用拖放将所选项目从一个 QListWidget 复制到另一个。

无论如何,我可以通过使用 item.setData 传递序列化参数来破解我需要的东西,但我无法找到一种直接的方法来处理在第二个 listWidget 中创建的新项目。

我想我可以查看第二个 QListWidget 中的所有项目,并以某种方式确定刚刚创建的项目,但似乎应该有一种更简单的方法来了解 drop 事件正在创建哪些项目。

import sys
from PyQt4 import QtGui , QtCore


def main():

    app = QtGui.QApplication(sys.argv)

    w = QtGui.QWidget()
    w.resize(250, 150)
    w.move(300, 300)
    w.setWindowTitle('Simple')
    layout=QtGui.QHBoxLayout(w)
    dragList=DragDropListWidget()
    layout.addWidget(dragList)
    dragList.setDragDropMode(QtGui.QAbstractItemView.InternalMove)
    dragList.name='dragList'
    dragList.populate(['one','two','three'])
    dragList2=DragDropListWidget()
    dragList2.setDragDropMode(QtGui.QAbstractItemView.DragDrop)
    dragList2.name='dragList'


    layout.addWidget(dragList2)
    w.show()

    sys.exit(app.exec_())

class scriptsWidget(QtGui.QWidget):


    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self)

        self.name=''

        self.widget_QHBoxLayout = QtGui.QHBoxLayout(self)
        self.widget_QHBoxLayout.setSpacing(0)
        self.widget_QHBoxLayout.setContentsMargins(0, 0, 0, 0)

        self.name_QLabel = QtGui.QLabel(self)
        self.widget_QHBoxLayout.addWidget(self.name_QLabel)

        self.user_QLabel = QtGui.QLabel(self)
        self.widget_QHBoxLayout.addWidget(self.user_QLabel)

        self.widget_QHBoxLayout.setSpacing(0)
        self.widget_QHBoxLayout.setContentsMargins(0, 0, 0, 0)



    def setName(self,name):
        self.name_QLabel.setText(name)
        self.name=name

    def setUser(self,user):
        self.user_QLabel.setText(user)

class customQListWidgetItem(QtGui.QListWidgetItem):


    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self)
        self.name=''

    def setName(self,name):
        self.name=name   




class DragDropListWidget(QtGui.QListWidget):
    _drag_info = []
    def __init__(self, parent = None):

        super(DragDropListWidget, self).__init__(parent)


        self.name=''


    def dragMoveEvent(self, event):
        if event.mimeData().hasUrls():
            event.setDropAction(QtCore.Qt.CopyAction)
            event.accept()

        else:
            super(DragDropListWidget, self).dragMoveEvent(event)


    def dropEvent(self, event):
        print('dropEvent') 
        print event.mimeData().text()

        if event.mimeData().hasText():
            print event.mimeData().text()
            event.setDropAction(QtCore.Qt.CopyAction)
            event.accept()
            links = []
            for url in event.mimeData().urls():
                links.append(str(url.toLocalFile()))
            self.emit(QtCore.SIGNAL("dropped"), links)

        else:
            event.setDropAction(QtCore.Qt.CopyAction)
            super(DragDropListWidget, self).dropEvent(event)
            items = []
            for index in xrange(self.count()):
                items.append(self.item(index))
                print self.item(index).data(QtCore.Qt.UserRole).toPyObject()



    def populate(self,items=[]):
        self.clear()
        for i in items:
            print(i)
            widget = scriptsWidget()
            widget.setName(i)
            widget.setUser('x')
            item = customQListWidgetItem()
            item.setName(i)
            data = (i)
            item.setData(QtCore.Qt.UserRole, data)
            self.addItem(item)
            self.setItemWidget(item,widget)



if __name__ == '__main__':
    main()

【问题讨论】:

    标签: python drag-and-drop pyqt qlistwidget qlistwidgetitem


    【解决方案1】:

    您可以连接到列表视图模型上的rowsInserted 信号

    class DragDropListWidget(...):
    
        def __init__(...):
            ...
            self._dropping = False
            self.model().rowsInserted.connect(self.on_rowsInserted)
    
        def on_rowsInserted(self, parent_index, start, end):
            if self._dropping:
                # Recently dropped items
                items = [self.item(i) for i in range(start, end + 1)]
    
        def dropEvent(self, event):
            self._dropping = True
            # code that drops the new rows
            ...
            self._dropping = False
    

    【讨论】:

    • 我在没有真正帮助之前检查过这个。我仍然需要比较删除前后的列表,以了解新项目的索引是什么。
    • @obfuscated on_rowsInserted 回调应该只为新项目触发。
    • 可能是这样,但另一个问题是,如果项目起源于同一个列表,我需要移动项目而不是复制它(如果项目起源于另一个列表,我想复制它)。
    【解决方案2】:

    有趣.. 好吧,我的解决方案最终是将项目列表存储在第二个列表小部件之前,然后在添加新项目后进行比较,这足够好并且只需要几行代码。然后我将新项目传递给一个函数,该函数使用在第一个列表小部件中创建项目时使用的相同类来创建项目,并且我在 .data(QtCore.Qt.UserRole) 中传递了有关的序列化信息

    def dropEvent(self, event):
        if event.mimeData().hasText():
            event.setDropAction(QtCore.Qt.CopyAction)
            event.accept()
            links = []
            for url in event.mimeData().urls():
                links.append(str(url.toLocalFile()))
            self.emit(QtCore.SIGNAL("dropped"), links)
    
        else:
            event.setDropAction(QtCore.Qt.CopyAction)
            items = []
            for index in xrange(self.count()):
                items.append(self.item(index))
    
            super(DragDropListWidget, self).dropEvent(event)
    
            for index in xrange(self.count()):
                if self.item(index) not in items:
                    self.populateDrop(self.item(index), index, [self.item(index).data(QtCore.Qt.UserRole).toPyObject()])
    
    def populateDrop(self,item,row,items=[]):
        for i in items:
            widget = scriptsWidget()
            widget.setName(i)
            widget.setUser('x')
            self.takeItem(row)
            item = customQListWidgetItem()
            item.setName(i)
            item.setWhatsThis(i)
            data = (i)
            item.setData(QtCore.Qt.UserRole, data)
            self.insertItem (row, item)
            self.setItemWidget(item,widget)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-04-22
      • 2014-08-17
      • 2021-04-23
      • 1970-01-01
      • 2018-07-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多