Drag and Drop Text between tableview
-
Hi, i need to drag text from a tableview (Elenco) to another tableview (Piano)
mModel = new QSqlTableModel(this); mModel->setTable("ORDINI"); ui->tableView_Elenco->setModel(mModel); // Ordina al click su Header ui->tableView_Elenco->setSortingEnabled(true); ui->tableView_Elenco->horizontalHeader()->setSectionsClickable(1); ui->tableView_Elenco->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); ui->tableView_Elenco->setColumnHidden(0,true); ui->tableView_Elenco->setColumnHidden(1,true); ui->tableView_Elenco->setColumnHidden(2,true); ui->tableView_Elenco->setColumnHidden(11,true); ui->tableView_Elenco->setColumnHidden(12,true); ui->tableView_Elenco->setColumnHidden(13,true); ui->tableView_Elenco->setColumnHidden(14,true); ui->tableView_Elenco->setColumnHidden(15,true); ui->tableView_Elenco->setColumnHidden(16,true); ui->tableView_Elenco->setEditTriggers(QAbstractItemView::NoEditTriggers); //DnD ui->tableView_Elenco->setDragEnabled(true); ui->tableView_Elenco->setAcceptDrops(true); ui->tableView_Elenco->setDropIndicatorShown(true); ui->tableView_Elenco->setDefaultDropAction(Qt::CopyAction); ui->tableView_Elenco->setDragDropMode(QAbstractItemView::DragOnly); ui->tableView_Elenco->setDragDropOverwriteMode(false); //DnD ui->tableView_Elenco->show();
// TABLEVIEW PIANO QStandardItemModel *model = new QStandardItemModel(7,6,this); //Rows,Columns //INTESTAZIONE COLONNE model->setHorizontalHeaderItem(0, new QStandardItem(QString("MACCHINA"))); model->setHorizontalHeaderItem(1, new QStandardItem(QString("1"))); model->setHorizontalHeaderItem(2, new QStandardItem(QString("2"))); model->setHorizontalHeaderItem(3, new QStandardItem(QString("3"))); model->setHorizontalHeaderItem(4, new QStandardItem(QString("4"))); model->setHorizontalHeaderItem(5, new QStandardItem(QString("5"))); model->setHorizontalHeaderItem(6, new QStandardItem(QString("6"))); // MACCHINE model->setItem(0,0,new QStandardItem(QString("PRESSA T63"))); model->setItem(1,0,new QStandardItem(QString("PRESSA T100"))); model->setItem(2,0,new QStandardItem(QString("PRESSA T160"))); model->setItem(3,0,new QStandardItem(QString("PRESSA T199"))); model->setItem(4,0,new QStandardItem(QString("PRESSA T200"))); model->setItem(5,0,new QStandardItem(QString("PRESSA T201"))); model->setItem(6,0,new QStandardItem(QString("TRAPANI"))); model->setItem(7,0,new QStandardItem(QString("OMERA/PIEGAT"))); model->setItem(8,0,new QStandardItem(QString("CARTATRICE"))); model->setItem(9,0,new QStandardItem(QString("TRONCA/CNC"))); model->setItem(10,0,new QStandardItem(QString("PUNT/MONTA"))); model->setItem(11,0,new QStandardItem(QString("SALDATRICI"))); model->setItem(12,0,new QStandardItem(QString("ROBOT"))); ui->tableView_Piano->horizontalHeader()->setSectionsClickable(1); ui->tableView_Piano->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); ui->tableView_Piano->setModel(model); //DnD ui->tableView_Piano->setDragEnabled(false); ui->tableView_Piano->setAcceptDrops(true); ui->tableView_Piano->setDropIndicatorShown(true); ui->tableView_Piano->setDefaultDropAction(Qt::CopyAction); ui->tableView_Piano->setDragDropOverwriteMode(false); //Dnd
this is my .h file:
#ifndef PIANIFICAPRODUZIONE_H #define PIANIFICAPRODUZIONE_H #include <QDialog> #include <QSqlTableModel> #include <QTextEdit> #include <QMouseEvent> #include <QDrag> #include <QMimeData> namespace Ui { class pianificaproduzione; } class pianificaproduzione : public QDialog { Q_OBJECT public: explicit pianificaproduzione(QWidget *parent = nullptr, const QString &Utente="", const QString &Password=""); ~pianificaproduzione() override; QString Utente, Password; //DnD protected: void dragEnterEvent(QDragEnterEvent *event) override; void dropEvent(QDropEvent *event) override; void mousePressEvent(QMouseEvent *event) override; //Fine DnD private: Ui::pianificaproduzione *ui; QSqlTableModel *mModel; QSqlDatabase mDatabase; }; #endif // PIANIFICAPRODUZIONE_H
now i'm not able to implement (in .cpp file):
- dragEnterEvent;
- dropEvent;
- mousePressEvent.
Anyone can help me please??
-
Hi,
Why are you trying to implement drag and drop in the dialog rather than the view itself ?
-
@TheCipo76 said in Drag and Drop Text between tableview:
it's the correct way?
No, the correct way is via
QAbstractItemModel::canDropMimeData
/QAbstractItemModel::dropMimeData
but if you useQStandardItemModel
then it should already be implemented for free, no need do do anything manually -
-
I see, it's a bit fiddly because
QStandardItemModel
by default appends child items.
Try something like this:#include <QApplication> #include <QMimeData> #include <QStandardItemModel> #include <QTableView> #include <QSqlDatabase> #include <QSqlQuery> #include <QSqlTableModel> #include <QHBoxLayout> class DragSqlTableModel : public QSqlTableModel{ Q_DISABLE_COPY(DragSqlTableModel) public: using QSqlTableModel::QSqlTableModel; Qt::ItemFlags flags(const QModelIndex &index) const override {return QSqlTableModel::flags(index) | Qt::ItemIsDragEnabled;} }; class OverwriteModel : public QStandardItemModel{ Q_DISABLE_COPY(OverwriteModel) public: using QStandardItemModel::QStandardItemModel; bool dropMimeData(const QMimeData *data, Qt::DropAction, int, int, const QModelIndex &parent) override { const QByteArray mimeData = data->data("application/x-qabstractitemmodeldatalist"); QDataStream mimeReader(mimeData); int junk; QMap<int,QVariant> modelData; for(;;){ mimeReader.startTransaction(); mimeReader >> junk >> junk >> modelData; if(!mimeReader.commitTransaction()) break; setItemData(parent,modelData); } return true; } }; int main(int argc, char **argv) { QApplication app(argc,argv); QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE"); db.setDatabaseName(":memory:"); if (!db.open()) return 1; QSqlQuery query; Q_ASSUME(query.exec("create table person (id int primary key, " "firstname varchar(20), lastname varchar(20))")); Q_ASSUME(query.exec("insert into person values(101, 'Danny', 'Young')")); Q_ASSUME(query.exec("insert into person values(102, 'Christine', 'Holand')")); Q_ASSUME(query.exec("insert into person values(103, 'Lars', 'Gordon')")); Q_ASSUME(query.exec("insert into person values(104, 'Roberto', 'Robitaille')")); Q_ASSUME(query.exec("insert into person values(105, 'Maria', 'Papadopoulos')")); OverwriteModel destination(3,2); DragSqlTableModel source(nullptr,db); source.setTable("person"); source.select(); QWidget mainWid; auto sourceView=new QTableView(&mainWid); sourceView->setDragEnabled(true); sourceView->setModel(&source); auto destinationView=new QTableView(&mainWid); destinationView->setModel(&destination); destinationView->setDragDropMode(QAbstractItemView::DropOnly); QHBoxLayout* mainLay = new QHBoxLayout(&mainWid); mainLay->addWidget(destinationView); mainLay->addWidget(sourceView); mainWid.show(); return app.exec(); }
-
@VRonin i have copied the class definition into my dialog.h
#ifndef PIANIFICAPRODUZIONE_H #define PIANIFICAPRODUZIONE_H #include <QDialog> #include <QSqlTableModel> #include <QMimeData> #include <QTableView> #include <QStandardItemModel> #include <QSqlDatabase> #include <QSqlQuery> #include <QSqlTableModel> class DragSqlTableModel : public QSqlTableModel{ Q_DISABLE_COPY(DragSqlTableModel) public: using QSqlTableModel::QSqlTableModel; Qt::ItemFlags flags(const QModelIndex &index) const override {return QSqlTableModel::flags(index) | Qt::ItemIsDragEnabled;} }; class OverwriteModel : public QStandardItemModel{ Q_DISABLE_COPY(OverwriteModel) public: using QStandardItemModel::QStandardItemModel; bool dropMimeData(const QMimeData *data, Qt::DropAction, int, int, const QModelIndex &parent) override { const QByteArray mimeData = data->data("application/x-qabstractitemmodeldatalist"); QDataStream mimeReader(mimeData); int junk; QMap<int,QVariant> modelData; for(;;){ mimeReader.startTransaction(); mimeReader >> junk >> junk >> modelData; if(!mimeReader.commitTransaction()) break; setItemData(parent,modelData); } return true; } }; namespace Ui { class pianificaproduzione; } class pianificaproduzione : public QDialog { Q_OBJECT public: explicit pianificaproduzione(QWidget *parent = nullptr, const QString &Utente="", const QString &Password=""); ~pianificaproduzione(); QString Utente, Password; private: Ui::pianificaproduzione *ui; QSqlTableModel *mModel; QSqlDatabase mDatabase; DragSqlTableModel *source; OverwriteModel *model; }; #endif // PIANIFICAPRODUZIONE_H
i've used DragSqlTableModel instead QSqlTableModel in dialog.cpp
source = new DragSqlTableModel(this); source->setTable("ORDINI"); source->select(); ui->tableView_Elenco->setModel(source); ui->tableView_Elenco->setEditTriggers(QAbstractItemView::NoEditTriggers); ui->tableView_Elenco->setSelectionMode(QAbstractItemView::SingleSelection); ui->tableView_Elenco->setDragEnabled(true); ui->tableView_Elenco->setDropIndicatorShown(true); ui->tableView_Elenco->setSortingEnabled(true); // Ordina al click su Header ui->tableView_Elenco->horizontalHeader()->setSectionsClickable(1); ui->tableView_Elenco->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); ui->tableView_Elenco->setColumnHidden(0, true); ui->tableView_Elenco->setColumnHidden(1, true); ui->tableView_Elenco->setColumnHidden(2, true); ui->tableView_Elenco->setColumnHidden(7, true); ui->tableView_Elenco->setColumnHidden(9, true); ui->tableView_Elenco->setColumnHidden(10, true); ui->tableView_Elenco->setColumnHidden(11, true); ui->tableView_Elenco->setColumnHidden(12, true); ui->tableView_Elenco->setColumnHidden(13, true); ui->tableView_Elenco->setColumnHidden(14, true); ui->tableView_Elenco->setColumnHidden(15, true); ui->tableView_Elenco->setColumnHidden(16, true); ui->tableView_Elenco->show(); // TABLEVIEW PIANO //QStandardItemModel *model = new QStandardItemModel(7,6,this); //Rows,Columns OverwriteModel *model = new OverwriteModel(7,6,this); //INTESTAZIONE COLONNE model->setHorizontalHeaderItem(0, new QStandardItem(QString("MACCHINA"))); model->setHorizontalHeaderItem(1, new QStandardItem(QString("1"))); model->setHorizontalHeaderItem(2, new QStandardItem(QString("2"))); model->setHorizontalHeaderItem(3, new QStandardItem(QString("3"))); model->setHorizontalHeaderItem(4, new QStandardItem(QString("4"))); model->setHorizontalHeaderItem(5, new QStandardItem(QString("5"))); model->setHorizontalHeaderItem(6, new QStandardItem(QString("6"))); // MACCHINE model->setItem(0,0,new QStandardItem(QString("PRESSA T63"))); model->setItem(1,0,new QStandardItem(QString("PRESSA T100"))); model->setItem(2,0,new QStandardItem(QString("PRESSA T160"))); model->setItem(3,0,new QStandardItem(QString("PRESSA T199"))); model->setItem(4,0,new QStandardItem(QString("PRESSA T200"))); model->setItem(5,0,new QStandardItem(QString("PRESSA T201"))); model->setItem(6,0,new QStandardItem(QString("TRAPANI"))); model->setItem(7,0,new QStandardItem(QString("OMERA/PIEGAT"))); model->setItem(8,0,new QStandardItem(QString("CARTATRICE"))); model->setItem(9,0,new QStandardItem(QString("TRONCA/CNC"))); model->setItem(10,0,new QStandardItem(QString("PUNT/MONTA"))); model->setItem(11,0,new QStandardItem(QString("SALDATRICI"))); model->setItem(12,0,new QStandardItem(QString("ROBOT"))); ui->tableView_Piano->horizontalHeader()->setSectionsClickable(1); ui->tableView_Piano->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); ui->tableView_Piano->setModel(model); ui->tableView_Elenco->setDragDropMode(QAbstractItemView::DropOnly);
but don't works.. when i try to drag text.. nothing happen..
i don't understand where is the problem..
Any help? -
-
Works perfectly in a dialog as well:
#include <QApplication> #include <QMimeData> #include <QStandardItemModel> #include <QTableView> #include <QSqlDatabase> #include <QSqlQuery> #include <QSqlTableModel> #include <QHBoxLayout> #include <QDialog> #include <QTimer> class DragSqlTableModel : public QSqlTableModel{ Q_DISABLE_COPY(DragSqlTableModel) public: using QSqlTableModel::QSqlTableModel; Qt::ItemFlags flags(const QModelIndex &index) const override {return QSqlTableModel::flags(index) | Qt::ItemIsDragEnabled;} }; class OverwriteModel : public QStandardItemModel{ Q_DISABLE_COPY(OverwriteModel) public: using QStandardItemModel::QStandardItemModel; bool dropMimeData(const QMimeData *data, Qt::DropAction, int, int, const QModelIndex &parent) override { const QByteArray mimeData = data->data("application/x-qabstractitemmodeldatalist"); QDataStream mimeReader(mimeData); int junk; QMap<int,QVariant> modelData; for(;;){ mimeReader.startTransaction(); mimeReader >> junk >> junk >> modelData; if(!mimeReader.commitTransaction()) break; setItemData(parent,modelData); } return true; } }; int main(int argc, char **argv) { QApplication app(argc,argv); QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE"); db.setDatabaseName(":memory:"); if (!db.open()) return 1; QSqlQuery query; Q_ASSUME(query.exec("create table person (id int primary key, " "firstname varchar(20), lastname varchar(20))")); Q_ASSUME(query.exec("insert into person values(101, 'Danny', 'Young')")); Q_ASSUME(query.exec("insert into person values(102, 'Christine', 'Holand')")); Q_ASSUME(query.exec("insert into person values(103, 'Lars', 'Gordon')")); Q_ASSUME(query.exec("insert into person values(104, 'Roberto', 'Robitaille')")); Q_ASSUME(query.exec("insert into person values(105, 'Maria', 'Papadopoulos')")); OverwriteModel destination(3,2); DragSqlTableModel source(nullptr,db); source.setTable("person"); source.select(); QWidget mainWid; QDialog* subDialog = new QDialog(&mainWid); auto sourceView=new QTableView(subDialog); sourceView->setDragEnabled(true); sourceView->setModel(&source); auto destinationView=new QTableView(subDialog); destinationView->setModel(&destination); destinationView->setDragDropMode(QAbstractItemView::DropOnly); QHBoxLayout* mainLay = new QHBoxLayout(subDialog); mainLay->addWidget(destinationView); mainLay->addWidget(sourceView); mainWid.show(); QTimer::singleShot(1000,subDialog,&QDialog::exec); return app.exec(); }
-
@VRonin You're right!
i've put your code in new project's main.cpp and workshowever i 've wrote that i'm not able to use it..
not that your code don't work.Now i will retry to use it in my project.
Thank you and thanks to all others who help me every time.