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.4k 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.
  • 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
                • VRoninV VRonin

                  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

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

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

                  Also me->pos() works in Qt5 but you need me->position() for Qt6

                  here QRect::contains takes a QPoint but me->position is a QPointF, I will have to do some casting.

                  Edit: I will just use QPointF::toPoint

                  VRoninV 1 Reply Last reply
                  0
                  • H hbatalha

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

                    Also me->pos() works in Qt5 but you need me->position() for Qt6

                    here QRect::contains takes a QPoint but me->position is a QPointF, I will have to do some casting.

                    Edit: I will just use QPointF::toPoint

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

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

                    here QRect::contains takes a QPoint but me->position is a QPointF, I will have to do some casting.

                    Just call .toPoint() see TableWidgetDelegate::viewportEvent

                    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?

                    Those 2 lines deal with when the user is actually editing. In my original example the delegate was the default editor (usually a lineedit) + a button on the side. The default editor is used to change the contents of the cell. If the user starts editing the cell (doubleclick by default) the editor will pop up and you'll see that clicking on the buttons will not do anything unless you have those 2 connects.
                    In a nutshell we have to handle 2 cases: when the delegate is just painting and when the editor is presented to the user

                    "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:

                      here QRect::contains takes a QPoint but me->position is a QPointF, I will have to do some casting.

                      Just call .toPoint() see TableWidgetDelegate::viewportEvent

                      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?

                      Those 2 lines deal with when the user is actually editing. In my original example the delegate was the default editor (usually a lineedit) + a button on the side. The default editor is used to change the contents of the cell. If the user starts editing the cell (doubleclick by default) the editor will pop up and you'll see that clicking on the buttons will not do anything unless you have those 2 connects.
                      In a nutshell we have to handle 2 cases: when the delegate is just painting and when the editor is presented to the user

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

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

                      Those 2 lines deal with when the user is actually editing. In my original example the delegate was the default editor (usually a lineedit) + a button on the side. The default editor is used to change the contents of the cell. If the user starts editing the cell (doubleclick by default) the editor will pop up and you'll see that clicking on the buttons will not do anything unless you have those 2 connects.
                      In a nutshell we have to handle 2 cases: when the delegate is just painting and when the editor is presented to the user

                      Got it, thanks.

                      Could you please answer me here?

                      1 Reply Last reply
                      0
                      • JonBJ Online
                        JonBJ Online
                        JonB
                        wrote on last edited by
                        #38

                        @VRonin
                        I hope I can hijack this thread now that the OP has had his questions answered?

                        I know the crusade you are on. And I have to respect that the OP may have a lot of items, I don't know. But would you admit that --- without starting a flame-war --- this is one hell of a lot of code to add for a delegate approach if setCellWidget() would have done the job?

                        VRoninV H 2 Replies Last reply
                        0
                        • JonBJ JonB

                          @VRonin
                          I hope I can hijack this thread now that the OP has had his questions answered?

                          I know the crusade you are on. And I have to respect that the OP may have a lot of items, I don't know. But would you admit that --- without starting a flame-war --- this is one hell of a lot of code to add for a delegate approach if setCellWidget() would have done the job?

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

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

                          would you admit that this is one hell of a lot of code to add for a delegate approach

                          I'll even go one step further, and say that for anything more complicated than adding a button, going down reimplementing paint is completely unreasonable. It still doesn't excuse setCellWidget(). You can always use something like this delegate (beware: old code) to have 1 widget taking care of painting every cell instead of having as many widgets as there are cells

                          "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
                          1
                          • JonBJ JonB

                            @VRonin
                            I hope I can hijack this thread now that the OP has had his questions answered?

                            I know the crusade you are on. And I have to respect that the OP may have a lot of items, I don't know. But would you admit that --- without starting a flame-war --- this is one hell of a lot of code to add for a delegate approach if setCellWidget() would have done the job?

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

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

                            Beware that this topic is not about replacing setCellWidget(), the one about setCellWidget() is still open.

                            this is one hell of a lot of code to add for a delegate approach if setCellWidget() would have done the job?

                            setCellWidget() is just awful when you have a chance of using a delegate instead. Since I discovered that I can use a delegate instead, having a setCellWidget has become very unsettling for me.

                            JonBJ 1 Reply Last reply
                            0
                            • H hbatalha

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

                              Beware that this topic is not about replacing setCellWidget(), the one about setCellWidget() is still open.

                              this is one hell of a lot of code to add for a delegate approach if setCellWidget() would have done the job?

                              setCellWidget() is just awful when you have a chance of using a delegate instead. Since I discovered that I can use a delegate instead, having a setCellWidget has become very unsettling for me.

                              JonBJ Online
                              JonBJ Online
                              JonB
                              wrote on last edited by JonB
                              #41

                              @hbatalha
                              Thanks, I did wonder whether it was a different topic, but didn't try to go find it.

                              Your sentiments must warm the cockles of @VRonin's heart ;-) But for those of us who value writing as little code as possble when there is built-in stuff it's not such good news. I do respect why delegates are a better choice, shame there is so much code to write.

                              @VRonin should "publish" a library/class, QStyledItemWidgetDelegate, perhaps based on the code of his referred to in his last post, which does everything one might want from setCellWidget but in a delegate-y way, for everyone to use :) [Also, he should try to keep it down to, say, 10 lines...]

                              VRoninV H 2 Replies Last reply
                              0
                              • JonBJ JonB

                                @hbatalha
                                Thanks, I did wonder whether it was a different topic, but didn't try to go find it.

                                Your sentiments must warm the cockles of @VRonin's heart ;-) But for those of us who value writing as little code as possble when there is built-in stuff it's not such good news. I do respect why delegates are a better choice, shame there is so much code to write.

                                @VRonin should "publish" a library/class, QStyledItemWidgetDelegate, perhaps based on the code of his referred to in his last post, which does everything one might want from setCellWidget but in a delegate-y way, for everyone to use :) [Also, he should try to keep it down to, say, 10 lines...]

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

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

                                Also, he should try to keep it down to, say, 10 lines...

                                ahahah!

                                should "publish" a library/class, QStyledItemWidgetDelegate

                                Already on my TODO list

                                "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
                                • JonBJ JonB

                                  @hbatalha
                                  Thanks, I did wonder whether it was a different topic, but didn't try to go find it.

                                  Your sentiments must warm the cockles of @VRonin's heart ;-) But for those of us who value writing as little code as possble when there is built-in stuff it's not such good news. I do respect why delegates are a better choice, shame there is so much code to write.

                                  @VRonin should "publish" a library/class, QStyledItemWidgetDelegate, perhaps based on the code of his referred to in his last post, which does everything one might want from setCellWidget but in a delegate-y way, for everyone to use :) [Also, he should try to keep it down to, say, 10 lines...]

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

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

                                  @VRonin should "publish" a library/class, QStyledItemWidgetDelegate, perhaps based on the code of his referred to in his last post, which does everything one might want from setCellWidget but in a delegate-y way, for everyone to use :) [Also, he should try to keep it down to, say, 10 lines...]

                                  I was about to say that. Maybe propose the library to the Qt team to add to the official release(if that's how it is done)

                                  1 Reply Last reply
                                  0
                                  • VRoninV VRonin

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

                                    Also, he should try to keep it down to, say, 10 lines...

                                    ahahah!

                                    should "publish" a library/class, QStyledItemWidgetDelegate

                                    Already on my TODO list

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

                                    @VRonin I have a simple question: is it possible to use setItemDelegateForRow and setItemDelegateForRow at the same view(same row)?

                                    VRoninV 1 Reply Last reply
                                    0
                                    • H hbatalha

                                      @VRonin I have a simple question: is it possible to use setItemDelegateForRow and setItemDelegateForRow at the same view(same row)?

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

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

                                      @VRonin I have a simple question: is it possible to use setItemDelegateForRow and setItemDelegateForRow at the same view(same row)?

                                      I assume you mean setItemDelegateForRow and setItemDelegateForColumn.
                                      from https://doc.qt.io/qt-5/qabstractitemview.html#setItemDelegateForRow

                                      Note: If a delegate has been assigned to both a row and a column, the row delegate will take precedence and manage the intersecting cell index.

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

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

                                      H 1 Reply Last reply
                                      2
                                      • VRoninV VRonin

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

                                        @VRonin I have a simple question: is it possible to use setItemDelegateForRow and setItemDelegateForRow at the same view(same row)?

                                        I assume you mean setItemDelegateForRow and setItemDelegateForColumn.
                                        from https://doc.qt.io/qt-5/qabstractitemview.html#setItemDelegateForRow

                                        Note: If a delegate has been assigned to both a row and a column, the row delegate will take precedence and manage the intersecting cell index.

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

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

                                        I assume you mean setItemDelegateForRow and setItemDelegateForColumn.

                                        yes, I copied and pasted n forgot to modify before submitting.

                                        Thanks

                                        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