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 7.2k 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.
  • H hbatalha

    @VRonin I tried it but I am facing some problems, the buttons are only visible when the row is selected and I can't click it.
    Also, how do I get the button and connect it outside the delegate class?

    VRoninV Offline
    VRoninV Offline
    VRonin
    wrote on last edited by
    #9

    @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));

    "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
    • VRoninV VRonin

      @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 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?

      VRoninV 1 Reply Last reply
      0
      • H hbatalha

        @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?

        VRoninV Offline
        VRoninV Offline
        VRonin
        wrote on 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
        3
        • VRoninV VRonin

          @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 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.

          VRoninV 1 Reply Last reply
          0
          • H Offline
            H Offline
            hbatalha
            wrote on last edited by
            #13

            Also the button is still not clickable

            1 Reply Last reply
            0
            • VRoninV Offline
              VRoninV Offline
              VRonin
              wrote on 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
              2
              • H hbatalha

                @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.

                VRoninV Offline
                VRoninV Offline
                VRonin
                wrote on 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
                • VRoninV VRonin

                  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 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 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)

                    VRoninV 1 Reply Last reply
                    0
                    • H Offline
                      H Offline
                      hbatalha
                      wrote on last edited by hbatalha
                      #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
                      • VRoninV Offline
                        VRoninV Offline
                        VRonin
                        wrote on last edited by VRonin
                        #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
                        • VRoninV VRonin

                          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 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.

                          VRoninV 1 Reply Last reply
                          0
                          • H hbatalha

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

                            VRoninV Offline
                            VRoninV Offline
                            VRonin
                            wrote on 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
                            1
                            • H hbatalha

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

                              VRoninV Offline
                              VRoninV Offline
                              VRonin
                              wrote on last edited by VRonin
                              #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
                              0
                              • VRoninV VRonin

                                @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 last edited by
                                #23

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

                                1 Reply Last reply
                                0
                                • VRoninV VRonin

                                  @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 last edited by
                                  #24

                                  @VRonin I figured that out.

                                  1 Reply Last reply
                                  0
                                  • VRoninV VRonin

                                    @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 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
                                    0
                                    • H hbatalha

                                      @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 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
                                      0
                                      • JonBJ JonB

                                        @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 last edited by hbatalha
                                        #27
                                        This post is deleted!
                                        1 Reply Last reply
                                        0
                                        • JonBJ JonB

                                          @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 last edited by hbatalha
                                          #28

                                          @JonB

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

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

                                          VRoninV 1 Reply Last reply
                                          0

                                          • Login

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