add buttons in tablewidget's row



  • i want to add buttons in the right side of the row .
    like this. it will appear only when one row is selected .(only one row is selectable) and otherwise buttons not shown.

    0_1534073447873_Untitled image.png
    there is a one "setCornerWidget" but it is only takes a widget,i want buttons.
    how cant in do that??


  • Qt Champions 2017

    Hi
    What is the list ?
    I mean type of widget.



  • @mrjj
    qtablewidget



  • @saber , @mrjj

    I trust/hope the answer is your own QTableWidgetItem (http://doc.qt.io/qt-5/qtablewidgetitem.html), and that is what @VRonin freaks over and tries to get us to never to use, right? :) You can't do this with a QStyledItemDelgate surely...?



  • @JonB
    is there noway to achieve this?


  • Qt Champions 2017

    @saber

    Hi
    have a look at
    http://doc.qt.io/qt-5/qtwidgets-itemviews-stardelegate-example.html

    its bascailly what you want to do,.
    but except of drawing stars , you will draw your custom buttons.

    @JonB
    Its setWidgetItem, he hates due to bad performance. ;)
    But yes you can make this with Delegate.



  • May setItemWidget burn in hell forever!

    #include <QApplication>
    #include <QTableView>
    #include <QStandardItemModel>
    #include <QStyledItemDelegate>
    #include <QHeaderView>
    #include <QPushButton>
    class TailButtonsDelegate : public QStyledItemDelegate{
        Q_OBJECT
        Q_DISABLE_COPY(TailButtonsDelegate)
    public:
        explicit TailButtonsDelegate(QObject* parent = Q_NULLPTR)
            :QStyledItemDelegate(parent)
        {}
        void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE{
            Q_ASSERT(index.isValid());
            QStyleOptionViewItem opt = option;
            initStyleOption(&opt, index);
            const QWidget *widget = option.widget;
            QStyle *style = widget ? widget->style() : QApplication::style();
            style->drawControl(QStyle::CE_ItemViewItem, &opt, painter, widget);
            if(!(option.state & QStyle::State_Selected))
                return;
            QStyleOptionButton editButtonOption;
            editButtonOption.text = QString(QChar(0x270D)); //use emoji for text, optionally you can use icon + iconSize
            editButtonOption.rect = QRect(option.rect.left()+option.rect.width()-(2*option.rect.height()),option.rect.top(),option.rect.height(),option.rect.height());
            editButtonOption.features = QStyleOptionButton::None;
            editButtonOption.direction = option.direction;
            editButtonOption.fontMetrics = option.fontMetrics;
            editButtonOption.palette = option.palette;
            editButtonOption.styleObject = option.styleObject;
            QStyleOptionButton removeButtonOption(editButtonOption);
            removeButtonOption.text = QString(QChar(0x274C)); //use emoji for text, optionally you can use icon + iconSize
            removeButtonOption.rect = QRect(option.rect.left()+option.rect.width()-option.rect.height(),option.rect.top(),option.rect.height(),option.rect.height());
            style->drawControl(QStyle::CE_PushButton, &editButtonOption, painter, widget);
            style->drawControl(QStyle::CE_PushButton, &removeButtonOption, painter, widget);
        }
        QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE{
            const QSize baseSize = QStyledItemDelegate::sizeHint(option,index);
            return QSize(baseSize.width()+(2*baseSize.height()),baseSize.height());
        }
        QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE{
            QWidget* result = new QWidget(parent);
            result->setGeometry(option.rect);
            QWidget* baseEditor = QStyledItemDelegate::createEditor(result,option,index);
            baseEditor->setObjectName("baseEditor");
            baseEditor->setGeometry(0,0,option.rect.width()-(2*option.rect.height()),option.rect.height());
            QPushButton* editButton = new QPushButton(QChar(0x270D),result);
            editButton->setObjectName("editButton");
            editButton->setGeometry(option.rect.width()-(2*option.rect.height()), 0, option.rect.height(),option.rect.height());
            connect(editButton,&QPushButton::clicked,[](){qDebug("Edit");});
            QPushButton* removeButton = new QPushButton(QChar(0x274C),result);
            removeButton->setObjectName("removeButton");
            removeButton->setGeometry(option.rect.width()-option.rect.height(), 0, option.rect.height(),option.rect.height());
            connect(removeButton,&QPushButton::clicked,[](){qDebug("Remove");});
            return result;
        }
        void setEditorData(QWidget *editor, const QModelIndex &index) const Q_DECL_OVERRIDE{
            QWidget* baseEditor = editor->findChild<QWidget*>("baseEditor");
            Q_ASSERT(baseEditor);
            QStyledItemDelegate::setEditorData(baseEditor,index);
        }
        void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const Q_DECL_OVERRIDE{
            QWidget* baseEditor = editor->findChild<QWidget*>("baseEditor");
            Q_ASSERT(baseEditor);
            QStyledItemDelegate::setModelData(baseEditor,model,index);
        }
        void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE{
            Q_UNUSED(index)
            editor->setGeometry(option.rect);
            QWidget* baseEditor = editor->findChild<QWidget*>("baseEditor");
            Q_ASSERT(baseEditor);
            baseEditor->setGeometry(0,0,option.rect.width()-(2*option.rect.height()),option.rect.height());
            QWidget* editButton = editor->findChild<QWidget*>("editButton");
            Q_ASSERT(editButton);
            editButton->setGeometry(option.rect.width()-(2*option.rect.height()), 0, option.rect.height(),option.rect.height());
            QWidget* removeButton = editor->findChild<QWidget*>("removeButton");
            Q_ASSERT(removeButton);
            removeButton->setGeometry(option.rect.width()-option.rect.height(), 0, option.rect.height(),option.rect.height());
            editor->setGeometry(option.rect);
        }
    };
    int main(int argc, char **argv) {
        QApplication app(argc, argv);
        QStandardItemModel baseModel;
        baseModel.insertRows(0, 3);
        baseModel.insertColumns(0, 4);
        for(int i=0;i<3;++i){
            for(int j=0;j<4;++j){
                baseModel.setData(baseModel.index(i,j),QStringLiteral("%1,%2").arg(i).arg(j));
            }
        }
        QTableView view;
        view.setEditTriggers(QTableView::AllEditTriggers);
        view.setModel(&baseModel);
        view.setSelectionBehavior(QTableView::SelectRows);
        view.horizontalHeader()->setStretchLastSection(true);
        view.setItemDelegateForColumn(3,new TailButtonsDelegate(&view));
        view.show();
        return app.exec();
    }
    

  • Qt Champions 2017

    And behold the Beauty
    alt text

    Thank you @VRonin :)



  • @mrjj said in add buttons in tablewidget's row:

    @JonB
    Its setWidgetItem, he hates due to bad performance. ;)
    But yes you can make this with Delegate.

    Damn!
    Isn't there anything you can't do with delegates and which do require setting the widget item? :)


  • Qt Champions 2017

    @JonB
    Not really, but the delegate is kinda involving to make if you have
    multiple widgets and need to reflect various states. You have to go digging around in
    Qt source to see how to mirror the states to draw them with right QStyle calls.
    Also,say you want hover effect on your (drawn widgets) widgets
    then you suddenly have to add extra logic to handle and so on.
    So first time hurts a lot. ;)



  • @mrjj @VRonin
    i need help.
    i added the code in sparate header file and used this in the QTableWidget.
    by this way

    ui->boklist->setItemDelegateForColumn(1, new TailButtonsDelegate(ui->boklist));
    }
    

    here is the header file

    #ifndef TAILBUTTONSDELEGATE_H
    #define TAILBUTTONSDELEGATE_H
    
    #include <QApplication>
    #include <QTableView>
    #include <QStandardItemModel>
    #include <QStyledItemDelegate>
    #include <QHeaderView>
    #include <QPushButton>
    
    class TailButtonsDelegate : public QStyledItemDelegate {
        Q_OBJECT
        Q_DISABLE_COPY(TailButtonsDelegate)
    public:
        explicit TailButtonsDelegate(QObject* parent = Q_NULLPTR)
            :QStyledItemDelegate(parent)
        {}
    
        void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE{
            Q_ASSERT(index.isValid());
            QStyleOptionViewItem opt = option;
            initStyleOption(&opt, index);
            const QWidget *widget = option.widget;
            QStyle *style = widget ? widget->style() : QApplication::style();
            style->drawControl(QStyle::CE_ItemViewItem, &opt, painter, widget);
            if(!(option.state & QStyle::State_Selected))
                return;
            QStyleOptionButton editButtonOption;
            editButtonOption.text = QString(QChar(0x270D)); //use emoji for text, optionally you can use icon + iconSize
            editButtonOption.rect = QRect(option.rect.left()+option.rect.width()-(2*option.rect.height()),option.rect.top(),option.rect.height(),option.rect.height());
            editButtonOption.features = QStyleOptionButton::None;
            editButtonOption.direction = option.direction;
            editButtonOption.fontMetrics = option.fontMetrics;
            editButtonOption.palette = option.palette;
            editButtonOption.styleObject = option.styleObject;
            QStyleOptionButton removeButtonOption(editButtonOption);
            removeButtonOption.text = QString(QChar(0x274C)); //use emoji for text, optionally you can use icon + iconSize
            removeButtonOption.rect = QRect(option.rect.left()+option.rect.width()-option.rect.height(),option.rect.top(),option.rect.height(),option.rect.height());
            style->drawControl(QStyle::CE_PushButton, &editButtonOption, painter, widget);
            style->drawControl(QStyle::CE_PushButton, &removeButtonOption, painter, widget);
        }
        QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE{
            const QSize baseSize = QStyledItemDelegate::sizeHint(option,index);
            return QSize(baseSize.width()+(2*baseSize.height()),baseSize.height());
        }
        QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE{
            QWidget* result = new QWidget(parent);
            result->setGeometry(option.rect);
            QWidget* baseEditor = QStyledItemDelegate::createEditor(result,option,index);
            baseEditor->setObjectName("baseEditor");
            baseEditor->setGeometry(0,0,option.rect.width()-(2*option.rect.height()),option.rect.height());
            QPushButton* editButton = new QPushButton(/*QChar(0x270D),*/ result);
            editButton->setObjectName("editButton");
            editButton->setGeometry(option.rect.width()-(2*option.rect.height()), 0, option.rect.height(),option.rect.height());
            connect(editButton,&QPushButton::clicked,[](){qDebug("Edit");});
            QPushButton* removeButton = new QPushButton(QChar(0x274C),result);
            removeButton->setObjectName("removeButton");
            removeButton->setGeometry(option.rect.width()-option.rect.height(), 0, option.rect.height(),option.rect.height());
            connect(removeButton,&QPushButton::clicked,[](){qDebug("Remove");});
            return result;
        }
        void setEditorData(QWidget *editor, const QModelIndex &index) const Q_DECL_OVERRIDE{
            QWidget* baseEditor = editor->findChild<QWidget*>("baseEditor");
            Q_ASSERT(baseEditor);
            QStyledItemDelegate::setEditorData(baseEditor,index);
        }
        void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const Q_DECL_OVERRIDE{
            QWidget* baseEditor = editor->findChild<QWidget*>("baseEditor");
            Q_ASSERT(baseEditor);
            QStyledItemDelegate::setModelData(baseEditor,model,index);
        }
        void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE{
            Q_UNUSED(index)
            editor->setGeometry(option.rect);
            QWidget* baseEditor = editor->findChild<QWidget*>("baseEditor");
            Q_ASSERT(baseEditor);
            baseEditor->setGeometry(0,0,option.rect.width()-(2*option.rect.height()),option.rect.height());
            QWidget* editButton = editor->findChild<QWidget*>("editButton");
            Q_ASSERT(editButton);
            editButton->setGeometry(option.rect.width()-(2*option.rect.height()), 0, option.rect.height(),option.rect.height());
            QWidget* removeButton = editor->findChild<QWidget*>("removeButton");
            Q_ASSERT(removeButton);
            removeButton->setGeometry(option.rect.width()-option.rect.height(), 0, option.rect.height(),option.rect.height());
            editor->setGeometry(option.rect);
        }
    };
    
    #endif // TAILBUTTONSDELEGATE_H
    
    

    it works but there is some problem.

    1. i want to set the icon from a resource file . how can i do that?
      0_1536403880465_a.png
    2. when i clicked in the row that is going in the edit mode.(only second column)
      0_1536403890495_a2.png

    please help.

    NT:


  • Qt Champions 2017

    hi

    i want to set the icon from a resource file . how can i do that?

    Add it to the res file and
    use syntax
    ":/tractor.png"
    To make sure syntax is correct, RIGHt click file after adding it.
    it show the path to use.

    -when i clicked in the row that is going in the edit mode.(only second column)
    Im not sure what issue is. you never edit a "row" just a cell.



  • @mrjj
    my mistake .
    second cell is going in edit mode.
    here is the ui vriable
    0_1536405278895_s.png

    NT : icon not showing.just showing a part of the text.
    0_1536405506382_e.png

    /editButtonOption.text = QString(":/icons/edit.svg");
    


  • ok. i found the fix to show icon .

     editButtonOption.icon = QIcon(":/icons/edit.svg");
    

    but the icon is not in center.
    0_1536407763919_k.png


Log in to reply
 

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