9

我编写了一个自定义数据模型来显示几个 QTableView。

从技术上讲,一切正常:我的视图显示了我的模型所做的更改。我的数据模型是可编辑的,并且该setData()方法确实会发出dataChanged()信号并true在成功编辑时返回。

但是,我的问题是我必须将鼠标移到 aQTableView上才能显示实际更改,而我希望所有视图在进行更改时都显示更改,而无需与视图交互以使它们成为更新。

任何的想法?谢谢,


值得一提的是,我不使用默认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 线程来覆盖paintsizeHint方法以绘制QTextDocument. 此外,它在 中ActiveRole向编辑器提供 的内容,并在中setEditorData调用:DataMode::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 回答
5

我遇到了同样的问题,让我在piwi的答案中添加一个详细的解释。如果您更改数据,以及更新单列或多列(或行,取决于您的要求),您应该发出一组从左上角到右下角的索引。例如,如果您有如下表:

在此处输入图像描述

而且,现在您已经更改了一些数据,并且想要更新单元格第 1 行、第 1-2 列,那么您应该发出信号dataChange

emit datachange(index(1,1),index(1,2));
于 2019-08-13T04:16:02.203 回答
-1

你在打电话setData()吗?dataChanged()信号真的发出了吗?将一些调试日志插槽连接到它。我敢推测这与您的问题非常相似:

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

于 2012-10-15T14:45:37.460 回答