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

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

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

    Can you show your code?

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

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

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

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

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

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

    I Will try that, I am curious to see it

    Can you show your code?

    #ifndef TAILBUTTONSDELEGATE_H
    #define TAILBUTTONSDELEGATE_H
    
    #include <QApplication>
    #include <QTableView>
    #include <QStandardItemModel>
    #include <QStyledItemDelegate>
    #include <QHeaderView>
    #include <QPushButton>
    
    class TailButtonsDelegate : public QStyledItemDelegate
    {
        Q_OBJECT
        Q_DISABLE_COPY(TailButtonsDelegate)
    
    public:
        explicit TailButtonsDelegate(QObject* parent = Q_NULLPTR)
            :QStyledItemDelegate(parent)
        {}
        void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE
        {
            Q_ASSERT(index.isValid());
            QStyleOptionViewItem opt = option;
            initStyleOption(&opt, index);
            const QWidget *widget = option.widget;
            QStyle *style = widget ? widget->style() : QApplication::style();
            style->drawControl(QStyle::CE_ItemViewItem, &opt, painter, widget);
    
    
            QStyleOptionButton editButtonOption;
            editButtonOption.text = QString(); //use emoji for text, optionally you can use icon + iconSize
            editButtonOption.rect = QRect(option.rect.left()+option.rect.width()-(2*option.rect.height()),option.rect.top(),option.rect.height(),option.rect.height());
            editButtonOption.features = QStyleOptionButton::None;
            editButtonOption.direction = option.direction;
            editButtonOption.fontMetrics = option.fontMetrics;
            editButtonOption.palette = option.palette;
            editButtonOption.styleObject = option.styleObject;
            QStyleOptionButton removeButtonOption(editButtonOption);
            removeButtonOption.text = QString(); //use emoji for text, optionally you can use icon + iconSize
            removeButtonOption.rect = QRect(option.rect.left()+option.rect.width()-option.rect.height(),option.rect.top(),option.rect.height(),option.rect.height());
            style->drawControl(QStyle::CE_PushButton, &editButtonOption, painter, widget);
            style->drawControl(QStyle::CE_PushButton, &removeButtonOption, painter, widget);
        }
        QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE
        {
            const QSize baseSize = QStyledItemDelegate::sizeHint(option,index);
            return QSize(baseSize.width()+(2*baseSize.height()),baseSize.height());
        }
        QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE
        {
            QWidget* result = new QWidget(parent);
            result->setGeometry(option.rect);
            QWidget* baseEditor = QStyledItemDelegate::createEditor(result,option,index);
            baseEditor->setObjectName("baseEditor");
            baseEditor->setGeometry(0,0,option.rect.width()-(2*option.rect.height()),option.rect.height());
            QPushButton* editButton = new QPushButton(result);
            editButton->setObjectName("editButton");
            editButton->setGeometry(option.rect.width()-(2*option.rect.height()), 0, option.rect.height(),option.rect.height());
            connect(editButton,&QPushButton::clicked,[]()
            {
                qDebug("Edit");
            });
            QPushButton* removeButton = new QPushButton(result);
            removeButton->setObjectName("removeButton");
            removeButton->setGeometry(option.rect.width()-option.rect.height(), 0, option.rect.height(),option.rect.height());
            connect(editButton,&QPushButton::clicked,this,std::bind(&TailButtonsDelegate::clicked,this,index));
            return result;
        }
        void setEditorData(QWidget *editor, const QModelIndex &index) const Q_DECL_OVERRIDE
        {
            QWidget* baseEditor = editor->findChild<QWidget*>("baseEditor");
            Q_ASSERT(baseEditor);
            QStyledItemDelegate::setEditorData(baseEditor,index);
        }
        void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const Q_DECL_OVERRIDE
        {
            QWidget* baseEditor = editor->findChild<QWidget*>("baseEditor");
            Q_ASSERT(baseEditor);
            QStyledItemDelegate::setModelData(baseEditor,model,index);
        }
        void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE
        {
            Q_UNUSED(index)
            editor->setGeometry(option.rect);
            QWidget* baseEditor = editor->findChild<QWidget*>("baseEditor");
            Q_ASSERT(baseEditor);
            baseEditor->setGeometry(0,0,option.rect.width()-(2*option.rect.height()),option.rect.height());
            QWidget* editButton = editor->findChild<QWidget*>("editButton");
            Q_ASSERT(editButton);
            editButton->setGeometry(option.rect.width()-(2*option.rect.height()), 0, option.rect.height(),option.rect.height());
            QWidget* removeButton = editor->findChild<QWidget*>("removeButton");
            Q_ASSERT(removeButton);
            removeButton->setGeometry(option.rect.width()-option.rect.height(), 0, option.rect.height(),option.rect.height());
            editor->setGeometry(option.rect);
        }
    
        Q_SIGNAL void clicked(const QModelIndex &index);
    };
    
    #endif // TAILBUTTONSDELEGATE_H
    

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

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

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

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

      Also the button is still not clickable

      1 Reply Last reply
      0
      • VRoninV Offline
        VRoninV Offline
        VRonin
        wrote on last edited by
        #14

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

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

        Then you can use it with something like:

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

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

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

        H 1 Reply Last reply
        2
        • H hbatalha

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

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

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

          I Will try that, I am curious to see it

          Can you show your code?

          #ifndef TAILBUTTONSDELEGATE_H
          #define TAILBUTTONSDELEGATE_H
          
          #include <QApplication>
          #include <QTableView>
          #include <QStandardItemModel>
          #include <QStyledItemDelegate>
          #include <QHeaderView>
          #include <QPushButton>
          
          class TailButtonsDelegate : public QStyledItemDelegate
          {
              Q_OBJECT
              Q_DISABLE_COPY(TailButtonsDelegate)
          
          public:
              explicit TailButtonsDelegate(QObject* parent = Q_NULLPTR)
                  :QStyledItemDelegate(parent)
              {}
              void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE
              {
                  Q_ASSERT(index.isValid());
                  QStyleOptionViewItem opt = option;
                  initStyleOption(&opt, index);
                  const QWidget *widget = option.widget;
                  QStyle *style = widget ? widget->style() : QApplication::style();
                  style->drawControl(QStyle::CE_ItemViewItem, &opt, painter, widget);
          
          
                  QStyleOptionButton editButtonOption;
                  editButtonOption.text = QString(); //use emoji for text, optionally you can use icon + iconSize
                  editButtonOption.rect = QRect(option.rect.left()+option.rect.width()-(2*option.rect.height()),option.rect.top(),option.rect.height(),option.rect.height());
                  editButtonOption.features = QStyleOptionButton::None;
                  editButtonOption.direction = option.direction;
                  editButtonOption.fontMetrics = option.fontMetrics;
                  editButtonOption.palette = option.palette;
                  editButtonOption.styleObject = option.styleObject;
                  QStyleOptionButton removeButtonOption(editButtonOption);
                  removeButtonOption.text = QString(); //use emoji for text, optionally you can use icon + iconSize
                  removeButtonOption.rect = QRect(option.rect.left()+option.rect.width()-option.rect.height(),option.rect.top(),option.rect.height(),option.rect.height());
                  style->drawControl(QStyle::CE_PushButton, &editButtonOption, painter, widget);
                  style->drawControl(QStyle::CE_PushButton, &removeButtonOption, painter, widget);
              }
              QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE
              {
                  const QSize baseSize = QStyledItemDelegate::sizeHint(option,index);
                  return QSize(baseSize.width()+(2*baseSize.height()),baseSize.height());
              }
              QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE
              {
                  QWidget* result = new QWidget(parent);
                  result->setGeometry(option.rect);
                  QWidget* baseEditor = QStyledItemDelegate::createEditor(result,option,index);
                  baseEditor->setObjectName("baseEditor");
                  baseEditor->setGeometry(0,0,option.rect.width()-(2*option.rect.height()),option.rect.height());
                  QPushButton* editButton = new QPushButton(result);
                  editButton->setObjectName("editButton");
                  editButton->setGeometry(option.rect.width()-(2*option.rect.height()), 0, option.rect.height(),option.rect.height());
                  connect(editButton,&QPushButton::clicked,[]()
                  {
                      qDebug("Edit");
                  });
                  QPushButton* removeButton = new QPushButton(result);
                  removeButton->setObjectName("removeButton");
                  removeButton->setGeometry(option.rect.width()-option.rect.height(), 0, option.rect.height(),option.rect.height());
                  connect(editButton,&QPushButton::clicked,this,std::bind(&TailButtonsDelegate::clicked,this,index));
                  return result;
              }
              void setEditorData(QWidget *editor, const QModelIndex &index) const Q_DECL_OVERRIDE
              {
                  QWidget* baseEditor = editor->findChild<QWidget*>("baseEditor");
                  Q_ASSERT(baseEditor);
                  QStyledItemDelegate::setEditorData(baseEditor,index);
              }
              void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const Q_DECL_OVERRIDE
              {
                  QWidget* baseEditor = editor->findChild<QWidget*>("baseEditor");
                  Q_ASSERT(baseEditor);
                  QStyledItemDelegate::setModelData(baseEditor,model,index);
              }
              void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE
              {
                  Q_UNUSED(index)
                  editor->setGeometry(option.rect);
                  QWidget* baseEditor = editor->findChild<QWidget*>("baseEditor");
                  Q_ASSERT(baseEditor);
                  baseEditor->setGeometry(0,0,option.rect.width()-(2*option.rect.height()),option.rect.height());
                  QWidget* editButton = editor->findChild<QWidget*>("editButton");
                  Q_ASSERT(editButton);
                  editButton->setGeometry(option.rect.width()-(2*option.rect.height()), 0, option.rect.height(),option.rect.height());
                  QWidget* removeButton = editor->findChild<QWidget*>("removeButton");
                  Q_ASSERT(removeButton);
                  removeButton->setGeometry(option.rect.width()-option.rect.height(), 0, option.rect.height(),option.rect.height());
                  editor->setGeometry(option.rect);
              }
          
              Q_SIGNAL void clicked(const QModelIndex &index);
          };
          
          #endif // TAILBUTTONSDELEGATE_H
          

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

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

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

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

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

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

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

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

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

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

          1 Reply Last reply
          0
          • VRoninV VRonin

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

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

            Then you can use it with something like:

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

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

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

            but it is not working.

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

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

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

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

                1 Reply Last reply
                0
                • VRoninV Offline
                  VRoninV Offline
                  VRonin
                  wrote on last edited by VRonin
                  #19

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

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

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

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

                  H 1 Reply Last reply
                  1
                  • VRoninV VRonin

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

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

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

                    VRoninV 1 Reply Last reply
                    0
                    • H hbatalha

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

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

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

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

                      Thanks, fixed those

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

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

                      H 2 Replies Last reply
                      1
                      • H hbatalha

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

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

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

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

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

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

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

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

                        H 1 Reply Last reply
                        0
                        • VRoninV VRonin

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

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

                          Thanks, fixed those

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

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

                          1 Reply Last reply
                          0
                          • VRoninV VRonin

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

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

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

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

                            @VRonin I figured that out.

                            1 Reply Last reply
                            0
                            • VRoninV VRonin

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

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

                              Thanks, fixed those

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

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

                              JonBJ 1 Reply Last reply
                              0
                              • H hbatalha

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

                                JonBJ Offline
                                JonBJ Offline
                                JonB
                                wrote on last edited by
                                #26

                                @hbatalha
                                You wrote earlier

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

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

                                H 2 Replies Last reply
                                0
                                • JonBJ JonB

                                  @hbatalha
                                  You wrote earlier

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

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

                                  H Offline
                                  H Offline
                                  hbatalha
                                  wrote on last edited by hbatalha
                                  #27
                                  This post is deleted!
                                  1 Reply Last reply
                                  0
                                  • JonBJ JonB

                                    @hbatalha
                                    You wrote earlier

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

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

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

                                    @JonB

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

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

                                    VRoninV 1 Reply Last reply
                                    0
                                    • 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

                                          • Login

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