9

いくつかの QTableView で表示されるカスタム データ モデルを作成しました。

技術的には、すべて正常に動作します。ビューには、モデルから加えられた変更が表示されます。私のデータモデルは編集可能で、setData()メソッドはシグナルを発行し、編集が成功dataChanged()すると戻ります。true

ただし、私の問題はQTableView、実際の変更を表示するにはマウスを上に移動する必要があることですが、すべてのビューに変更が加えられたときに変更を表示したいのですが、ビューを操作する必要はありません。更新しました。

何か案が?ありがとう、


Qt::EditRoleデフォルトのロールを使用してデータを編集するのではなく、カスタム列挙値 (という名前) を使用することに言及することは適切かもしれませんActiveRole

ここに私が求めているものがあります: 私のデータ モデルには、viewS に供給されるスタイル シートを生成するために使用される、データを表示する方法に関するプロパティが含まれています。

したがって、モデルを変更すると、ビューごとにそのすべてのアイテムが影響を受けます。これが、dataChanged()すべてのセルをカバーするインデックスと共にシグナルが送信される理由です。

も発行しようとしましたがlayoutChanged()、私の場合は動作が変わらないようです。

setData()メソッドの抜粋を次に示します。

bool DataModel::setData(QModelIndex const& idx, QVariant const& value, int role)
{
  if (ActiveRole == role)
  {
    // Update data...

    QModelIndex topLeft = index(0, 0);
    QModelIndex bottomRight = index(rowCount() - 1, columnCount() - 1);

    emit dataChanged(topLeft, bottomRight);
    emit layoutChanged();

    return true;
  }
  return false;
}

data()メソッドのサンプルを次に示します。

QVariant DataModel::data(QModelIndex const& idx, int role) const
{
  if (ActiveRole == role)
  {
    boost::uuids::uuid id;

    return qVariantFromValue(id);
  }

  return QVariant();
}

そしてflags()、編集可能なモデルを示します:

Qt::ItemFlags DataModel::flags(QModelIndex const& idx) const
{
  if (false == idx.isValid())
  {
    return Qt::ItemIsEditable;
  }

  return QAbstractTableModel::flags(idx) | Qt::ItemIsEditable;
}

を描画するためにメソッドとメソッドをオーバーライドするために、このSO スレッドに大きく依存するカスタム デリゲートがあります。また、 の内容をのエディターに提供し、 を呼び出します。paintsizeHintQTextDocumentActiveRolesetEditorDataDataMode::setDatasetModelData

void DataModelDelegate::setEditorData(QWidget* editor, QModelIndex const& idx) const
{
  auto active = qVariantValue<boost::uuids::uuid>(idx.data(ActiveRole));
  static_cast<DataModelEditor*>(editor)->setActive(active);
}

void DataModelDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, QModelIndex const& idx) const
{
  auto active = static_cast<DataModelEditor*>(editor)->getActive();
  model->setData(idx, qVariantFromValue(active), ActiveRole);
}

では、createEditor()データをコミットするために、エディタからデリゲートのスロットに信号を接続します。

QWidget* DataModelDelegate::createEditor(QWidget* parent, QStyleOptionViewItem const& option, QModelIndex const& idx) const
{
  auto editor = new DataModelEditor(parent);
  connect(editor, SIGNAL(activeItem()), this, SLOT(commitEditorData()));
  return editor;
}

activeItemアイテムをクリックすると、エディターはシグナルをトリガーします。接続されたスロットは、エディタの引数で信号を発生さcommitEditorDataせます。commitData

したがって、私のすべてのビューは、これらのカスタム デリゲート、エディター、およびデータ モデルを使用します。私が操作しているビューには変更がすぐに表示されますが、他のビューでも変更を表示するには、マウスをそれらの上に置く必要があります。

4

3 に答える 3

6

私は実際に問題を発見しました。これは、他のビューにデータの変更が適切に通知されなかったことです。ビューはそれぞれデータの異なる部分を示していたため、他のビューに通知する必要がありましたdataChanged()。 .

余談ですが、Qt アプリケーションがウィンドウ マネージャーでアクティブなウィンドウではないときに、ビューを更新するという問題もありました。repaint()解決策は、メイン ウィンドウを呼び出すことでした。

于 2012-11-16T14:22:01.367 に答える
-1

に電話していsetData()ますか? dataChanged()信号は本当に発信されていますか?それにいくつかのデバッグ ログ スロットを接続します。これはあなたの問題と非常によく似ていると思います:

http://www.qtcentre.org/threads/18388-Refreshing-a-QTableView-when-QAbstractTableModel-changes?s=fd88b7c4e59f4487a5457db551f3df2c

于 2012-10-15T14:45:37.460 に答える