QStyledItemDelegate - updateEditorGeometry如何工作?

New*_*biZ 5 qt widget qwidget

我正在使用Qt 4.7.

我有一个模型,我QTableView在两列中显示,我的目标是在我的中提供该模型的内联编辑QTableView.

+-----------------+----------------+
|  Axis position  |  Axis range    |
+-----------------+----------------+
|      Left       | Fixed [0,1]    |
|      Left       | Source: SRC1   |
|      Right      | Source: SRC2   |
|      Left       | Fixed [5,10]   |
+-----------------+----------------+
Run Code Online (Sandbox Code Playgroud)

第一列是可编辑的,使用简单的QComboxBox方法在右和左之间切换,它可以很好地工作.问题出在我的第二列,可以使用自定义小部件进行编辑.

这个小部件很简单,它描述了一个范围.所以有一个QComboBox来选择范围的类型("固定":值由用户给出,"源":该值是从源的最小值/最大值动态调整的).

这是我的自定义小部件的源代码:

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();
  }
}
Run Code Online (Sandbox Code Playgroud)

好的,现在,我创建了一个QStyledItemDelegate,为我的列提供了一个自定义编辑器视图.我是这样做的:

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 );
}
Run Code Online (Sandbox Code Playgroud)

基本上,我得到的是单像素高度编辑器.

以下是结果的屏幕截图:Screenshot1

我试图改为updateEditorGeometry以下内容:

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

这似乎解决了尺寸问题,但不是位置: 在此输入图像描述

我觉得有点丢失,因为我不知道问题是来自我的自定义小部件(没有为Qt提供足够的信息来正确计算它的位置),还是视图(可能是一些会破坏编辑器大小的边缘),或者updateEditorGeometry()方法.

任何帮助非常感谢,感谢阅读!

ser*_*nko 11

我会说通过调用来设置编辑器的几何:

editor->setGeometry(rect);
Run Code Online (Sandbox Code Playgroud)

应该正常工作; 在你的情况下发生的是你的编辑器是使用QHBoxLayout构建的,它具有默认的边距和间距集.tableview行的默认高度小于编辑器的高度,这使得编辑器可以调整大小; 屏幕截图上的一个像素行将是:上边距+控件左下边距+下边距.

通过为tableview启用垂直标题,您可以调整行高,使编辑器控件完全可见.

你可以做什么:

1.删​​除\减少布局的间距和边距:

QHBoxLayout* layout = new QHBoxLayout();
layout->setSpacing(1);
layout->setMargin(1);
setLayout(layout);
Run Code Online (Sandbox Code Playgroud)

在这种情况下,以这种方式更新编辑器的几何:

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);
Run Code Online (Sandbox Code Playgroud)

要不就

editor->setGeometry(rect);
Run Code Online (Sandbox Code Playgroud)

应该适合你

2.您还可以考虑为行\单元格值使用弹出编辑器

3.Resize小部件的行高,以适应单元格编辑器.

希望这有帮助,问候