Add widget right aligned to a QTableWidget cell
-
Sorry for the choppy response. Your delegate code is doing the right thing (just minor note it should handle
QEvent::HoverEnter
instead ofQEvent::Enter
), the problem is that hover events are not passed by the view to the delegate. You need to subclass your view and reimplementviewportEvent
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); } };
-
@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); }
-
@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
-
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(); }
-
@VRonin Working perfectly, can't thank you enough. I made some changes in the
buttondelegate.h
'seditorEvent
function to better suit my needs:bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) override { Q_ASSERT(event); Q_ASSERT(model); Qt::ItemFlags flags = model->flags(index); if ((option.state & QStyle::State_Enabled) && (flags & Qt::ItemIsEnabled)) { switch (event->type()) { case QEvent::MouseButtonRelease: { QStyleOptionViewItem viewOpt(option); initStyleOption(&viewOpt, index); QMouseEvent *me = static_cast<QMouseEvent*>(event); if (me->button() == Qt::LeftButton) { mIsChecked = ! mIsChecked; currentIndex = index; clickedHelper(); } } break; case QEvent::HoverMove: case QEvent::HoverEnter: { QStyleOptionViewItem viewOpt(option); const QRect butRect = buttonRect(viewOpt); QMouseEvent *me = static_cast<QMouseEvent*>(event); currentIndex = index; if(index.isValid() && butRect.contains(me->pos())) mouseInHelper(); } break; default: break; } } return QStyledItemDelegate::editorEvent(event,model,option,index); }
-
I'm surprised
QMouseEvent *me = static_cast<QMouseEvent*>(event);
undercase QEvent::HoverMove: case QEvent::HoverEnter:
works. if it does is just through some compiler magic. you should cast it to the correct type:QHoverEvent
. Alsome->pos()
works in Qt5 but you needme->position()
for Qt6 -
Ok
@VRonin said in Add widget right aligned to a QTableWidget cell:
you should cast it to the correct type: QHoverEvent. Also me->pos() works in Qt5 but you need me->position() for Qt6
Will do it.
I have a question: in
createEditor
, I just deleted the twoconnect
lines and signals are still being emitted. So what is the purpose of creating theMyButton
object there? -
@VRonin said in Add widget right aligned to a QTableWidget cell:
Also me->pos() works in Qt5 but you need me->position() for Qt6
here
QRect::contains
takes aQPoint
butme->position
is aQPointF
, I will have to do some casting.Edit: I will just use
QPointF::toPoint
-
@hbatalha said in Add widget right aligned to a QTableWidget cell:
here QRect::contains takes a QPoint but me->position is a QPointF, I will have to do some casting.
Just call
.toPoint()
seeTableWidgetDelegate::viewportEvent
I have a question: in createEditor, I just deleted the two connect lines and signals are still being emitted. So what is the purpose of creating the MyButton object there?
Those 2 lines deal with when the user is actually editing. In my original example the delegate was the default editor (usually a lineedit) + a button on the side. The default editor is used to change the contents of the cell. If the user starts editing the cell (doubleclick by default) the editor will pop up and you'll see that clicking on the buttons will not do anything unless you have those 2
connect
s.
In a nutshell we have to handle 2 cases: when the delegate is just painting and when the editor is presented to the user -
@VRonin said in Add widget right aligned to a QTableWidget cell:
Those 2 lines deal with when the user is actually editing. In my original example the delegate was the default editor (usually a lineedit) + a button on the side. The default editor is used to change the contents of the cell. If the user starts editing the cell (doubleclick by default) the editor will pop up and you'll see that clicking on the buttons will not do anything unless you have those 2 connects.
In a nutshell we have to handle 2 cases: when the delegate is just painting and when the editor is presented to the userGot it, thanks.
Could you please answer me here?
-
@VRonin
I hope I can hijack this thread now that the OP has had his questions answered?I know the crusade you are on. And I have to respect that the OP may have a lot of items, I don't know. But would you admit that --- without starting a flame-war --- this is one hell of a lot of code to add for a delegate approach if
setCellWidget()
would have done the job?