Reputation: 555
I have a QListWidget with rows of simple text. I want to set it up so the user can drag and drop this data into some QLineEdit objects.
I have turned on drag and drop for both types but it doesn't allow me to drag and drop from QListWidget to QLineEdit. However, it does allow me to drag from one QLineEdit to another QLineEdit.
I didn't re-implement any methods so far. All I did was to turn on drag and drop features in Edit view.
How do I enable drag and drop from QListWidget to QLineEdit? Which methods do I need to re-implement?
Thanks,
Upvotes: 2
Views: 2572
Reputation: 95
For the completeness of the answer: you need to subclass QLineEdit (create MyLineEdit class, which inherits from QLineEdit), and replace usage of QLineEdit with MyLineEdit (usually inside xxxx.ui file):
Create file: MyLineEdit.h:
#include <QLineEdit>
class MyLineEdit : public QLineEdit
{
public:
MyLineEdit(QWidget *parent = 0);
~MyLineEdit();
void dragEnterEvent(QDragEnterEvent *e);
void dragMoveEvent(QDragMoveEvent *e);
void dropEvent(QDropEvent *e);
};
Create file: MyLineEdit.cpp:
#include "MyLineEdit.h"
#include <QDragMoveEvent>
#include <QDropEvent>
#include <QUrl>
#include <QFileInfo>
MyLineEdit::MyLineEdit(QWidget *parent)
: QLineEdit(parent)
{}
MyLineEdit::~MyLineEdit()
{}
void MyLineEdit::dragEnterEvent(QDragEnterEvent *e){
if (e->mimeData()->hasUrls()) {
e->acceptProposedAction();
}
}
void MyLineEdit::dragMoveEvent(QDragMoveEvent *e){
if (e->mimeData()->hasUrls()) {
e->acceptProposedAction();
}
}
void MyLineEdit::dropEvent(QDropEvent *event){
const QMimeData* mimeData = event->mimeData();
if (mimeData->hasUrls())
{
QStringList pathList;
QList<QUrl> urlList = mimeData->urls();
for (int i = 0; i < urlList.size() && i < 32; ++i)
{
QString str = urlList.at(i).toLocalFile();
if (!str.isEmpty())
{
// support txt/csv files only
QString suffix = QFileInfo(str).suffix();
if (suffix == "txt" || suffix == "csv") // place here whatever suffix you want
{
// action - set the file path field to the name of the dropped file
this->setText(str);
event->acceptProposedAction();
break;
}
}
}
}
}
And change the usage, for example, from this:
<widget class="QLineEdit" name="lineEdit_xxxx">
to this:
<widget class="MyLineEdit" name="lineEdit_xxxx">
Upvotes: 0
Reputation: 555
I figured it out.
FYI:
You need to subclass QLineEdit and re-implement dragEnterEvent and dropEvent.
void MyLineEdit::dragEnterEvent(QDragEnterEvent *e){
if(e->mimeData()->hasFormat("application/x-qabstractitemmodeldatalist")){
e->acceptProposedAction();
}
}
void MyLineEdit::dropEvent(QDropEvent *e){
QByteArray encoded = e->mimeData()->data("application/x-qabstractitemmodeldatalist");
QDataStream strm(&encoded, QIODevice::ReadOnly);
while(!strm.atEnd()){
int row, col;
QMap<int, QVariant> data;
strm >> row >> col >> data;
this->setText(data[0].toString());
}
}
Upvotes: 3
Reputation: 4029
Since you are trying to dnd from different types you drag differen mime data. Therefor the QLineEdit does not know how to handle the data being dropped. Subclass your widget and implement dropEvent() and eventually you also need dragEnterEvent() dragLeaveEvent() and dragMoveEvent().
Upvotes: 2