Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

how do i pervent QTableWidget cells from having an item dropped on them?



  • Hello everyone, noobie here.

    i am making a program where i am using the QtableWidget's internal drag and drop functionality to drag certain items from one table and drop it into another.
    however, i want certain cells in the table not to accept drops while still being able drop stuff on other cells of the same table.
    does anyone have an idea of how to do that? i have already tried some stuff like this:

    ui->twEmployees->item(1,0)->setFlags(ui->twEmployees->item(1,0)->flags() ^ (Qt::ItemIsDropEnabled));
    

    and it works... partially. the item cannot be dropped on the specific cell. but instead it creates a new row and drops it on that new row. which does not solve the problem at all.
    any kind of help would be appreciated.


  • Lifetime Qt Champion

    Hi and welcome to the forums.
    You have to subclass the TableWidget and help it a bit

    You could do like

    #ifndef MYTABLEWIDGET_H
    #define MYTABLEWIDGET_H
    
    #include <QTableWidget>
    #include <QDragMoveEvent>
    #include <QDebug>
    
    class MyTableWidget : public QTableWidget
    {
        Q_OBJECT
    public:
        explicit MyTableWidget(QWidget *parent = nullptr) : QTableWidget(parent) {}
    protected:
        void dragMoveEvent(QDragMoveEvent *event) override
        {
            // get item at mouse cursor 
            QTableWidgetItem *item = itemAt( event->pos() );
            if (!item ) return;
            if (item->flags() & Qt::ItemIsDropEnabled) { // is item ItemIsDropEnabled
                qDebug() << "ALL OK.";
                event->acceptProposedAction(); // then say yes 
                return; // leave
            }
    
            event->ignore(); // else we just ignore the drop
    
        }
    };
    
    #endif // MYTABLEWIDGET_H
    

    If you use UI forms, then have a look at Creators promotion feature to easily
    use such subclass with Designer.
    https://doc.qt.io/qt-5/designer-using-custom-widgets.html

    Then it works fine. The Blue as ^ (Qt::ItemIsDropEnabled) so it wont accept.

    alt text


  • Lifetime Qt Champion

    Hi and welcome to the forums.
    You have to subclass the TableWidget and help it a bit

    You could do like

    #ifndef MYTABLEWIDGET_H
    #define MYTABLEWIDGET_H
    
    #include <QTableWidget>
    #include <QDragMoveEvent>
    #include <QDebug>
    
    class MyTableWidget : public QTableWidget
    {
        Q_OBJECT
    public:
        explicit MyTableWidget(QWidget *parent = nullptr) : QTableWidget(parent) {}
    protected:
        void dragMoveEvent(QDragMoveEvent *event) override
        {
            // get item at mouse cursor 
            QTableWidgetItem *item = itemAt( event->pos() );
            if (!item ) return;
            if (item->flags() & Qt::ItemIsDropEnabled) { // is item ItemIsDropEnabled
                qDebug() << "ALL OK.";
                event->acceptProposedAction(); // then say yes 
                return; // leave
            }
    
            event->ignore(); // else we just ignore the drop
    
        }
    };
    
    #endif // MYTABLEWIDGET_H
    

    If you use UI forms, then have a look at Creators promotion feature to easily
    use such subclass with Designer.
    https://doc.qt.io/qt-5/designer-using-custom-widgets.html

    Then it works fine. The Blue as ^ (Qt::ItemIsDropEnabled) so it wont accept.

    alt text



  • thank you sooo much! i have been struggling with this for way too long.
    i will try to implement this and see how it works out for me.


  • Lifetime Qt Champion

    @Contrasty
    You are welcome. Should work good for your use case if i did understand it correctly. :)



  • @mrjj Hi, I kind of left this code for a while and now I am coming back to it. i tried it and it works so far.
    I have another question if I may:
    Lets say that for the purposes of my program, I want to override the "dropEvent" function similar to what we did with "DragMoveEvent".
    and in order for me to know how to override it the right way, I need to look at the original implementation of the function "dropEvent". because otherwise the drop functinality won't work as intended.
    do you know if that code is available?

    what I want to do with DropEvent in this example is to print out which column and row the item was dropped on.
    any help would be appreciated!


  • Lifetime Qt Champion

    Hi and welcome back

    do you know if that code is available?

    All code for Qt is available. You can ask the installer to include it or you can use https://code.woboq.org/qt5/
    to browse it online.

    • I need to look at the original implementation of the function "dropEvent". because otherwise the drop functinality won't work as intended.

    Well yes if you want to change how it works you should reimplemnt it.

    However, if you just want to add to it. then often you can just call
    the base class's dropevent and do your code after.
    Then it will do as always and then you can do what you want.



  • alright, Thanks for the advice!


Log in to reply