Add widget right aligned to a QTableWidget cell
-
@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? -
@JonB said in Add widget right aligned to a QTableWidget cell:
would you admit that this is one hell of a lot of code to add for a delegate approach
I'll even go one step further, and say that for anything more complicated than adding a button, going down reimplementing
paint
is completely unreasonable. It still doesn't excusesetCellWidget()
. You can always use something like this delegate (beware: old code) to have 1 widget taking care of painting every cell instead of having as many widgets as there are cells -
@JonB said in Add widget right aligned to a QTableWidget cell:
Beware that this topic is not about replacing
setCellWidget()
, the one aboutsetCellWidget()
is still open.this is one hell of a lot of code to add for a delegate approach if setCellWidget() would have done the job?
setCellWidget()
is just awful when you have a chance of using a delegate instead. Since I discovered that I can use a delegate instead, having asetCellWidget
has become very unsettling for me. -
@hbatalha
Thanks, I did wonder whether it was a different topic, but didn't try to go find it.Your sentiments must warm the cockles of @VRonin's heart ;-) But for those of us who value writing as little code as possble when there is built-in stuff it's not such good news. I do respect why delegates are a better choice, shame there is so much code to write.
@VRonin should "publish" a library/class,
QStyledItemWidgetDelegate
, perhaps based on the code of his referred to in his last post, which does everything one might want fromsetCellWidget
but in a delegate-y way, for everyone to use :) [Also, he should try to keep it down to, say, 10 lines...] -
@JonB said in Add widget right aligned to a QTableWidget cell:
Also, he should try to keep it down to, say, 10 lines...
ahahah!
should "publish" a library/class, QStyledItemWidgetDelegate
Already on my TODO list
-
@JonB said in Add widget right aligned to a QTableWidget cell:
@VRonin should "publish" a library/class, QStyledItemWidgetDelegate, perhaps based on the code of his referred to in his last post, which does everything one might want from setCellWidget but in a delegate-y way, for everyone to use :) [Also, he should try to keep it down to, say, 10 lines...]
I was about to say that. Maybe propose the library to the Qt team to add to the official release(if that's how it is done)
-
@hbatalha said in Add widget right aligned to a QTableWidget cell:
@VRonin I have a simple question: is it possible to use
setItemDelegateForRow
andsetItemDelegateForRow
at the same view(same row)?I assume you mean
setItemDelegateForRow
andsetItemDelegateForColumn
.
from https://doc.qt.io/qt-5/qabstractitemview.html#setItemDelegateForRowNote: If a delegate has been assigned to both a row and a column, the row delegate will take precedence and manage the intersecting cell index.