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.


  • Banned

    This post is deleted!

Log in to reply
 

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