【问题标题】:Qt After drop eventQt 丢弃事件后
【发布时间】:2011-11-30 09:18:04
【问题描述】:

在小部件上发生放置事件后,我需要处理一些数据。

即用户选择列表 A 中的一些项目并将它们放入列表 B。我的程序需要在 B 添加从 A 中选择的项目后比较这两个列表。

有什么想法吗?

【问题讨论】:

    标签: qt events pyqt drag-and-drop qlistwidget


    【解决方案1】:

    这是一个 PyQt 脚本,它演示了两种捕获丢弃事件的方法:

    from PyQt4 import QtGui, QtCore
    
    class Window(QtGui.QMainWindow):
        def __init__(self):
            QtGui.QMainWindow.__init__(self)
            widget = QtGui.QWidget(self)
            self.setCentralWidget(widget)
            layout = QtGui.QVBoxLayout(widget)
            self.listA = ListWidget(self)
            self.listB = QtGui.QListWidget(self)
            self.listB.viewport().installEventFilter(self)
            for widget in (self.listA, self.listB):
                widget.setAcceptDrops(True)
                widget.setDragEnabled(True)
                for item in 'One Two Three Four Five Six'.split():
                    widget.addItem(item)
                layout.addWidget(widget)
    
        def eventFilter(self, source, event):
            if (event.type() == QtCore.QEvent.Drop and
                source is self.listB.viewport()):
                self.listB.dropEvent(event)
                if event.isAccepted():
                    print 'eventFilter', self.listB.count()
                return True
            return QtGui.QMainWindow.eventFilter(self, source, event)
    
    class ListWidget(QtGui.QListWidget):
        def __init__(self, parent):
            QtGui.QListWidget.__init__(self, parent)
    
        def dropEvent(self, event):
            QtGui.QListWidget.dropEvent(self, event)
            if event.isAccepted():
                print 'dropEvent', self.count()
    
    if __name__ == '__main__':
    
        import sys
        app = QtGui.QApplication(sys.argv)
        window = Window()
        window.show()
        sys.exit(app.exec_())
    

    【讨论】:

    • tableView-> viewport() ->installEventFilter(this) 是这里的重要部分。 :-)
    【解决方案2】:

    您正在收听的事件是QDropEvent。要在收到事件时做一些工作,您需要:


    编辑:更深入:

    1. 重新实现 dropEvent

    标题:

    cDropTarget : public QWidget
    {
      Q_OBJECT
    
    public:
      cDropTarget(QWidget *Parent = 0);
    
    protected:
      virtual void dropEvent(QDropEvent *event);
    }
    

    实施:

    cDropTarget::cDropTarget(QWidget *Parent)
      : QWidget(Parent)
    {
      setAcceptDrops(true);
    }
    
    void cDropTarget::dropEvent(QDropEvent *event)
    {
      //check that you want to process the drop event
      //i.e. its mimeData()->hasFormat(that you can interpret)
    
      //extract mimeData() from the drop event
    
      //do something with it
    }
    
    1. 使用单独的事件过滤器

    标题:

    cDropEventFilter : public QObject
    {
       ...
    
    protected:
      virtual bool eventFilter(QObject *watched, QEvent *event);
    
       ...
    }
    

    实施:

    bool cDropEventFilter::eventFilter(QObject *watched, QEvent *event)
    {
      if(event->type() == QEvent::DropEnter)
      {
        QDropEvent *DropEvent = static_cast<QDropEvent*>(event);
        if (DropEvent->mimeData()->hasFormat(MIME_TYPE))
        {
    
          DropEvent->acceptProposedAction();
          return true;
        }
      }
      else
      {
        return QObject::eventFilter(watched, event);
      }
    
      //Handle all events not matching mimeData format MIME_TYPE
      event->ignore();
      return true;
    }
    

    【讨论】:

    • 谢谢,你能举个例子吗?
    • 我之前尝试过创建自己的列表类,并用我自己的自定义事件覆盖 drop 事件,但无法获取代码来保留丢弃的小部件。感谢您提供详细信息和示例:)
    【解决方案3】:

    搞定了!

    我的代码给感兴趣的人:

    class MyList(QListWidget):
        def __init__(self , parent = None):
            super(MyList, self).__init__(parent)
            
            self.setAlternatingRowColors(True)
            self.setDragDropMode( QAbstractItemView.InternalMove ) 
    
    
        def dropEvent( self , event ):
            # get index to insert at
            insertPos   = event.pos()
            fromList    = event.source()
            insertRow   = fromList.row( fromList.itemAt( insertPos ) )
        
            lowestRow = insertRow
            for item in fromList.selectedItems():
                name = item.text()
                sip.delete( item )
            
                listItem = QListWidgetItem( name )
                listItem.setTextAlignment( Qt.AlignHCenter )
                self.insertItem( insertRow , listItem ) 
                insertRow += 1
            
            self.emit( SIGNAL("stuffDropped") , lowestRow )
        
            event.accept()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-19
      • 1970-01-01
      • 2013-06-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多