Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Add widget right aligned to a QTableWidget cell
Forum Updated to NodeBB v4.3 + New Features

Add widget right aligned to a QTableWidget cell

Scheduled Pinned Locked Moved Solved General and Desktop
46 Posts 4 Posters 6.5k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • V VRonin
    19 Oct 2021, 19:32

    @hbatalha said in Add widget right aligned to a QTableWidget cell:

    the buttons are only visible when the row is selected

    Just remove:

    if(!(option.state & QStyle::State_Selected))
                return;
    

    and I can't click it.

    You need to adjust the edit trigger of the view: https://doc.qt.io/qt-5/qabstractitemview.html#editTriggers-prop

    how do I get the button and connect it outside the delegate class?

    create a signal in the delegate, something like Q_SIGNAL void clicked(const QModelIndex &index); and replace connect(editButton,&QPushButton::clicked,[](){qDebug("Edit");}); with connect(editButton,&QPushButton::clicked,this,std::bind(&TailButtonsDelegate::clicked,this,index));

    H Offline
    H Offline
    hbatalha
    wrote on 19 Oct 2021, 20:19 last edited by
    #10

    @VRonin I getting this error when trying to create a signal in the delegate:

    C:\msys64\mingw64\include\c++\10.3.0\functional:460: error: no type named 'type' in 'class std::result_of<void (TailButtonsDelegate::*&(const TailButtonsDelegate*&, QModelIndex&))(const QModelIndex&)>'
    C:/msys64/mingw64/include/c++/10.3.0/functional:494:9:   required from 'struct QtPrivate::FunctorReturnType<std::_Bind<void (TailButtonsDelegate::*(const TailButtonsDelegate*, QModelIndex))(const QModelIndex&)>, QtPrivate::List<> >'
    C:/Qt/6.2.0/mingw81_64/include/QtCore/qobject.h:306:158:   required from 'static typename std::enable_if<(QtPrivate::FunctionPointer<Func2>::ArgumentCount == -1), QMetaObject::Connection>::type QObject::connect(const typename QtPrivate::FunctionPointer<Func>::Object*, Func1, const QObject*, Func2, Qt::ConnectionType) [with Func1 = void (QAbstractButton::*)(bool); Func2 = std::_Bind<void (TailButtonsDelegate::*(const TailButtonsDelegate*, QModelIndex))(const QModelIndex&)>; typename std::enable_if<(QtPrivate::FunctionPointer<Func2>::ArgumentCount == -1), QMetaObject::Connection>::type = QMetaObject::Connection; typename QtPrivate::FunctionPointer<Func>::Object = QAbstractButton]'
    release\../delegate.h:55:108:   required from here
    C:/msys64/mingw64/include/c++/10.3.0/functional:460:8: error: no type named 'type' in 'class std::result_of<void (TailButtonsDelegate::*&(const TailButtonsDelegate*&, QModelIndex&))(const QModelIndex&)>'
      460 |  using _Res_type_impl
          |        ^~~~~~~~~~~~~~
    

    Also, I have a question: what's so wrong with setIndexWidget, creating a delegate seems so complex so I am asking what are the advantages of it over setIndexWidget?

    V 1 Reply Last reply 19 Oct 2021, 20:22
    0
    • H hbatalha
      19 Oct 2021, 20:19

      @VRonin I getting this error when trying to create a signal in the delegate:

      C:\msys64\mingw64\include\c++\10.3.0\functional:460: error: no type named 'type' in 'class std::result_of<void (TailButtonsDelegate::*&(const TailButtonsDelegate*&, QModelIndex&))(const QModelIndex&)>'
      C:/msys64/mingw64/include/c++/10.3.0/functional:494:9:   required from 'struct QtPrivate::FunctorReturnType<std::_Bind<void (TailButtonsDelegate::*(const TailButtonsDelegate*, QModelIndex))(const QModelIndex&)>, QtPrivate::List<> >'
      C:/Qt/6.2.0/mingw81_64/include/QtCore/qobject.h:306:158:   required from 'static typename std::enable_if<(QtPrivate::FunctionPointer<Func2>::ArgumentCount == -1), QMetaObject::Connection>::type QObject::connect(const typename QtPrivate::FunctionPointer<Func>::Object*, Func1, const QObject*, Func2, Qt::ConnectionType) [with Func1 = void (QAbstractButton::*)(bool); Func2 = std::_Bind<void (TailButtonsDelegate::*(const TailButtonsDelegate*, QModelIndex))(const QModelIndex&)>; typename std::enable_if<(QtPrivate::FunctionPointer<Func2>::ArgumentCount == -1), QMetaObject::Connection>::type = QMetaObject::Connection; typename QtPrivate::FunctionPointer<Func>::Object = QAbstractButton]'
      release\../delegate.h:55:108:   required from here
      C:/msys64/mingw64/include/c++/10.3.0/functional:460:8: error: no type named 'type' in 'class std::result_of<void (TailButtonsDelegate::*&(const TailButtonsDelegate*&, QModelIndex&))(const QModelIndex&)>'
        460 |  using _Res_type_impl
            |        ^~~~~~~~~~~~~~
      

      Also, I have a question: what's so wrong with setIndexWidget, creating a delegate seems so complex so I am asking what are the advantages of it over setIndexWidget?

      V Offline
      V Offline
      VRonin
      wrote on 19 Oct 2021, 20:22 last edited by
      #11

      @hbatalha said in Add widget right aligned to a QTableWidget cell:

      I getting this error when trying to create a signal in the delegate:

      Can you show your code?

      what's so wrong with setIndexWidget, creating a delegate seems so complex so I am asking what are the advantages of it over setIndexWidget?

      Try creating 1000 rows and scroll through them. You'll realise very quick what the problem is. setIndexWidget is a HOG on resources

      "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
      ~Napoleon Bonaparte

      On a crusade to banish setIndexWidget() from the holy land of Qt

      H 1 Reply Last reply 25 Oct 2021, 17:10
      3
      • V VRonin
        19 Oct 2021, 20:22

        @hbatalha said in Add widget right aligned to a QTableWidget cell:

        I getting this error when trying to create a signal in the delegate:

        Can you show your code?

        what's so wrong with setIndexWidget, creating a delegate seems so complex so I am asking what are the advantages of it over setIndexWidget?

        Try creating 1000 rows and scroll through them. You'll realise very quick what the problem is. setIndexWidget is a HOG on resources

        H Offline
        H Offline
        hbatalha
        wrote on 25 Oct 2021, 17:10 last edited by
        #12

        @VRonin Sorry for the really late reply, I have been working offline due to internet cut.

        @VRonin said in Add widget right aligned to a QTableWidget cell:

        Try creating 1000 rows and scroll through them. You'll realise very quick what the problem is. setIndexWidget is a HOG on resources

        I Will try that, I am curious to see it

        Can you show your code?

        #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);
        
        
                QStyleOptionButton editButtonOption;
                editButtonOption.text = QString(); //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(); //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(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(result);
                removeButton->setObjectName("removeButton");
                removeButton->setGeometry(option.rect.width()-option.rect.height(), 0, option.rect.height(),option.rect.height());
                connect(editButton,&QPushButton::clicked,this,std::bind(&TailButtonsDelegate::clicked,this,index));
                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);
            }
        
            Q_SIGNAL void clicked(const QModelIndex &index);
        };
        
        #endif // TAILBUTTONSDELEGATE_H
        

        Also I want to set the button size to setFixedSize(10, 10); but I have been having problems controlling the size. For the time being I have being using this version using setIndexWidget

            QWidget* widget = new QWidget;
        
            QPushButton* detailsButton = new QPushButton;
            detailsButton->setFixedSize(10, 10);
        
            QHBoxLayout* hLayout = new QHBoxLayout;
            hLayout->addStretch();
            hLayout->addWidget(detailsButton);
            widget->setLayout(hLayout);
        
            ui->tableWidget->setIndexWidget(ui->tableWidget->model()->index(row, 0), widget);
        

        So above is what I am trying to achieve using delegate.

        V 1 Reply Last reply 29 Oct 2021, 14:09
        0
        • H Offline
          H Offline
          hbatalha
          wrote on 25 Oct 2021, 18:12 last edited by
          #13

          Also the button is still not clickable

          1 Reply Last reply
          0
          • V Offline
            V Offline
            VRonin
            wrote on 29 Oct 2021, 13:51 last edited by
            #14

            Sorry for the delay in getting back to you, I've been offline for a few days. Try this:

            #ifndef TAILBUTTONDELEGATE_H
            #define TAILBUTTONDELEGATE_H
            
            #include <QApplication>
            #include <QStyledItemDelegate>
            #include <QPushButton>
            #include <QMouseEvent>
            class TailButtonDelegate : public QStyledItemDelegate
            {
                Q_OBJECT
            #if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0)
                Q_DISABLE_COPY_MOVE(TailButtonDelegate)
            #else
                Q_DISABLE_COPY(TailButtonDelegate)
            #endif
            public:
                explicit TailButtonDelegate(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);
                    QStyleOptionButton buttonOption = buttonOptions(opt);
                    style->drawControl(QStyle::CE_PushButton, &buttonOption, painter, widget);
                }
                QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE
                {
                    QStyleOptionViewItem opt = option;
                    initStyleOption(&opt, index);
                    const QSize baseSize = QStyledItemDelegate::sizeHint(option,index);
                    const QRect butRect = buttonRect(opt);
                    return QSize(baseSize.width()+butRect.width(),qMax(butRect.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);
                    result->setFocusProxy(baseEditor);
                    QStyleOptionViewItem opt = option;
                    initStyleOption(&opt, index);
                    const QRect butRect = buttonRect(opt);
                    baseEditor->setObjectName("baseEditor");
                    baseEditor->setGeometry(0,0,opt.rect.width()-butRect.width(),opt.rect.height());
                    QPushButton* extraButton = new QPushButton(result);
                    extraButton->setObjectName("extraButton");
                    extraButton->setText(m_buttonText);
                    extraButton->setIcon(m_buttonIcon);
                    extraButton->setGeometry(opt.rect.width()-butRect.width(), 0, butRect.width(),butRect.height());
                    connect(extraButton,&QPushButton::clicked,this,&TailButtonDelegate::clickedHelper);
                    return result;
                }
                void setEditorData(QWidget *editor, const QModelIndex &index) const Q_DECL_OVERRIDE
                {
                    currentIndex = index;
                    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
                {
                    QStyleOptionViewItem opt = option;
                    initStyleOption(&opt, index);
                    editor->setGeometry(opt.rect);
                    const QRect butRect = buttonRect(opt);
                    QWidget* baseEditor = editor->findChild<QWidget*>("baseEditor");
                    Q_ASSERT(baseEditor);
                    baseEditor->setGeometry(0,0,opt.rect.width()-butRect.width(),opt.rect.height());
                    QWidget* extraButton = editor->findChild<QWidget*>("extraButton");
                    Q_ASSERT(extraButton);
                    extraButton->setGeometry(opt.rect.width()-butRect.width(), 0, butRect.width(),butRect.height());
                }
                const QString buttonText() const
                {
                    return m_buttonText;
                }
                void setButtonText(const QString &newButtonText)
                {
                    m_buttonText = newButtonText;
                }
                const QIcon &buttonIcon() const
                {
                    return m_buttonIcon;
                }
                void setButtonIcon(const QIcon &newButtonIcon)
                {
                    m_buttonIcon = newButtonIcon;
                }
            Q_SIGNALS:
                void buttonClicked(const QModelIndex &index);
            protected:
                bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) Q_DECL_OVERRIDE{
                    Q_ASSERT(event);
                    Q_ASSERT(model);
                    Qt::ItemFlags flags = model->flags(index);
                    if ((option.state & QStyle::State_Enabled) && (flags & Qt::ItemIsEnabled)){
                        if (event->type() == QEvent::MouseButtonRelease) {
                            QStyleOptionViewItem viewOpt(option);
                            initStyleOption(&viewOpt, index);
                            const QRect butRect = buttonRect(viewOpt);
                            QMouseEvent *me = static_cast<QMouseEvent*>(event);
                            if (me->button() == Qt::LeftButton && butRect.contains(me->pos())){
                                currentIndex = index;
                                clickedHelper();
                            }
                        }
                    }
                    return QStyledItemDelegate::editorEvent(event,model,option,index);
                }
                virtual QStyleOptionButton buttonOptions(const QStyleOptionViewItem &option, bool skipRct=false) const{
                    const QWidget *widget = option.widget;
                    QStyle *style = widget ? widget->style() : QApplication::style();
                    int buttonIconSize = style->pixelMetric(QStyle::PM_ButtonIconSize, 0, widget);
                    QStyleOptionButton buttonOption;
                    buttonOption.text = m_buttonText;
                    buttonOption.icon = m_buttonIcon;
                    buttonOption.iconSize = (QSize(buttonIconSize,buttonIconSize));
                    buttonOption.rect = skipRct ? QRect() : buttonRect(option);
                    buttonOption.features = QStyleOptionButton::None;
                    buttonOption.direction = option.direction;
                    buttonOption.fontMetrics = option.fontMetrics;
                    buttonOption.palette = option.palette;
                    buttonOption.styleObject = option.styleObject;
                    buttonOption.state = option.state;
                    return buttonOption;
                }
                virtual QRect buttonRect(const QStyleOptionViewItem &option) const{
                    const QStyleOptionButton buttonOption = buttonOptions(option,true);
                    const QWidget *widget = option.widget;
                    QStyle *style = widget ? widget->style() : QApplication::style();
                    QSize buttonSize = style->sizeFromContents(QStyle::CT_PushButton, &buttonOption, QSize(), widget);
                    buttonSize.setWidth(qMin(buttonSize.width(),option.rect.width()/2));
                    return QRect(option.rect.left()+option.rect.width()-buttonSize.width(),option.rect.top(),buttonSize.width(),qMax(buttonSize.height(),option.rect.height()));
                }
            private:
                mutable QModelIndex currentIndex;
                QString m_buttonText;
                QIcon m_buttonIcon;
                void clickedHelper(){buttonClicked(currentIndex);}
            };
            
            #endif // TAILBUTTONDELEGATE_H
            

            Then you can use it with something like:

            int main(int argc, char *argv[])
            {
                QApplication app(argc,argv);
                QTableWidget wid(2,2);
                TailButtonDelegate *butDelegate = new TailButtonDelegate(&wid);
                butDelegate->setButtonText("Test");
                QPixmap bluePixmap(20,20);
                bluePixmap.fill(Qt::blue);
                QIcon blueIcon;
                blueIcon.addPixmap(bluePixmap);
                butDelegate->setButtonIcon(blueIcon);
                QObject::connect(butDelegate,&TailButtonDelegate::buttonClicked,[](const QModelIndex& index){qDebug() << "Clicked " << index;});
                wid.setItemDelegate(butDelegate);
                wid.show();
                return app.exec();
            
            }
            

            "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
            ~Napoleon Bonaparte

            On a crusade to banish setIndexWidget() from the holy land of Qt

            H 1 Reply Last reply 29 Oct 2021, 17:52
            2
            • H hbatalha
              25 Oct 2021, 17:10

              @VRonin Sorry for the really late reply, I have been working offline due to internet cut.

              @VRonin said in Add widget right aligned to a QTableWidget cell:

              Try creating 1000 rows and scroll through them. You'll realise very quick what the problem is. setIndexWidget is a HOG on resources

              I Will try that, I am curious to see it

              Can you show your code?

              #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);
              
              
                      QStyleOptionButton editButtonOption;
                      editButtonOption.text = QString(); //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(); //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(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(result);
                      removeButton->setObjectName("removeButton");
                      removeButton->setGeometry(option.rect.width()-option.rect.height(), 0, option.rect.height(),option.rect.height());
                      connect(editButton,&QPushButton::clicked,this,std::bind(&TailButtonsDelegate::clicked,this,index));
                      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);
                  }
              
                  Q_SIGNAL void clicked(const QModelIndex &index);
              };
              
              #endif // TAILBUTTONSDELEGATE_H
              

              Also I want to set the button size to setFixedSize(10, 10); but I have been having problems controlling the size. For the time being I have being using this version using setIndexWidget

                  QWidget* widget = new QWidget;
              
                  QPushButton* detailsButton = new QPushButton;
                  detailsButton->setFixedSize(10, 10);
              
                  QHBoxLayout* hLayout = new QHBoxLayout;
                  hLayout->addStretch();
                  hLayout->addWidget(detailsButton);
                  widget->setLayout(hLayout);
              
                  ui->tableWidget->setIndexWidget(ui->tableWidget->model()->index(row, 0), widget);
              

              So above is what I am trying to achieve using delegate.

              V Offline
              V Offline
              VRonin
              wrote on 29 Oct 2021, 14:09 last edited by
              #15

              @hbatalha said in Add widget right aligned to a QTableWidget cell:

              Also I want to set the button size to setFixedSize(10, 10);

              To do this in the example above you'd need to tweak the buttonRect() method to something like

              virtual QRect buttonRect(const QStyleOptionViewItem &option) const{
                  return QRect(option.rect.left()+option.rect.width()-10,option.rect.top(),10,10);
              }
              

              "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
              ~Napoleon Bonaparte

              On a crusade to banish setIndexWidget() from the holy land of Qt

              1 Reply Last reply
              0
              • V VRonin
                29 Oct 2021, 13:51

                Sorry for the delay in getting back to you, I've been offline for a few days. Try this:

                #ifndef TAILBUTTONDELEGATE_H
                #define TAILBUTTONDELEGATE_H
                
                #include <QApplication>
                #include <QStyledItemDelegate>
                #include <QPushButton>
                #include <QMouseEvent>
                class TailButtonDelegate : public QStyledItemDelegate
                {
                    Q_OBJECT
                #if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0)
                    Q_DISABLE_COPY_MOVE(TailButtonDelegate)
                #else
                    Q_DISABLE_COPY(TailButtonDelegate)
                #endif
                public:
                    explicit TailButtonDelegate(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);
                        QStyleOptionButton buttonOption = buttonOptions(opt);
                        style->drawControl(QStyle::CE_PushButton, &buttonOption, painter, widget);
                    }
                    QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE
                    {
                        QStyleOptionViewItem opt = option;
                        initStyleOption(&opt, index);
                        const QSize baseSize = QStyledItemDelegate::sizeHint(option,index);
                        const QRect butRect = buttonRect(opt);
                        return QSize(baseSize.width()+butRect.width(),qMax(butRect.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);
                        result->setFocusProxy(baseEditor);
                        QStyleOptionViewItem opt = option;
                        initStyleOption(&opt, index);
                        const QRect butRect = buttonRect(opt);
                        baseEditor->setObjectName("baseEditor");
                        baseEditor->setGeometry(0,0,opt.rect.width()-butRect.width(),opt.rect.height());
                        QPushButton* extraButton = new QPushButton(result);
                        extraButton->setObjectName("extraButton");
                        extraButton->setText(m_buttonText);
                        extraButton->setIcon(m_buttonIcon);
                        extraButton->setGeometry(opt.rect.width()-butRect.width(), 0, butRect.width(),butRect.height());
                        connect(extraButton,&QPushButton::clicked,this,&TailButtonDelegate::clickedHelper);
                        return result;
                    }
                    void setEditorData(QWidget *editor, const QModelIndex &index) const Q_DECL_OVERRIDE
                    {
                        currentIndex = index;
                        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
                    {
                        QStyleOptionViewItem opt = option;
                        initStyleOption(&opt, index);
                        editor->setGeometry(opt.rect);
                        const QRect butRect = buttonRect(opt);
                        QWidget* baseEditor = editor->findChild<QWidget*>("baseEditor");
                        Q_ASSERT(baseEditor);
                        baseEditor->setGeometry(0,0,opt.rect.width()-butRect.width(),opt.rect.height());
                        QWidget* extraButton = editor->findChild<QWidget*>("extraButton");
                        Q_ASSERT(extraButton);
                        extraButton->setGeometry(opt.rect.width()-butRect.width(), 0, butRect.width(),butRect.height());
                    }
                    const QString buttonText() const
                    {
                        return m_buttonText;
                    }
                    void setButtonText(const QString &newButtonText)
                    {
                        m_buttonText = newButtonText;
                    }
                    const QIcon &buttonIcon() const
                    {
                        return m_buttonIcon;
                    }
                    void setButtonIcon(const QIcon &newButtonIcon)
                    {
                        m_buttonIcon = newButtonIcon;
                    }
                Q_SIGNALS:
                    void buttonClicked(const QModelIndex &index);
                protected:
                    bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) Q_DECL_OVERRIDE{
                        Q_ASSERT(event);
                        Q_ASSERT(model);
                        Qt::ItemFlags flags = model->flags(index);
                        if ((option.state & QStyle::State_Enabled) && (flags & Qt::ItemIsEnabled)){
                            if (event->type() == QEvent::MouseButtonRelease) {
                                QStyleOptionViewItem viewOpt(option);
                                initStyleOption(&viewOpt, index);
                                const QRect butRect = buttonRect(viewOpt);
                                QMouseEvent *me = static_cast<QMouseEvent*>(event);
                                if (me->button() == Qt::LeftButton && butRect.contains(me->pos())){
                                    currentIndex = index;
                                    clickedHelper();
                                }
                            }
                        }
                        return QStyledItemDelegate::editorEvent(event,model,option,index);
                    }
                    virtual QStyleOptionButton buttonOptions(const QStyleOptionViewItem &option, bool skipRct=false) const{
                        const QWidget *widget = option.widget;
                        QStyle *style = widget ? widget->style() : QApplication::style();
                        int buttonIconSize = style->pixelMetric(QStyle::PM_ButtonIconSize, 0, widget);
                        QStyleOptionButton buttonOption;
                        buttonOption.text = m_buttonText;
                        buttonOption.icon = m_buttonIcon;
                        buttonOption.iconSize = (QSize(buttonIconSize,buttonIconSize));
                        buttonOption.rect = skipRct ? QRect() : buttonRect(option);
                        buttonOption.features = QStyleOptionButton::None;
                        buttonOption.direction = option.direction;
                        buttonOption.fontMetrics = option.fontMetrics;
                        buttonOption.palette = option.palette;
                        buttonOption.styleObject = option.styleObject;
                        buttonOption.state = option.state;
                        return buttonOption;
                    }
                    virtual QRect buttonRect(const QStyleOptionViewItem &option) const{
                        const QStyleOptionButton buttonOption = buttonOptions(option,true);
                        const QWidget *widget = option.widget;
                        QStyle *style = widget ? widget->style() : QApplication::style();
                        QSize buttonSize = style->sizeFromContents(QStyle::CT_PushButton, &buttonOption, QSize(), widget);
                        buttonSize.setWidth(qMin(buttonSize.width(),option.rect.width()/2));
                        return QRect(option.rect.left()+option.rect.width()-buttonSize.width(),option.rect.top(),buttonSize.width(),qMax(buttonSize.height(),option.rect.height()));
                    }
                private:
                    mutable QModelIndex currentIndex;
                    QString m_buttonText;
                    QIcon m_buttonIcon;
                    void clickedHelper(){buttonClicked(currentIndex);}
                };
                
                #endif // TAILBUTTONDELEGATE_H
                

                Then you can use it with something like:

                int main(int argc, char *argv[])
                {
                    QApplication app(argc,argv);
                    QTableWidget wid(2,2);
                    TailButtonDelegate *butDelegate = new TailButtonDelegate(&wid);
                    butDelegate->setButtonText("Test");
                    QPixmap bluePixmap(20,20);
                    bluePixmap.fill(Qt::blue);
                    QIcon blueIcon;
                    blueIcon.addPixmap(bluePixmap);
                    butDelegate->setButtonIcon(blueIcon);
                    QObject::connect(butDelegate,&TailButtonDelegate::buttonClicked,[](const QModelIndex& index){qDebug() << "Clicked " << index;});
                    wid.setItemDelegate(butDelegate);
                    wid.show();
                    return app.exec();
                
                }
                
                H Offline
                H Offline
                hbatalha
                wrote on 29 Oct 2021, 17:52 last edited by hbatalha
                #16

                @VRonin It's working greatly, thanks, but I want to access some QPushButton methods, namely setCheckable, isChecked, setChecked, setToolTip. Also I want to emit signal when the mouse enters the button, I tried doind that but it's not working.
                This is what I have tried to get a signal when mouse enters the button

                #ifndef TAILBUTTONSDELEGATE_H
                #define TAILBUTTONSDELEGATE_H
                
                #include <QApplication>
                #include <QStyledItemDelegate>
                #include <QPushButton>
                #include <QMouseEvent>
                
                class MyButton : public QPushButton
                {
                    Q_OBJECT
                
                public:
                    MyButton(QWidget* parent = 0) : QPushButton(parent) {}
                    ~MyButton() {};
                
                signals:
                    void mouseIn();
                
                protected:
                    void enterEvent(QEnterEvent*) override
                    {
                        emit mouseIn();
                    }
                };
                
                class TailButtonDelegate : public QStyledItemDelegate
                {
                    Q_OBJECT
                #if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0)
                    Q_DISABLE_COPY_MOVE(TailButtonDelegate)
                #else
                    Q_DISABLE_COPY(TailButtonDelegate)
                #endif
                public:
                    explicit TailButtonDelegate(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);
                        QStyleOptionButton buttonOption = buttonOptions(opt);
                        style->drawControl(QStyle::CE_PushButton, &buttonOption, painter, widget);
                    }
                    QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE
                    {
                        QStyleOptionViewItem opt = option;
                        initStyleOption(&opt, index);
                        const QSize baseSize = QStyledItemDelegate::sizeHint(option,index);
                        const QRect butRect = buttonRect(opt);
                        return QSize(baseSize.width()+butRect.width(),qMax(butRect.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);
                        result->setFocusProxy(baseEditor);
                        QStyleOptionViewItem opt = option;
                        initStyleOption(&opt, index);
                        const QRect butRect = buttonRect(opt);
                        baseEditor->setObjectName("baseEditor");
                        baseEditor->setGeometry(0,0,opt.rect.width()-butRect.width(),opt.rect.height());
                        MyButton* myButton = new MyButton(result);
                        myButton->setObjectName("myButton");
                        myButton->setText(m_buttonText);
                        myButton->setIcon(m_buttonIcon);
                        myButton->setGeometry(opt.rect.width()-butRect.width(), 0, butRect.width(),butRect.height());
                        connect(myButton, &MyButton::clicked, this, &TailButtonDelegate::clickedHelper);
                        connect(myButton, &MyButton::mouseIn, this, &TailButtonDelegate::mouseInHelper);
                        return result;
                    }
                    void setEditorData(QWidget *editor, const QModelIndex &index) const Q_DECL_OVERRIDE
                    {
                        currentIndex = index;
                        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
                    {
                        QStyleOptionViewItem opt = option;
                        initStyleOption(&opt, index);
                        editor->setGeometry(opt.rect);
                        const QRect butRect = buttonRect(opt);
                        QWidget* baseEditor = editor->findChild<QWidget*>("baseEditor");
                        Q_ASSERT(baseEditor);
                        baseEditor->setGeometry(0,0,opt.rect.width()-butRect.width(),opt.rect.height());
                        QWidget* myButton = editor->findChild<QWidget*>("myButton");
                        Q_ASSERT(myButton);
                        myButton->setGeometry(opt.rect.width()-butRect.width(), 0, butRect.width(),butRect.height());
                    }
                    const QString buttonText() const
                    {
                        return m_buttonText;
                    }
                    void setButtonText(const QString &newButtonText)
                    {
                        m_buttonText = newButtonText;
                    }
                    const QIcon &buttonIcon() const
                    {
                        return m_buttonIcon;
                    }
                    void setButtonIcon(const QIcon &newButtonIcon)
                    {
                        m_buttonIcon = newButtonIcon;
                    }
                Q_SIGNALS:
                    void clicked(const QModelIndex &index);
                    void mouseIn(const QModelIndex &index);
                protected:
                    bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) Q_DECL_OVERRIDE
                    {
                        Q_ASSERT(event);
                        Q_ASSERT(model);
                        Qt::ItemFlags flags = model->flags(index);
                        if ((option.state & QStyle::State_Enabled) && (flags & Qt::ItemIsEnabled))
                        {
                            if (event->type() == QEvent::MouseButtonRelease)
                            {
                                QStyleOptionViewItem viewOpt(option);
                                initStyleOption(&viewOpt, index);
                                const QRect butRect = buttonRect(viewOpt);
                                QMouseEvent *me = static_cast<QMouseEvent*>(event);
                                if (me->button() == Qt::LeftButton && butRect.contains(me->pos()))
                                {
                                    currentIndex = index;
                                    clickedHelper();
                                }
                            }
                            if (event->type() == QEvent::Enter)
                            {
                                {
                                    currentIndex = index;
                                    mouseInHelper();
                                }
                            }
                        }
                        return QStyledItemDelegate::editorEvent(event,model,option,index);
                    }
                    virtual QStyleOptionButton buttonOptions(const QStyleOptionViewItem &option, bool skipRct=false) const
                    {
                        const QWidget *widget = option.widget;
                        QStyle *style = widget ? widget->style() : QApplication::style();
                        int buttonIconSize = style->pixelMetric(QStyle::PM_ButtonIconSize, 0, widget);
                        QStyleOptionButton buttonOption;
                        buttonOption.text = m_buttonText;
                        buttonOption.icon = m_buttonIcon;
                        buttonOption.iconSize = (QSize(buttonIconSize,buttonIconSize));
                        buttonOption.rect = skipRct ? QRect() : buttonRect(option);
                        buttonOption.features = QStyleOptionButton::None;
                        buttonOption.direction = option.direction;
                        buttonOption.fontMetrics = option.fontMetrics;
                        buttonOption.palette = option.palette;
                        buttonOption.styleObject = option.styleObject;
                        buttonOption.state = option.state;
                        return buttonOption;
                    }
                    virtual QRect buttonRect(const QStyleOptionViewItem &option) const
                    {
                        const QStyleOptionButton buttonOption = buttonOptions(option,true);
                        const QWidget *widget = option.widget;
                        QStyle *style = widget ? widget->style() : QApplication::style();
                        QSize buttonSize = style->sizeFromContents(QStyle::CT_PushButton, &buttonOption, QSize(), widget);
                        buttonSize.setWidth(qMin(buttonSize.width(),option.rect.width()/2));
                        return QRect(option.rect.left()+option.rect.width()-10,option.rect.top(),10,10);
                    }
                private:
                    mutable QModelIndex currentIndex;
                    QString m_buttonText;
                    QIcon m_buttonIcon;
                    void clickedHelper()
                    {
                        clicked(currentIndex);
                    }
                    void mouseInHelper()
                    {
                        mouseIn(currentIndex);
                    }
                };
                
                #endif // TAILBUTTONSDELEGATE_H
                

                but it is not working.

                1 Reply Last reply
                0
                • H Offline
                  H Offline
                  hbatalha
                  wrote on 29 Oct 2021, 19:14 last edited by hbatalha
                  #17

                  Also I would like have the button in the middle of the cell(top - bottom), this when set the size to (10,10)

                  V 1 Reply Last reply 2 Nov 2021, 11:35
                  0
                  • H Offline
                    H Offline
                    hbatalha
                    wrote on 1 Nov 2021, 13:04 last edited by hbatalha 11 Jan 2021, 13:05
                    #18

                    Update: I was able to solve all the problems mentioned above except for the mouse over event signal.
                    So now I just want a way to signal when the mouse goes over the delegate, I have tried many "solutions" none has worked yet for me.

                    1 Reply Last reply
                    0
                    • V Offline
                      V Offline
                      VRonin
                      wrote on 1 Nov 2021, 14:02 last edited by VRonin 11 Feb 2021, 10:36
                      #19

                      Sorry for the choppy response. Your delegate code is doing the right thing (just minor note it should handle QEvent::HoverEnter instead of QEvent::Enter), the problem is that hover events are not passed by the view to the delegate. You need to subclass your view and reimplement viewportEvent to something like: (warning: untested code)

                      class HoverDelegateView : public QTableView{
                          Q_OBJECT
                      #if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0)
                          Q_DISABLE_COPY_MOVE(HoverDelegateView)
                      #else
                          Q_DISABLE_COPY(HoverDelegateView)
                      #endif
                      public:
                          explicit HoverDelegateView(QWidget *parent = Q_NULLPTR)
                              : QTableView(parent)
                          {}
                      protected:
                          bool viewportEvent(QEvent *event) Q_DECL_OVERRIDE
                          {
                              switch (event->type()){
                              case QEvent::HoverMove:
                              case QEvent::HoverEnter:
                              case QEvent::HoverLeave:{
                      #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
                                  QModelIndex index = indexAt(static_cast<QHoverEvent*>(event)->position().toPoint());
                                  QStyleOptionViewItem options;
                                  initViewItemOption(&options);
                      #else
                                  QModelIndex index = indexAt(static_cast<QHoverEvent*>(event)->pos());
                                  QStyleOptionViewItem options = viewOptions();
                      #endif
                                  QModelIndex buddy = model()->buddy(index);
                                  options.rect = visualRect(buddy);
                                  options.state |= (buddy == currentIndex() ? QStyle::State_HasFocus : QStyle::State_None);
                                  QAbstractItemDelegate *delegate = itemDelegate(index);
                                  delegate->editorEvent(event, model(), options, buddy);
                                  break;
                              }
                              default:
                                  break;
                              }
                              return QAbstractItemView::viewportEvent(event);
                          }
                      };
                      

                      "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                      ~Napoleon Bonaparte

                      On a crusade to banish setIndexWidget() from the holy land of Qt

                      H 1 Reply Last reply 1 Nov 2021, 22:47
                      1
                      • V VRonin
                        1 Nov 2021, 14:02

                        Sorry for the choppy response. Your delegate code is doing the right thing (just minor note it should handle QEvent::HoverEnter instead of QEvent::Enter), the problem is that hover events are not passed by the view to the delegate. You need to subclass your view and reimplement viewportEvent to something like: (warning: untested code)

                        class HoverDelegateView : public QTableView{
                            Q_OBJECT
                        #if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0)
                            Q_DISABLE_COPY_MOVE(HoverDelegateView)
                        #else
                            Q_DISABLE_COPY(HoverDelegateView)
                        #endif
                        public:
                            explicit HoverDelegateView(QWidget *parent = Q_NULLPTR)
                                : QTableView(parent)
                            {}
                        protected:
                            bool viewportEvent(QEvent *event) Q_DECL_OVERRIDE
                            {
                                switch (event->type()){
                                case QEvent::HoverMove:
                                case QEvent::HoverEnter:
                                case QEvent::HoverLeave:{
                        #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
                                    QModelIndex index = indexAt(static_cast<QHoverEvent*>(event)->position().toPoint());
                                    QStyleOptionViewItem options;
                                    initViewItemOption(&options);
                        #else
                                    QModelIndex index = indexAt(static_cast<QHoverEvent*>(event)->pos());
                                    QStyleOptionViewItem options = viewOptions();
                        #endif
                                    QModelIndex buddy = model()->buddy(index);
                                    options.rect = visualRect(buddy);
                                    options.state |= (buddy == currentIndex() ? QStyle::State_HasFocus : QStyle::State_None);
                                    QAbstractItemDelegate *delegate = itemDelegate(index);
                                    delegate->editorEvent(event, model(), options, buddy);
                                    break;
                                }
                                default:
                                    break;
                                }
                                return QAbstractItemView::viewportEvent(event);
                            }
                        };
                        
                        H Offline
                        H Offline
                        hbatalha
                        wrote on 1 Nov 2021, 22:47 last edited by
                        #20

                        @VRonin I understood what you said, the concept behind it. In the code there are two undeclared identifiers: viewOptions and index though.

                        V 1 Reply Last reply 2 Nov 2021, 10:29
                        0
                        • H hbatalha
                          1 Nov 2021, 22:47

                          @VRonin I understood what you said, the concept behind it. In the code there are two undeclared identifiers: viewOptions and index though.

                          V Offline
                          V Offline
                          VRonin
                          wrote on 2 Nov 2021, 10:29 last edited by
                          #21

                          @hbatalha said in Add widget right aligned to a QTableWidget cell:

                          @VRonin I understood what you said, the concept behind it. In the code there are two undeclared identifiers: viewOptions and index though.

                          Thanks, fixed those

                          "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                          ~Napoleon Bonaparte

                          On a crusade to banish setIndexWidget() from the holy land of Qt

                          H 2 Replies Last reply 2 Nov 2021, 12:27
                          1
                          • H hbatalha
                            29 Oct 2021, 19:14

                            Also I would like have the button in the middle of the cell(top - bottom), this when set the size to (10,10)

                            V Offline
                            V Offline
                            VRonin
                            wrote on 2 Nov 2021, 11:35 last edited by VRonin 11 Feb 2021, 12:48
                            #22

                            @hbatalha said in Add widget right aligned to a QTableWidget cell:

                            Also I would like have the button in the middle of the cell(top - bottom), this when set the size to (10,10)

                            Again this is managed by buttonRect, the 3rd argument to be precise:

                            virtual QRect buttonRect(const QStyleOptionViewItem &option) const{
                                return QRect(option.rect.left()+option.rect.width()-10,option.rect.top()+qMax(0,(option.rect.height()-10)/2),10,10);
                            }
                            

                            "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                            ~Napoleon Bonaparte

                            On a crusade to banish setIndexWidget() from the holy land of Qt

                            H 1 Reply Last reply 2 Nov 2021, 12:29
                            0
                            • V VRonin
                              2 Nov 2021, 10:29

                              @hbatalha said in Add widget right aligned to a QTableWidget cell:

                              @VRonin I understood what you said, the concept behind it. In the code there are two undeclared identifiers: viewOptions and index though.

                              Thanks, fixed those

                              H Offline
                              H Offline
                              hbatalha
                              wrote on 2 Nov 2021, 12:27 last edited by
                              #23

                              @VRonin I will test the code and get back to you.

                              1 Reply Last reply
                              0
                              • V VRonin
                                2 Nov 2021, 11:35

                                @hbatalha said in Add widget right aligned to a QTableWidget cell:

                                Also I would like have the button in the middle of the cell(top - bottom), this when set the size to (10,10)

                                Again this is managed by buttonRect, the 3rd argument to be precise:

                                virtual QRect buttonRect(const QStyleOptionViewItem &option) const{
                                    return QRect(option.rect.left()+option.rect.width()-10,option.rect.top()+qMax(0,(option.rect.height()-10)/2),10,10);
                                }
                                
                                H Offline
                                H Offline
                                hbatalha
                                wrote on 2 Nov 2021, 12:29 last edited by
                                #24

                                @VRonin I figured that out.

                                1 Reply Last reply
                                0
                                • V VRonin
                                  2 Nov 2021, 10:29

                                  @hbatalha said in Add widget right aligned to a QTableWidget cell:

                                  @VRonin I understood what you said, the concept behind it. In the code there are two undeclared identifiers: viewOptions and index though.

                                  Thanks, fixed those

                                  H Offline
                                  H Offline
                                  hbatalha
                                  wrote on 2 Nov 2021, 19:24 last edited by
                                  #25

                                  @VRonin I thought you edited the reply to fix the undeclared identifiers errors in the code but they are still there.

                                  JonBJ 1 Reply Last reply 2 Nov 2021, 19:44
                                  0
                                  • H hbatalha
                                    2 Nov 2021, 19:24

                                    @VRonin I thought you edited the reply to fix the undeclared identifiers errors in the code but they are still there.

                                    JonBJ Offline
                                    JonBJ Offline
                                    JonB
                                    wrote on 2 Nov 2021, 19:44 last edited by
                                    #26

                                    @hbatalha
                                    You wrote earlier

                                    In the code there are two undeclared identifiers: viewOptions and index though.

                                    Looking at those in @VRonin's code now they should be fine? If you have a compilation error show it.

                                    H 2 Replies Last reply 2 Nov 2021, 21:02
                                    0
                                    • JonBJ JonB
                                      2 Nov 2021, 19:44

                                      @hbatalha
                                      You wrote earlier

                                      In the code there are two undeclared identifiers: viewOptions and index though.

                                      Looking at those in @VRonin's code now they should be fine? If you have a compilation error show it.

                                      H Offline
                                      H Offline
                                      hbatalha
                                      wrote on 2 Nov 2021, 21:02 last edited by hbatalha 11 Feb 2021, 21:29
                                      #27
                                      This post is deleted!
                                      1 Reply Last reply
                                      0
                                      • JonBJ JonB
                                        2 Nov 2021, 19:44

                                        @hbatalha
                                        You wrote earlier

                                        In the code there are two undeclared identifiers: viewOptions and index though.

                                        Looking at those in @VRonin's code now they should be fine? If you have a compilation error show it.

                                        H Offline
                                        H Offline
                                        hbatalha
                                        wrote on 2 Nov 2021, 21:30 last edited by hbatalha 11 Feb 2021, 21:32
                                        #28

                                        @JonB

                                        10b05a11-55e7-482b-89bc-47cfbe8a827f-image.png

                                        When I include it and tried to use it theses errors we thrown.

                                        V 1 Reply Last reply 2 Nov 2021, 22:55
                                        0
                                        • H hbatalha
                                          2 Nov 2021, 21:30

                                          @JonB

                                          10b05a11-55e7-482b-89bc-47cfbe8a827f-image.png

                                          When I include it and tried to use it theses errors we thrown.

                                          V Offline
                                          V Offline
                                          VRonin
                                          wrote on 2 Nov 2021, 22:55 last edited by
                                          #29

                                          @hbatalha I edited my post above to take care of these issues

                                          "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                                          ~Napoleon Bonaparte

                                          On a crusade to banish setIndexWidget() from the holy land of Qt

                                          H 1 Reply Last reply 3 Nov 2021, 09:04
                                          0

                                          19/46

                                          1 Nov 2021, 14:02

                                          • Login

                                          • Login or register to search.
                                          19 out of 46
                                          • First post
                                            19/46
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • Users
                                          • Groups
                                          • Search
                                          • Get Qt Extensions
                                          • Unsolved