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 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 Online
                              JonBJ Online
                              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
                                  • H hbatalha

                                    @JonB

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

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

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

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

                                      H Offline
                                      H Offline
                                      hbatalha
                                      wrote on last edited by
                                      #30

                                      @VRonin yeah it is compiling now but it's not emitting the HoverEnter signal unfortunately:
                                      buttondelegate.h

                                      #ifndef BUTTONDELEGATE_H
                                      #define BUTTONDELEGATE_H
                                      
                                      #include <QApplication>
                                      #include <QStyledItemDelegate>
                                      #include <QPushButton>
                                      #include <QMouseEvent>
                                      #include <QToolTip>
                                      #include <QPainter>
                                      #include <QPalette>
                                      #include <QTableWidget>
                                      
                                      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 ButtonDelegate : public QStyledItemDelegate
                                      {
                                          Q_OBJECT
                                      #if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0)
                                          Q_DISABLE_COPY_MOVE(ButtonDelegate)
                                      #else
                                          Q_DISABLE_COPY(ButtonDelegate)
                                      #endif
                                      public:
                                          explicit ButtonDelegate(QObject* parent)
                                              :QStyledItemDelegate(parent),
                                               tableWidget(qobject_cast<QTableWidget*>(parent))
                                          {
                                              mIsChecked = false;
                                              isDetailsButton = false;
                                              isEnabled = true;
                                              isHidden = false;
                                          }
                                          void update()
                                          {
                                              tableWidget->viewport()->update();
                                          }
                                          void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override
                                          {
                                              Q_ASSERT(index.isValid());
                                      
                                              bool shouldPaint = false;
                                              if(isDetailsButton)
                                              {
                                                  if(index.column() == 0)
                                                      shouldPaint = true;
                                              }
                                              else
                                                  shouldPaint = true;
                                      
                                              if(shouldPaint)
                                              {
                                                  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);
                                      
                                                  if(! isHidden)
                                                  {
                                                      style->drawControl(QStyle::CE_PushButton, &buttonOption, painter, widget);
                                                  }
                                              }
                                              else
                                                  QStyledItemDelegate::paint(painter, option, index);
                                          }
                                          QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const 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 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->setEnabled(false);
                                              myButton->setGeometry(opt.rect.width()-butRect.width(), 0, butRect.width(),butRect.height());
                                              connect(myButton, &MyButton::clicked, this, &ButtonDelegate::clickedHelper);
                                              connect(myButton, &MyButton::mouseIn, this, &ButtonDelegate::mouseInHelper);
                                              return result;
                                          }
                                          void setEditorData(QWidget *editor, const QModelIndex &index) const 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 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 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 text() const
                                          {
                                              return m_buttonText;
                                          }
                                          void setText(const QString &newButtonText)
                                          {
                                              m_buttonText = newButtonText;
                                              update();
                                          }
                                          const QIcon &icon() const
                                          {
                                              return m_buttonIcon;
                                          }
                                          void setIcon(const QIcon &newButtonIcon)
                                          {
                                              m_buttonIcon = newButtonIcon;
                                              update();
                                          }
                                          void setChecked(bool checked)
                                          {
                                              mIsChecked = checked;
                                          }
                                          bool isChecked()
                                          {
                                              return mIsChecked;
                                          }
                                          void setToolTip(QString tooltip)
                                          {
                                              tooltipText = tooltip;
                                          }
                                          void setDetailsButton(bool idb)
                                          {
                                              isDetailsButton = idb;
                                              update();
                                          }
                                          void setEnabled(bool enabled)
                                          {
                                              isEnabled = enabled;
                                              update();
                                          }
                                          void setHidden(bool hide)
                                          {
                                              isHidden = hide;
                                              isEnabled = ! hide;
                                              update();
                                          }
                                          void click()
                                          {
                                              mIsChecked = ! mIsChecked;
                                              clickedHelper();
                                          }
                                      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) 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);
                                                      QMouseEvent *me = static_cast<QMouseEvent*>(event);
                                                      if (me->button() == Qt::LeftButton)
                                                      {
                                                          mIsChecked = ! mIsChecked;
                                                          currentIndex = index;
                                                          clickedHelper();
                                                      }
                                                  }
                                              }
                                      
                                              if (event->type() == QEvent::HoverEnter)
                                              {
                                                  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;
                                      
                                              if(isEnabled)
                                                  buttonOption.state = QStyle::State_Enabled;
                                              else
                                                  buttonOption.state &= ~QStyle::State_Enabled;
                                      
                                              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));
                                      
                                              QRect r = option.rect;
                                              int x = isDetailsButton ? (r.left()+ r.width() - 10) : (r.center().x() - 6);
                                              int y = isDetailsButton ? r.top() : r.top() + 10;
                                              int s = isDetailsButton ? 10 : 1;
                                      
                                              return QRect(x, y, s, s);
                                          }
                                          virtual bool helpEvent(QHelpEvent *event, QAbstractItemView *view, const QStyleOptionViewItem &option, const QModelIndex &index) override
                                          {
                                              if( !event || !view )
                                                  return false;
                                      
                                              if( event->type() == QEvent::ToolTip )
                                              {
                                                  QVariant tooltip = index.data( Qt::DisplayRole );
                                                  if( QApplication::keyboardModifiers() == Qt::AltModifier )
                                                  {
                                                      QToolTip::showText( event->globalPos(), tooltipText);
                                                  }
                                                  else
                                                  {
                                                      QToolTip::showText( event->globalPos(), tooltipText);
                                                  }
                                      
                                                  if( !QStyledItemDelegate::helpEvent( event, view, option, index ) )
                                                      QToolTip::hideText();
                                                  return true;
                                              }
                                      
                                              return QStyledItemDelegate::helpEvent( event, view, option, index );
                                          }
                                      private:
                                          mutable QModelIndex currentIndex;
                                          QPainter* mPainter;
                                          QString m_buttonText;
                                          QIcon m_buttonIcon;
                                          bool mIsChecked;
                                          bool isDetailsButton;
                                          bool isEnabled;
                                          bool isHidden;
                                          QString tooltipText;
                                          QTableWidget* tableWidget;
                                      
                                          void clickedHelper()
                                          {
                                              clicked(currentIndex);
                                          }
                                          void mouseInHelper()
                                          {
                                              mouseIn(currentIndex);
                                          }
                                      };
                                      #endif // BUTTONDELEGATE_H
                                      

                                      tableWidgetDelegate.h

                                      #ifndef TABLEWIDGETDELEGATE_H
                                      #define TABLEWIDGETDELEGATE_H
                                      
                                      #include <QTableWidget>
                                      #include <QEvent>
                                      #include <QModelIndex>
                                      #include <QStyleOptionViewItem>
                                      #include <QHoverEvent>
                                      
                                      class TableWidgetDelegate : public QTableWidget
                                      {
                                          Q_OBJECT
                                      #if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0)
                                          Q_DISABLE_COPY_MOVE(TableWidgetDelegate)
                                      #else
                                          Q_DISABLE_COPY(TableWidgetDelegate)
                                      #endif
                                      public:
                                          explicit TableWidgetDelegate(QWidget *parent = Q_NULLPTR)
                                              : QTableWidget(parent)
                                          {}
                                      protected:
                                          bool viewportEvent(QEvent *event) override
                                          {
                                              switch (event->type())
                                              {
                                              case QEvent::HoverMove:
                                              case QEvent::HoverEnter:
                                              case QEvent::HoverLeave:
                                              case QEvent::MouseMove:
                                              {
                                      #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
                                                  qDebug() << "QTableWidget -- viewport";
                                      
                                                  QModelIndex buddy = model()->buddy(index);
                                                  options.rect = visualRect(buddy);
                                                  options.state |= (buddy == currentIndex() ? QStyle::State_HasFocus : QStyle::State_None);
                                                  QAbstractItemDelegate *delegate = itemDelegateForIndex(index);
                                                  delegate->editorEvent(event, model(), options, buddy);
                                                  break;
                                              }
                                              default:
                                                  break;
                                              }
                                              return QAbstractItemView::viewportEvent(event);
                                          }
                                      };
                                      #endif // TABLEWIDGETDELEGATE_H
                                      
                                      
                                      1 Reply Last reply
                                      0
                                      • VRoninV Offline
                                        VRoninV Offline
                                        VRonin
                                        wrote on last edited by
                                        #31

                                        Tested now:
                                        tablewidgetdelegate.h

                                        #ifndef TABLEWIDGETDELEGATE_H
                                        #define TABLEWIDGETDELEGATE_H
                                        
                                        #include <QTableWidget>
                                        #include <QEvent>
                                        #include <QModelIndex>
                                        #include <QStyleOptionViewItem>
                                        #include <QHoverEvent>
                                        
                                        class TableWidgetDelegate : public QTableWidget
                                        {
                                            Q_OBJECT
                                        #if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0)
                                            Q_DISABLE_COPY_MOVE(TableWidgetDelegate)
                                        #else
                                            Q_DISABLE_COPY(TableWidgetDelegate)
                                        #endif
                                        public:
                                            explicit TableWidgetDelegate(QWidget *parent = Q_NULLPTR)
                                                : QTableWidget(parent)
                                            {
                                                viewport()->setAttribute(Qt::WA_Hover,true);
                                            }
                                        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);
                                                    QAbstractItemDelegate *delegate = itemDelegateForIndex(index);
                                        #else
                                                    QModelIndex index = indexAt(static_cast<QHoverEvent*>(event)->pos());
                                                    QStyleOptionViewItem options = viewOptions();
                                                    QAbstractItemDelegate *delegate = itemDelegate(index);
                                        #endif
                                                    if(delegate){
                                                        QModelIndex buddy = model()->buddy(index);
                                                        options.rect = visualRect(buddy);
                                                        options.state |= (buddy == currentIndex() ? QStyle::State_HasFocus : QStyle::State_None);
                                                        delegate->editorEvent(event, model(), options, buddy);
                                                    }
                                                    break;
                                                }
                                                default:
                                                    break;
                                                }
                                                return QAbstractItemView::viewportEvent(event);
                                            }
                                        };
                                        #endif // TABLEWIDGETDELEGATE_H
                                        

                                        buttondelegate.h

                                        #ifndef BUTTONDELEGATE_H
                                        #define BUTTONDELEGATE_H
                                        
                                        #include <QApplication>
                                        #include <QStyledItemDelegate>
                                        #include <QPushButton>
                                        #include <QMouseEvent>
                                        #include <QToolTip>
                                        #include <QPainter>
                                        #include <QPalette>
                                        #include <QTableWidget>
                                        #include "mybutton.h"
                                        
                                        class ButtonDelegate : public QStyledItemDelegate
                                        {
                                            Q_OBJECT
                                        #if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0)
                                            Q_DISABLE_COPY_MOVE(ButtonDelegate)
                                        #else
                                            Q_DISABLE_COPY(ButtonDelegate)
                                        #endif
                                        public:
                                            explicit ButtonDelegate(QObject* parent)
                                                :QStyledItemDelegate(parent),
                                                 tableWidget(qobject_cast<QTableWidget*>(parent))
                                            {
                                                mIsChecked = false;
                                                isDetailsButton = false;
                                                isEnabled = true;
                                                isHidden = false;
                                            }
                                            void update()
                                            {
                                                tableWidget->viewport()->update();
                                            }
                                            void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE
                                            {
                                                Q_ASSERT(index.isValid());
                                        
                                                bool shouldPaint = false;
                                                if(isDetailsButton)
                                                {
                                                    if(index.column() == 0)
                                                        shouldPaint = true;
                                                }
                                                else
                                                    shouldPaint = true;
                                        
                                                if(shouldPaint)
                                                {
                                                    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);
                                        
                                                    if(! isHidden)
                                                    {
                                                        style->drawControl(QStyle::CE_PushButton, &buttonOption, painter, widget);
                                                    }
                                                }
                                                else
                                                    QStyledItemDelegate::paint(painter, option, index);
                                            }
                                            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->setEnabled(false);
                                                myButton->setGeometry(opt.rect.width()-butRect.width(), 0, butRect.width(),butRect.height());
                                                connect(myButton, &MyButton::clicked, this, &ButtonDelegate::clickedHelper);
                                                connect(myButton, &MyButton::mouseIn, this, &ButtonDelegate::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 text() const
                                            {
                                                return m_buttonText;
                                            }
                                            void setText(const QString &newButtonText)
                                            {
                                                m_buttonText = newButtonText;
                                                update();
                                            }
                                            const QIcon &icon() const
                                            {
                                                return m_buttonIcon;
                                            }
                                            void setIcon(const QIcon &newButtonIcon)
                                            {
                                                m_buttonIcon = newButtonIcon;
                                                update();
                                            }
                                            void setChecked(bool checked)
                                            {
                                                mIsChecked = checked;
                                            }
                                            bool isChecked()
                                            {
                                                return mIsChecked;
                                            }
                                            void setToolTip(QString tooltip)
                                            {
                                                tooltipText = tooltip;
                                            }
                                            void setDetailsButton(bool idb)
                                            {
                                                isDetailsButton = idb;
                                                update();
                                            }
                                            void setEnabled(bool enabled)
                                            {
                                                isEnabled = enabled;
                                                update();
                                            }
                                            void setHidden(bool hide)
                                            {
                                                isHidden = hide;
                                                isEnabled = ! hide;
                                                update();
                                            }
                                            void click()
                                            {
                                                mIsChecked = ! mIsChecked;
                                                clickedHelper();
                                            }
                                        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) override
                                            {
                                                Q_ASSERT(event);
                                                Q_ASSERT(model);
                                                Qt::ItemFlags flags = model->flags(index);
                                                if ((option.state & QStyle::State_Enabled) && (flags & Qt::ItemIsEnabled))
                                                {
                                                    switch (event->type()){
                                                    case QEvent::MouseButtonRelease:{
                                                        QStyleOptionViewItem viewOpt(option);
                                                        initStyleOption(&viewOpt, index);
                                                        QMouseEvent *me = static_cast<QMouseEvent*>(event);
                                                        if (me->button() == Qt::LeftButton)
                                                        {
                                                            mIsChecked = ! mIsChecked;
                                                            currentIndex = index;
                                                            clickedHelper();
                                                        }
                                                    }
                                                        break;
                                                    case QEvent::HoverMove:
                                                    case QEvent::HoverEnter:
                                                    case QEvent::HoverLeave:
                                                        if(index!=currentIndex){
                                                            currentIndex = index;
                                                            if(index.isValid())
                                                                mouseInHelper();
                                                        }
                                                        break;
                                                    default:
                                                        break;
                                                    }
                                                }
                                                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;
                                        
                                                if(isEnabled)
                                                    buttonOption.state = QStyle::State_Enabled;
                                                else
                                                    buttonOption.state &= ~QStyle::State_Enabled;
                                        
                                                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()));
                                        /*
                                                QRect r = option.rect;
                                                int x = isDetailsButton ? (r.left()+ r.width() - 10) : (r.center().x() - 6);
                                                int y = isDetailsButton ? r.top() : r.top() + 10;
                                                int s = isDetailsButton ? 10 : 1;
                                        
                                                return QRect(x, y, s, s);
                                                */
                                            }
                                            virtual bool helpEvent(QHelpEvent *event, QAbstractItemView *view, const QStyleOptionViewItem &option, const QModelIndex &index) override
                                            {
                                                if( !event || !view )
                                                    return false;
                                        
                                                if( event->type() == QEvent::ToolTip )
                                                {
                                                    QVariant tooltip = index.data( Qt::DisplayRole );
                                                    if( QApplication::keyboardModifiers() == Qt::AltModifier )
                                                    {
                                                        QToolTip::showText( event->globalPos(), tooltipText);
                                                    }
                                                    else
                                                    {
                                                        QToolTip::showText( event->globalPos(), tooltipText);
                                                    }
                                        
                                                    if( !QStyledItemDelegate::helpEvent( event, view, option, index ) )
                                                        QToolTip::hideText();
                                                    return true;
                                                }
                                        
                                                return QStyledItemDelegate::helpEvent( event, view, option, index );
                                            }
                                        private:
                                            mutable QModelIndex currentIndex;
                                            QPainter* mPainter;
                                            QString m_buttonText;
                                            QIcon m_buttonIcon;
                                            bool mIsChecked;
                                            bool isDetailsButton;
                                            bool isEnabled;
                                            bool isHidden;
                                            QString tooltipText;
                                            QTableWidget* tableWidget;
                                        
                                            void clickedHelper()
                                            {
                                                clicked(currentIndex);
                                            }
                                            void mouseInHelper()
                                            {
                                                mouseIn(currentIndex);
                                            }
                                        };
                                        #endif // BUTTONDELEGATE_H
                                        

                                        mybutton.h

                                        #ifndef MYBUTTON_H
                                        #define MYBUTTON_H
                                        #include <QPushButton>
                                        class MyButton : public QPushButton
                                        {
                                            Q_OBJECT
                                        #if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0)
                                            Q_DISABLE_COPY_MOVE(MyButton)
                                        #else
                                            Q_DISABLE_COPY(MyButton)
                                        #endif
                                        public:
                                            MyButton(QWidget* parent = 0) : QPushButton(parent) {}
                                            ~MyButton() {};
                                        
                                        signals:
                                            void mouseIn();
                                        
                                        protected:
                                        #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
                                            void enterEvent(QEnterEvent*) Q_DECL_OVERRIDE
                                        #else
                                            void enterEvent(QEvent*) Q_DECL_OVERRIDE
                                        #endif
                                            {
                                                emit mouseIn();
                                            }
                                        };
                                        #endif // MYBUTTON_H
                                        

                                        main.cpp

                                        #include <QApplication>
                                        #include "buttondelegate.h"
                                        #include <QModelIndex>
                                        #include "tablewidgetdelegate.h"
                                        #include <QDebug>
                                        
                                        int main(int argc, char *argv[])
                                        {
                                            QApplication app(argc,argv);
                                            TableWidgetDelegate wid;
                                            wid.setColumnCount(2);
                                            wid.setRowCount(2);
                                            ButtonDelegate *butDelegate = new ButtonDelegate(&wid);
                                            butDelegate->setText("Test");
                                            QPixmap bluePixmap(20,20);
                                            bluePixmap.fill(Qt::blue);
                                            QIcon blueIcon;
                                            blueIcon.addPixmap(bluePixmap);
                                            butDelegate->setIcon(blueIcon);
                                            QObject::connect(butDelegate,&ButtonDelegate::clicked,[](const QModelIndex& index){qDebug() << "Clicked " << index;});
                                            QObject::connect(butDelegate,&ButtonDelegate::mouseIn,[](const QModelIndex& index){qDebug() << "MouseIn " << 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
                                        1
                                        • VRoninV VRonin

                                          Tested now:
                                          tablewidgetdelegate.h

                                          #ifndef TABLEWIDGETDELEGATE_H
                                          #define TABLEWIDGETDELEGATE_H
                                          
                                          #include <QTableWidget>
                                          #include <QEvent>
                                          #include <QModelIndex>
                                          #include <QStyleOptionViewItem>
                                          #include <QHoverEvent>
                                          
                                          class TableWidgetDelegate : public QTableWidget
                                          {
                                              Q_OBJECT
                                          #if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0)
                                              Q_DISABLE_COPY_MOVE(TableWidgetDelegate)
                                          #else
                                              Q_DISABLE_COPY(TableWidgetDelegate)
                                          #endif
                                          public:
                                              explicit TableWidgetDelegate(QWidget *parent = Q_NULLPTR)
                                                  : QTableWidget(parent)
                                              {
                                                  viewport()->setAttribute(Qt::WA_Hover,true);
                                              }
                                          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);
                                                      QAbstractItemDelegate *delegate = itemDelegateForIndex(index);
                                          #else
                                                      QModelIndex index = indexAt(static_cast<QHoverEvent*>(event)->pos());
                                                      QStyleOptionViewItem options = viewOptions();
                                                      QAbstractItemDelegate *delegate = itemDelegate(index);
                                          #endif
                                                      if(delegate){
                                                          QModelIndex buddy = model()->buddy(index);
                                                          options.rect = visualRect(buddy);
                                                          options.state |= (buddy == currentIndex() ? QStyle::State_HasFocus : QStyle::State_None);
                                                          delegate->editorEvent(event, model(), options, buddy);
                                                      }
                                                      break;
                                                  }
                                                  default:
                                                      break;
                                                  }
                                                  return QAbstractItemView::viewportEvent(event);
                                              }
                                          };
                                          #endif // TABLEWIDGETDELEGATE_H
                                          

                                          buttondelegate.h

                                          #ifndef BUTTONDELEGATE_H
                                          #define BUTTONDELEGATE_H
                                          
                                          #include <QApplication>
                                          #include <QStyledItemDelegate>
                                          #include <QPushButton>
                                          #include <QMouseEvent>
                                          #include <QToolTip>
                                          #include <QPainter>
                                          #include <QPalette>
                                          #include <QTableWidget>
                                          #include "mybutton.h"
                                          
                                          class ButtonDelegate : public QStyledItemDelegate
                                          {
                                              Q_OBJECT
                                          #if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0)
                                              Q_DISABLE_COPY_MOVE(ButtonDelegate)
                                          #else
                                              Q_DISABLE_COPY(ButtonDelegate)
                                          #endif
                                          public:
                                              explicit ButtonDelegate(QObject* parent)
                                                  :QStyledItemDelegate(parent),
                                                   tableWidget(qobject_cast<QTableWidget*>(parent))
                                              {
                                                  mIsChecked = false;
                                                  isDetailsButton = false;
                                                  isEnabled = true;
                                                  isHidden = false;
                                              }
                                              void update()
                                              {
                                                  tableWidget->viewport()->update();
                                              }
                                              void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE
                                              {
                                                  Q_ASSERT(index.isValid());
                                          
                                                  bool shouldPaint = false;
                                                  if(isDetailsButton)
                                                  {
                                                      if(index.column() == 0)
                                                          shouldPaint = true;
                                                  }
                                                  else
                                                      shouldPaint = true;
                                          
                                                  if(shouldPaint)
                                                  {
                                                      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);
                                          
                                                      if(! isHidden)
                                                      {
                                                          style->drawControl(QStyle::CE_PushButton, &buttonOption, painter, widget);
                                                      }
                                                  }
                                                  else
                                                      QStyledItemDelegate::paint(painter, option, index);
                                              }
                                              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->setEnabled(false);
                                                  myButton->setGeometry(opt.rect.width()-butRect.width(), 0, butRect.width(),butRect.height());
                                                  connect(myButton, &MyButton::clicked, this, &ButtonDelegate::clickedHelper);
                                                  connect(myButton, &MyButton::mouseIn, this, &ButtonDelegate::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 text() const
                                              {
                                                  return m_buttonText;
                                              }
                                              void setText(const QString &newButtonText)
                                              {
                                                  m_buttonText = newButtonText;
                                                  update();
                                              }
                                              const QIcon &icon() const
                                              {
                                                  return m_buttonIcon;
                                              }
                                              void setIcon(const QIcon &newButtonIcon)
                                              {
                                                  m_buttonIcon = newButtonIcon;
                                                  update();
                                              }
                                              void setChecked(bool checked)
                                              {
                                                  mIsChecked = checked;
                                              }
                                              bool isChecked()
                                              {
                                                  return mIsChecked;
                                              }
                                              void setToolTip(QString tooltip)
                                              {
                                                  tooltipText = tooltip;
                                              }
                                              void setDetailsButton(bool idb)
                                              {
                                                  isDetailsButton = idb;
                                                  update();
                                              }
                                              void setEnabled(bool enabled)
                                              {
                                                  isEnabled = enabled;
                                                  update();
                                              }
                                              void setHidden(bool hide)
                                              {
                                                  isHidden = hide;
                                                  isEnabled = ! hide;
                                                  update();
                                              }
                                              void click()
                                              {
                                                  mIsChecked = ! mIsChecked;
                                                  clickedHelper();
                                              }
                                          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) override
                                              {
                                                  Q_ASSERT(event);
                                                  Q_ASSERT(model);
                                                  Qt::ItemFlags flags = model->flags(index);
                                                  if ((option.state & QStyle::State_Enabled) && (flags & Qt::ItemIsEnabled))
                                                  {
                                                      switch (event->type()){
                                                      case QEvent::MouseButtonRelease:{
                                                          QStyleOptionViewItem viewOpt(option);
                                                          initStyleOption(&viewOpt, index);
                                                          QMouseEvent *me = static_cast<QMouseEvent*>(event);
                                                          if (me->button() == Qt::LeftButton)
                                                          {
                                                              mIsChecked = ! mIsChecked;
                                                              currentIndex = index;
                                                              clickedHelper();
                                                          }
                                                      }
                                                          break;
                                                      case QEvent::HoverMove:
                                                      case QEvent::HoverEnter:
                                                      case QEvent::HoverLeave:
                                                          if(index!=currentIndex){
                                                              currentIndex = index;
                                                              if(index.isValid())
                                                                  mouseInHelper();
                                                          }
                                                          break;
                                                      default:
                                                          break;
                                                      }
                                                  }
                                                  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;
                                          
                                                  if(isEnabled)
                                                      buttonOption.state = QStyle::State_Enabled;
                                                  else
                                                      buttonOption.state &= ~QStyle::State_Enabled;
                                          
                                                  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()));
                                          /*
                                                  QRect r = option.rect;
                                                  int x = isDetailsButton ? (r.left()+ r.width() - 10) : (r.center().x() - 6);
                                                  int y = isDetailsButton ? r.top() : r.top() + 10;
                                                  int s = isDetailsButton ? 10 : 1;
                                          
                                                  return QRect(x, y, s, s);
                                                  */
                                              }
                                              virtual bool helpEvent(QHelpEvent *event, QAbstractItemView *view, const QStyleOptionViewItem &option, const QModelIndex &index) override
                                              {
                                                  if( !event || !view )
                                                      return false;
                                          
                                                  if( event->type() == QEvent::ToolTip )
                                                  {
                                                      QVariant tooltip = index.data( Qt::DisplayRole );
                                                      if( QApplication::keyboardModifiers() == Qt::AltModifier )
                                                      {
                                                          QToolTip::showText( event->globalPos(), tooltipText);
                                                      }
                                                      else
                                                      {
                                                          QToolTip::showText( event->globalPos(), tooltipText);
                                                      }
                                          
                                                      if( !QStyledItemDelegate::helpEvent( event, view, option, index ) )
                                                          QToolTip::hideText();
                                                      return true;
                                                  }
                                          
                                                  return QStyledItemDelegate::helpEvent( event, view, option, index );
                                              }
                                          private:
                                              mutable QModelIndex currentIndex;
                                              QPainter* mPainter;
                                              QString m_buttonText;
                                              QIcon m_buttonIcon;
                                              bool mIsChecked;
                                              bool isDetailsButton;
                                              bool isEnabled;
                                              bool isHidden;
                                              QString tooltipText;
                                              QTableWidget* tableWidget;
                                          
                                              void clickedHelper()
                                              {
                                                  clicked(currentIndex);
                                              }
                                              void mouseInHelper()
                                              {
                                                  mouseIn(currentIndex);
                                              }
                                          };
                                          #endif // BUTTONDELEGATE_H
                                          

                                          mybutton.h

                                          #ifndef MYBUTTON_H
                                          #define MYBUTTON_H
                                          #include <QPushButton>
                                          class MyButton : public QPushButton
                                          {
                                              Q_OBJECT
                                          #if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0)
                                              Q_DISABLE_COPY_MOVE(MyButton)
                                          #else
                                              Q_DISABLE_COPY(MyButton)
                                          #endif
                                          public:
                                              MyButton(QWidget* parent = 0) : QPushButton(parent) {}
                                              ~MyButton() {};
                                          
                                          signals:
                                              void mouseIn();
                                          
                                          protected:
                                          #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
                                              void enterEvent(QEnterEvent*) Q_DECL_OVERRIDE
                                          #else
                                              void enterEvent(QEvent*) Q_DECL_OVERRIDE
                                          #endif
                                              {
                                                  emit mouseIn();
                                              }
                                          };
                                          #endif // MYBUTTON_H
                                          

                                          main.cpp

                                          #include <QApplication>
                                          #include "buttondelegate.h"
                                          #include <QModelIndex>
                                          #include "tablewidgetdelegate.h"
                                          #include <QDebug>
                                          
                                          int main(int argc, char *argv[])
                                          {
                                              QApplication app(argc,argv);
                                              TableWidgetDelegate wid;
                                              wid.setColumnCount(2);
                                              wid.setRowCount(2);
                                              ButtonDelegate *butDelegate = new ButtonDelegate(&wid);
                                              butDelegate->setText("Test");
                                              QPixmap bluePixmap(20,20);
                                              bluePixmap.fill(Qt::blue);
                                              QIcon blueIcon;
                                              blueIcon.addPixmap(bluePixmap);
                                              butDelegate->setIcon(blueIcon);
                                              QObject::connect(butDelegate,&ButtonDelegate::clicked,[](const QModelIndex& index){qDebug() << "Clicked " << index;});
                                              QObject::connect(butDelegate,&ButtonDelegate::mouseIn,[](const QModelIndex& index){qDebug() << "MouseIn " << index;});
                                              wid.setItemDelegate(butDelegate);
                                              wid.show();
                                              return app.exec();
                                          }
                                          
                                          H Offline
                                          H Offline
                                          hbatalha
                                          wrote on last edited by hbatalha
                                          #32

                                          @VRonin Working perfectly, can't thank you enough. I made some changes in the buttondelegate.h's editorEvent function to better suit my needs:

                                              bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) override
                                              {
                                                  Q_ASSERT(event);
                                                  Q_ASSERT(model);
                                                  Qt::ItemFlags flags = model->flags(index);
                                                  if ((option.state & QStyle::State_Enabled) && (flags & Qt::ItemIsEnabled))
                                                  {
                                                      switch (event->type())
                                                      {
                                                      case QEvent::MouseButtonRelease:
                                                      {
                                                          QStyleOptionViewItem viewOpt(option);
                                                          initStyleOption(&viewOpt, index);
                                                          QMouseEvent *me = static_cast<QMouseEvent*>(event);
                                                          if (me->button() == Qt::LeftButton)
                                                          {
                                                              mIsChecked = ! mIsChecked;
                                                              currentIndex = index;
                                                              clickedHelper();
                                                          }
                                                      }
                                                      break;
                                                      case QEvent::HoverMove:
                                                      case QEvent::HoverEnter:
                                                      {
                                                          QStyleOptionViewItem viewOpt(option);
                                                          const QRect butRect = buttonRect(viewOpt);
                                                          QMouseEvent *me = static_cast<QMouseEvent*>(event);
                                          
                                                          currentIndex = index;
                                                          if(index.isValid() && butRect.contains(me->pos()))
                                                              mouseInHelper();
                                                      }
                                                      break;
                                                      default:
                                                          break;
                                                      }
                                                  }
                                                  return QStyledItemDelegate::editorEvent(event,model,option,index);
                                              }
                                          
                                          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