QTableView Drag and Drop



  • Hi everybody,
    I want to realize following issue with two TableViews:

    • TableView A and TableView B have a different type of data
    • The user shall be able to reorder the elements of B (! without overwriting existing data-sets !)
    • The user shall be able to drag elements from A to B (data-set must be "converted" of course)

    I thought that can't be so difficult...
    Currently I have problems with step 2 (reorder elements), because if I move on row over another the other row will be overwritten.

    Code for Table A:

    //selection behavior
        tableViewA->setSelectionBehavior(QAbstractItemView::SelectRows);
        tableViewA->setSelectionMode(QAbstractItemView::SingleSelection);
    //drag and drop
        tableViewA->setDragEnabled(true);
        tableViewA->setDropIndicatorShown(true);
        tableViewA->setDragDropMode(QAbstractItemView::InternalMove);
        tableViewA->setDragDropOverwriteMode(false);
    

    Thank you for your help.



  • usually when i do stuff like this i will subclass and modify the drag drop events/signals/slots to do what i want them to do.



  • Thank you.
    I'm new to Qt. Do you have an example or something like that?





  • I decided first to read the article about Model/View Programming (http://doc.qt.io/qt-5.5/model-view-programming.html).
    There is a simple dnd example. I tried it but it doesn't work. Either the example or me is wrong.
    Here is my code of the main function:

    #include "stringlistmodel.h"
    #include <QApplication>
    #include <QListView>
    
    int main(int argc, char *argv[])
    {
        QApplication app(argc, argv);
    
        QStringList list({"a","b","c","d","e","f"});
        StringListModel *model = new StringListModel(list);
        QListView *view = new QListView();
        view->setModel(model);
        view->setSelectionMode(QAbstractItemView::SingleSelection);
        view->setDragDropMode(QAbstractItemView::InternalMove);
        view->setDragEnabled(true);
        view->setAcceptDrops(true);
        view->setDropIndicatorShown(true);
        view->show();
    
        return app.exec();
    }
    

    stringlistmodel.h:

    #include <QAbstractListModel>
    #include <QStringList>
    
    class StringListModel : public QAbstractListModel
    {
        Q_OBJECT
    public:
        StringListModel(const QStringList &strings, QObject *parent = 0);
    
    
        int rowCount(const QModelIndex &parent = QModelIndex()) const;
        QVariant data(const QModelIndex &index, int role) const;
        QVariant headerData(int section, Qt::Orientation orientation,
                            int role = Qt::DisplayRole) const;
    
        Qt::ItemFlags flags(const QModelIndex &index) const;
    
        bool insertRows(int position, int rows, const QModelIndex &index = QModelIndex());
        bool removeRows(int position, int rows, const QModelIndex &index = QModelIndex());
    
        Qt::DropActions supportedDropActions() const;
    
    private:
        QStringList stringList;
    };
    

    stringlistmodel.cpp:

    #include "stringlistmodel.h"
    
    StringListModel::StringListModel(const QStringList &strings, QObject *parent)
        : QAbstractListModel(parent), stringList(strings)
    {
    }
    
    int StringListModel::rowCount(const QModelIndex &parent) const
    {
        return stringList.count();
    }
    
    QVariant StringListModel::data(const QModelIndex &index, int role) const
    {
        if (!index.isValid())
            return QVariant();
    
        if (index.row() >= stringList.size())
            return QVariant();
    
        if (role == Qt::DisplayRole)
            return stringList.at(index.row());
        else
            return QVariant();
    }
    
    QVariant StringListModel::headerData(int section, Qt::Orientation orientation,
                                         int role) const
    {
        if (role != Qt::DisplayRole)
            return QVariant();
    
        if (orientation == Qt::Horizontal)
            return QString("Column %1").arg(section);
        else
            return QString("Row %1").arg(section);
    }
    
    Qt::ItemFlags StringListModel::flags(const QModelIndex &index) const
    {
        Qt::ItemFlags defaultFlags = QAbstractListModel::flags(index);
    
        if (index.isValid())
            return Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | defaultFlags;
        else
            return Qt::ItemIsDropEnabled | defaultFlags;
    }
    
    bool StringListModel::insertRows(int position, int rows, const QModelIndex &parent)
    {
        beginInsertRows(QModelIndex(), position, position+rows-1);
    
        for (int row = 0; row < rows; ++row) {
            stringList.insert(position,"");
        }
    
        endInsertRows();
        return true;
    }
    
    bool StringListModel::removeRows(int position, int rows, const QModelIndex &parent)
    {
        beginRemoveRows(QModelIndex(), position, position+rows-1);
    
        for (int row = 0; row < rows; ++row) {
            stringList.removeAt(position);
        }
    
        endRemoveRows();
        return true;
    }
    
    Qt::DropActions StringListModel::supportedDropActions() const
    {
        return Qt::MoveAction | Qt::CopyAction;
    }
    
    

Log in to reply
 

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