QStyledItemDelegate - How does updateEditorGeometry work?

I am using Qt 4.7.

I have a model that I show in a QTableView in two columns, and my goal is to provide inline editing of this model in my QTableView .

 +-----------------+----------------+ | Axis position | Axis range | +-----------------+----------------+ | Left | Fixed [0,1] | | Left | Source: SRC1 | | Right | Source: SRC2 | | Left | Fixed [5,10] | +-----------------+----------------+ 

The first column can be edited using a simple QComboxBox to switch between Right and Left, and it works quite well. The problem is with my second column, which can be edited using a custom widget.

This widget is simple; it describes a range. Thus, QComboBox selects the type of range ("Fixed": values ​​are set by the user "Source": the value is dynamically changed from the minimum / maximum value of the source).

Here is the source code of my custom widget:

 class RangeEditor : public QWidget { Q_OBJECT public: RangeEditor( ... ); ~RangeEditor(); public: CurveView::ConfigAxes::Range range () const; QVariant minimum() const; QVariant maximum() const; DataModel* model () const; void range ( CurveView::ConfigAxes::Range range ); void minimum( QVariant minimum ); void maximum( QVariant maximum ); void model ( DataModel* model ); public slots: void rangeTypeChanged( int type ); private: // --- External editors QComboBox* editRange_; QSpinBox* editMinimum_; QSpinBox* editMaximum_; QComboBox* editModel_; }; RangeEditor::RangeEditor( ... ) : QWidget(parent) { editRange_ = new QComboBox(this); editMinimum_ = new QSpinBox (this); editMaximum_ = new QSpinBox (this); editModel_ = new QComboBox(this); QHBoxLayout* layout = new QHBoxLayout(); setLayout(layout); layout->addWidget( editRange_ ); layout->addWidget( editMinimum_ ); layout->addWidget( editMaximum_ ); layout->addWidget( editModel_ ); editRange_->addItem( "Fixed" ); editRange_->addItem( "Source" ); editModel_->setCurrentIndex(0); editModel_->hide(); QObject::connect( editRange_, SIGNAL(currentIndexChanged(int)), this, SLOT (rangeTypeChanged(int)) ); } void RangeEditor::rangeTypeChanged( int type ) { if ( type==CurveView::ConfigAxes::FIXED ) { editMinimum_->show(); editMaximum_->show(); editModel_->hide(); } else if ( type==CurveView::ConfigAxes::SOURCE ) { editMinimum_->hide(); editMaximum_->hide(); editModel_->show(); } } 

Ok, so now I created a QStyledItemDelegate to provide a custom editor view for my columns. Here is how I did it:

 class ConfigAxesDelegate : public QStyledItemDelegate { public: ConfigAxesDelegate( ... ); ~ConfigAxesDelegate(); public: virtual QWidget* createEditor ( QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index ) const; virtual void setEditorData ( QWidget* editor, const QModelIndex& index ) const; virtual void setModelData ( QWidget* editor, QAbstractItemModel* model, const QModelIndex& index ) const; virtual void updateEditorGeometry( QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index ) const; }; QWidget* ConfigAxesDelegate::createEditor( QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index ) const { if ( index.column()==0 ) // Position { PositionEditor* editor = new PositionEditor(parent); return editor; } else if ( index.column()==1 ) // Range { RangeEditor* editor = new RangeEditor(parent); return editor; } else { return QStyledItemDelegate::createEditor(parent,option,index); } } void ConfigAxesDelegate::updateEditorGeometry( QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index ) const { // WHAT TO DO HERE? editor->setGeometry( option.rect ); } 

Basically, what I get is a single pixel height editor.

Here is a screenshot of the result: Screenshothot1

I tried changing updateEditorGeometry to the following:

 void ConfigAxesDelegate::updateEditorGeometry( QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index ) const { QRect r = option.rect; r.setSize( editor->sizeHint() ); editor->setGeometry( r ); } 

The size problem seems to be fixed, but not the position: enter image description here

I feel lost because I don’t know if a problem arises from my custom widget (not providing enough information for Qt to correctly calculate its position) or presentation (maybe some fields that may lead to a reduction in the size of the editor), or updateEditorGeometry()

Any help is much appreciated, thanks for reading!

+4
source share
1 answer

I would say setting the geometry of the editor by calling:

 editor->setGeometry(rect); 

should work correctly; What happens in your case is that your editor is built using QHBoxLayout with the default fields and intervals. The default height for table rows is less than the height of the editor, and this changes the size of your editor; one pixel line in your screenshot will be: top edge + what is left of the controls + bottom edge.

By including a vertical title for your spreadsheet view, you can resize the row so that all editor controls are fully visible.

What could you do:

1. Remove / reduce the distance and margins for the layout:

 QHBoxLayout* layout = new QHBoxLayout(); layout->setSpacing(1); layout->setMargin(1); setLayout(layout); 

in this case, updating the editor geometry as follows:

 QRect rect = option.rect; QSize sizeHint = editor->sizeHint(); if (rect.width()<sizeHint.width()) rect.setWidth(sizeHint.width()); if (rect.height()<sizeHint.height()) rect.setHeight(sizeHint.height()); editor->setGeometry(rect); 

or simply

 editor->setGeometry(rect); 

should work great for you

2. You may also consider using pop-up editors for your row / value cells.

3.Cut the widget row height to fit cell editors.

hope this helps, believes

+10
source

Source: https://habr.com/ru/post/1345522/


All Articles