c++ - 数据更改时自动刷新 QTableView

标签 c++ qt model-view-controller

我已经编写了一个自定义数据模型来显示多个 QTableViews。

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

但是,我的问题是我必须将鼠标移到 QTableView 上才能显示实际更改,而我希望所有 View 在进行更改时显示更改,而不需要与 View 交互以更新它们。

有什么想法吗?谢谢,


值得一提的是,我不使用默认的 Qt::EditRole 角色来编辑数据,而是使用自定义枚举值(名为 ActiveRole)。

这就是我要寻找的:我的数据模型包含有关如何显示数据的属性,用于生成样式表并提供给 viewS。

因此,当更改模型时,对于每个 View ,其所有项目都会受到影响,这就是为什么发送 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;
}

我有一个自定义委托(delegate),它在很大程度上依赖于这个 SO thread用于覆盖 paintsizeHint 方法以绘制 QTextDocument。此外,它在setEditorData中将ActiveRole的内容提供给编辑器,并在setModelData中调用DataMode::setData >:

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() 中,我将来自编辑器的信号插入到我的委托(delegate)的槽中以提交数据:

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

当点击一个item时,编辑器触发activeItem信号;连接的插槽 commitEditorData 依次在参数中引发 commitData 信号和编辑器。

所以我所有的 View 都使用这些自定义委托(delegate)、编辑器和数据模型。我正在与之交互的 View 确实会立即显示更改,但其他 View 也需要将鼠标悬停在它们上方才能显示更改。

最佳答案

我实际上发现了问题,那就是我的另一个 View 没有得到数据更改的正确通知:我的每个 View 都显示了我的数据的不同部分,因此需要将 dataChanged() 通知给其他 View ,但对于它们自己的、适当的索引。

附带说明一下,当我的 Qt 应用程序不是窗口管理器中的事件窗口时,我还遇到了更新 View 的问题。解决方案是在主窗口上调用 repaint()

关于c++ - 数据更改时自动刷新 QTableView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12893904/

相关文章:

qt - 在样式表中创建的渐变看起来与通过 QBrush 创建的渐变不同?

java - 在 Servlet/MVC 中查看模型

ios - Swift,如何在遵循 MVC 的同时声明需要实例成员的方法

c++ - 无法派生的类

c++ - 无法将字符串转换为字符数组

c++ - 链接 C++ 项目时出现多重定义错误

qt - 覆盖文本文件与追加

android - 错误构建 APK QT Creator - 构建 android 包失败

javascript - Backbone ?可以.js吗?贫民窟DIY?我应该如何处理这些数据?

c++ - 当 std 数组初始化太小时,C++ 会引发错误吗?