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

Add widget right aligned to a QTableWidget cell

Scheduled Pinned Locked Moved Solved General and Desktop
46 Posts 4 Posters 6.3k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • H hbatalha

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

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

                                        I'm surprised QMouseEvent *me = static_cast<QMouseEvent*>(event); under case QEvent::HoverMove: case QEvent::HoverEnter: works. if it does is just through some compiler magic. you should cast it to the correct type: QHoverEvent. Also me->pos() works in Qt5 but you need me->position() for Qt6

                                        "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
                                        • H Offline
                                          H Offline
                                          hbatalha
                                          wrote on last edited by
                                          #34

                                          Ok

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

                                          you should cast it to the correct type: QHoverEvent. Also me->pos() works in Qt5 but you need me->position() for Qt6

                                          Will do it.

                                          I have a question: in createEditor, I just deleted the two connect lines and signals are still being emitted. So what is the purpose of creating the MyButton object there?

                                          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