6

Qt4.7を使用しています。

2列で表示するモデルがありQTableViewます。私の目標は、でこのモデルのインライン編集を提供することQTableViewです。

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

最初の列はQComboxBox、右と左を簡単に切り替えることで編集可能であり、非常にうまく機能します。問題は、カスタムウィジェットを使用して編集可能な2番目の列にあります。

このウィジェットは一種の単純なもので、範囲を記述します。したがって、範囲の種類を選択するための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();
  }
}

さて、これで、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 );
}

基本的に、私が得るのは単一ピクセルの高さエディターです。

結果のスクリーンショットは次のとおりです。スクリーンショット1

私は次のように変更しようとしましupdateEditorGeometryた:

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

これはサイズの問題を修正するようですが、位置は修正しません: ここに画像の説明を入力してください

問題がカスタムウィジェット(Qtがその位置を適切に計算するための十分な情報を提供していない)、ビュー(エディターのサイズを押しつぶす可能性のあるマージン)、またはupdateEditorGeometry()方法。

読んでくれてありがとう!

4

1 に答える 1

12

次のように呼び出して、エディターのジオメトリを設定します。

editor->setGeometry(rect);

正しく動作するはずです。あなたの場合に起こることは、あなたのエディタがデフォルトのマージンと間隔が設定されているQHBoxLayoutを使用して構築されているということです。テーブルビュー行のデフォルトの高さはエディターの高さよりも低く、これによりエディターのサイズが変更されます。スクリーンショットの1ピクセル行は、上マージン+コントロールから残っているもの+下マージンになります。

テーブルビューの垂直ヘッダーを有効にすると、行の高さのサイズを変更して、エディターコントロールを完全に表示できるようになります。

あなたができること:

1.レイアウトの間隔と余白を削除/縮小します。

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

この場合、エディターのジオメトリを次のように更新します。

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);

あるいは単に

editor->setGeometry(rect);

あなたのためにうまくいくはずです

2.行\セルの値にポップアップエディタを使用することも検討できます

3.セルエディタに合わせてウィジェットの行の高さを変更します。

これがお役に立てば幸いです

于 2011-03-29T04:04:07.703 に答える