PDA

View Full Version : When does Mimedata() get called?



TEAmerc
12th October 2015, 05:42
I'm trying to re-implement the MimeData() function on a subclassed QTreeWidget so that when I drag and drop items from it they carry some extra text data I specify with them for adding to external text docs. So far I've found that the MimeType() function gets called when a drag begins using std::cerr, but I haven't been able to find when MimeData() gets called to add the text data so that it gets received on drops. I don't want to reimplement the drag and drop operations to add this extra mimedata as I want to keep the standard selection and drag and drop behaviour of a QTreeWidget along with its standard drag behaviour. Or should I be subclassing QTreeWidgetItem and re-implementing its MimeData() function instead of QTreeWidget's?

anda_skoa
12th October 2015, 09:11
So far I've found that the MimeType() function gets called when a drag begins using std::cerr, but I haven't been able to find when MimeData() gets called to add the text data so that it gets received on drops.

I am not sure I understand the question or what kind of issue you run into.
The mimeData() is called when the drag starts and the resulting QMimeData is stored in the QDrag object that handles the Drag&Drop.

The Drop location simply gets that QMimeData instance from the drop event.

Cheers,
_

TEAmerc
13th October 2015, 14:31
Thanks, I thought it was supposed to be like that, but for some reason when I start a drag I don't see the mimedata function get called, and when I do a drop I don't see the text that I've written into the mimeData output.

SigTreeWidget is just being defined as:



class SigTreeWidget : public QTreeWidget
{
Q_OBJECT
public:
explicit SigTreeWidget(QWidget *parent = 0);

Q_SIGNALS:

public Q_SLOTS:
void SelectedSigsDnDHelper(); //Stores the TreeWidget's selected signals in a string when selection changes

private:
QPoint dragStartPosition;
std::string selectedSignals;
QStringList mimeTypes() const;
QMimeData *mimeData(const QModelIndexList &indexes) const;
};


With the full implementation below:



SigTreeWidget::SigTreeWidget(QWidget *parent) :
QTreeWidget(parent)
{
}

void SigTreeWidget::SelectedSigsDnDHelper()
{
QList<QTreeWidgetItem *> itemList = this->selectedItems();

selectedSignals.clear();

while (!itemList.isEmpty())
{
selectedSignals += itemList.takeFirst()->text(1).toStdString() + ".";
}

if (!selectedSignals.empty())
selectedSignals.pop_back();

// std::cerr << "Selected Signals = " << selectedSignals << std::endl;
}

QStringList SigTreeWidget::mimeTypes() const
{
std::cerr << "mimeTypes" << std::endl;

QStringList types;
types << "application/vnd.text.list";
return types;
}

QMimeData *SigTreeWidget::mimeData(const QModelIndexList &indexes) const
{
std::cerr << "mimeData" << std::endl;

QMimeData *mimeData = new QMimeData();
QByteArray encodedData;

QDataStream stream(&encodedData, QIODevice::WriteOnly);

stream << selectedSignals.data();

mimeData->setData("application/vnd.text.list", encodedData);
return mimeData;
}


When I start a drag in the compiled version I see "mimeTypes" output to console, but I never see "mimeData" is why I was wondering when mimeData() is called originally, but from your answer I still don't know why I don't see the mimeData I want being attached to the drag.

anda_skoa
13th October 2015, 15:35
When I start a drag in the compiled version I see "mimeTypes" output to console, but I never see "mimeData" is why I was wondering when mimeData() is called originally, but from your answer I still don't know why I don't see the mimeData I want being attached to the drag.

Your mimeData() method is not called because it does not match the signature of QTreeWidget's mimeData():
http://doc.qt.io/qt-5/qtreewidget.html#mimeData

Cheers,
_

TEAmerc
13th October 2015, 16:15
Thanks for the quick reply. I've changed my mimeData() header and function definition to below, but I still don't see it getting called when I do a drag, only the mimeTypes() function:
Header:


class SigTreeWidget : public QTreeWidget
{
Q_OBJECT
public:
explicit SigTreeWidget(QWidget *parent = 0);

Q_SIGNALS:

public Q_SLOTS:
void SelectedSigsDnDHelper();

private:
QPoint dragStartPosition;
std::string selectedSignals;
QStringList mimeTypes() const;
QMimeData * mimeData(const QList<QTreeWidgetItem *> & items) const;
};


Function Definition:


QMimeData *SigTreeWidget::mimeData(const QList<QTreeWidgetItem *> & items) const
{
(void)items;
std::cerr << "mimeData" << std::endl;

QMimeData *mimeData = new QMimeData();
QByteArray encodedData;

QDataStream stream(&encodedData, QIODevice::WriteOnly);

stream << selectedSignals.data();

mimeData->setData("application/vnd.text.list", encodedData);
return mimeData;
}


Everything else has stayed the same as my last post

Maybe I need something else when I create the SigTreeWidget to enable drag? I've included the code where I create the SigTreeWidget below as well since maybe I'm missing something there too:



// Instantiate the tree Widget
signalTreeWidget = new SigTreeWidget();
signalTreeWidget->setColumnCount(2);

signalTreeWidget->setHeaderHidden(true);
signalTreeWidget->setColumnHidden(1, true);
signalTreeWidget->setEditTriggers(QAbstractItemView::NoEditTriggers) ;
signalTreeWidget->setSelectionMode(QAbstractItemView::ExtendedSelect ion);
signalTreeWidget->setDragEnabled(true);
signalTreeWidget->setDragDropMode(QAbstractItemView::DragOnly);
signalTreeWidget->expandAll();

connect(signalTreeWidget, SIGNAL(itemSelectionChanged()), signalTreeWidget, SLOT(SelectedSigsDnDHelper()));
}


I populate this tree using the selected items in another QTreeWidget though unless you think that part is necessary to include I'll omit it here

Added after 16 minutes:

I found the last reason, it was because I needed the Qt 4.8 header that is



QMimeData * QTreeWidget::mimeData(const QList<QTreeWidgetItem *> items) const


instead of



QMimeData * QTreeWidget::mimeData(const QList<QTreeWidgetItem *> & items) const


My Qt creator says it's based on Qt 5.2.1 so I thought I had to use the Qt 5 documentation but I guess I'm somehow compiling against Qt 4.8 instead.

Anyways thanks for all the help!