简体   繁体   中英

Drag and drop item text from QTreeView to QLineEdit

I need to drop an item from a QTreeView with a QStandardItemModel into a QLineEdit.

I'm a little lost at how to get the data from the QTreeView. Assuming this has something to do with re-implementing the dropMimeData method but dealing with mimeData is not something I do that often (or fully understand for that matter).

Here's a skeletal bit of example code, I need to drag the items in MyTreeView into MyLineEdit and have it set the text to whatever the item text is.

from PySide.QtCore import *
from PySide.QtGui import *

class MyWidget(QWidget):
    def __init__(self):
        super(MyWidget, self).__init__()

        model = MyModel()
        view = MyTreeView()
        view.setModel(model)
        lineEdit = MyLineEdit()

        model.addItem('My Item')
        model.addItem('My Item2')


        layout = QVBoxLayout()
        layout.addWidget(view)
        layout.addWidget(lineEdit)

        self.setLayout(layout)

class MyLineEdit(QLineEdit):
    def __init__(self):
        super(MyLineEdit, self).__init__()
        self.setAcceptDrops( True )

    def dragEnterEvent(self, event):
        data_type = "application/x-qstandarditemmodeldatalist"
        if event.mimeData().hasFormat(data_type):
            event.accept()
        else:
            event.ignore()

    def dropEvent(self, event):
        data_type = "application/x-qstandarditemmodeldatalist"
        if event.mimeData().hasFormat(data_type):
            #Get the QStandardItem text somehow?
            item_text = 'Get the text somehow'
            self.setText(item_text)


class MyModel(QStandardItemModel):
    def __init__(self):
        super(MyModel, self).__init__()

    def addItem(self, text):        
        root_item = self.invisibleRootItem()
        item = QStandardItem(text)
        root_item.appendRow(item)

class MyTreeView(QTreeView):
    def __init__(self):
        super(MyTreeView, self).__init__()
        self.setDragEnabled( True )

widget = MyWidget()
widget.show()

This can be achieved very simply by reimplementing mimeData in your model:

class MyModel(QStandardItemModel):
    ...
    def mimeData(self, indexes):
        mimedata = super(MyModel, self).mimeData(indexes)
        if indexes:
            mimedata.setText(indexes[0].data())
        return mimedata

That's all that's needed. You don't need to implement dragEnterEvent or dropEvent in the line-edit.

There are several alternatives to obtain the text:

  • Using the mimeData()

def dropEvent(self, event):
    data_type = "application/x-qstandarditemmodeldatalist"
    mimeData = event.mimeData()
    if mimeData.hasFormat(data_type):
        encodedData = mimeData.data(data_type)
        stream = QDataStream(encodedData, QIODevice.ReadOnly)
        row = stream.readInt32()
        column = stream.readInt32()
        it = QStandardItem()
        stream >> it
        self.setText(it.text())

  • Using source() which is the widget where the drag operation is performed, in this case it is the view, then we access the current QModelIndex which is the selected one.

def dropEvent(self, event):
    if isinstance(event.source(), QAbstractItemView):
        ix = event.source().currentIndex()
        self.setText(ix.data())

If you enable the selection of several items then you must use the selected items:

...

class MyLineEdit(QLineEdit):
    def __init__(self):
        super(MyLineEdit, self).__init__()
        self.setAcceptDrops( True )

    def dragEnterEvent(self, event):
        data_type = "application/x-qstandarditemmodeldatalist"
        if event.mimeData().hasFormat(data_type):
            event.accept()
        else:
            event.ignore()

    def dropEvent(self, event):
        if isinstance(event.source(), QAbstractItemView):
            ixdexes = event.source().selectedIndexes()
            text = " ".join([ix.data() for ix in sorted(ixdexes)])
            self.setText(text)


...

class MyTreeView(QTreeView):
    def __init__(self):
        super(MyTreeView, self).__init__()
        self.setDragEnabled( True )
        self.setSelectionMode(QAbstractItemView.MultiSelection)

...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM