Drag and Drop Text between tableview



  • Hi, i need to drag text from a tableview (Elenco) to another tableview (Piano)

    0_1543919492024_Schermata 2018-12-04 alle 11.26.26.png

    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??


  • Lifetime Qt Champion

    Hi,

    Why are you trying to implement drag and drop in the dialog rather than the view itself ?



  • @SGaist i don't know how to do it..

    i'm trying to follow this
    https://doc.qt.io/archives/4.6/model-view-dnd.html
    Using Model/View Classes
    it's the correct way?



  • @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 use QStandardItemModel then it should already be implemented for free, no need do do anything manually



  • @VRonin Thank you for response

    but..

    if i use QStandardItemModel i can't order tableview (i have int value in my database) with a simple click..

    where can i find more information about how to do it with QAbstractItemModel as you up-wrote ?



  • if i use QStandardItemModel i can't order tableview (i have int value in my database) with a simple click

    You can, see QSortFilterProxyModel. Anyway, is the source or the destination being an QSqlTableModel?



  • @VRonin yes, the source was a QSqlTableModel



  • 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();
    }
    


  • This post is deleted!


  • @VRonin Great!! This code works!

    now i've to adapt it to my project

    Thank you very much!!!



  • @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?



  • @SGaist Hi, i have tried the VRonin solution but i'm not able to use it in a dialog.. (in mainwindow works very well!)

    can you tell me how can i implement drag and drop in the view as you suggested??
    or is the same way??



  • 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 works

    however 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.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.