QAbstractTableModel 并为单行发出 dataChanged

2024-01-24

我从 QAbstractTableModel 派生了一个模型,现在我想通知,整行的数据已更改。例如,如果索引为 5 的行的数据发生更改(4 列),则使用以下代码可以按预期工作。

emit dataChanged(index(5,0), index(5, 0));
emit dataChanged(index(5,1), index(5, 1));
emit dataChanged(index(5,2), index(5, 2));
emit dataChanged(index(5,3), index(5, 3));

但如果我尝试达到同样的效果仅发出一次,视图中所有行的所有列都会更新。

emit dataChanged(index(5, 0), index(5, 3));

我在这里做错了什么?

最小示例(C++11、QTCreator 4.7.1、Windows 10 (1803)、64 位)

demo.h

#pragma once
#include <QAbstractTableModel>
#include <QTime>
#include <QTimer>

class Demo : public QAbstractTableModel
{
  Q_OBJECT
  QTimer * t;
public:
  Demo()
  {
    t = new QTimer(this);
    t->setInterval(1000);
    connect(t, SIGNAL(timeout()) , this, SLOT(timerHit()));
    t->start();
  }

  QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override
  {
    int c = index.column();
    if (role == Qt::DisplayRole)
    {
      QString strTime = QTime::currentTime().toString();
      if (c == 0) return "A" + strTime;
      if (c == 1) return "B" + strTime;
      if (c == 2) return "C" + strTime;
      if (c == 3) return "D" + strTime;
    }
    return QVariant();
  }

  int rowCount(const QModelIndex &) const override { return 10; }
  int columnCount(const QModelIndex &) const override { return 4; }
private slots:
  void timerHit()
  {
    //Works
    emit dataChanged(index(5,0), index(5, 0));
    emit dataChanged(index(5,1), index(5, 1));
    emit dataChanged(index(5,2), index(5, 2));
    emit dataChanged(index(5,3), index(5, 3));

    //emit dataChanged(index(5,0), index(5, 3)); // <-- Doesn't work
  }
};

main.cpp

#include "demo.h"
#include <QApplication>
#include <QTreeView>

int main(int argc, char *argv[])
{
  QApplication a(argc, argv);
  QTreeView dataView;
  Demo dataModel{};
  dataView.setModel( &dataModel );
  dataView.show();
  return a.exec();
}

我认为问题在于你对以下行为所做的某些假设QTreeView当。。。的时候QAbstractItemModel::dataChanged http://doc.qt.io/qt-5/qabstractitemmodel.html#dataChanged发出信号。

具体来说,您假设视图只会调用QAbstractItemModel::data http://doc.qt.io/qt-5/qabstractitemmodel.html#data在信号中指定的那些索引上。情况不一定如此。

查看源代码QAbstractItemView::dataChanged (Qt5.11.2) 你会看到...

void QAbstractItemView::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles)
{
    Q_UNUSED(roles);
    // Single item changed
    Q_D(QAbstractItemView);
    if (topLeft == bottomRight && topLeft.isValid()) {
        const QEditorInfo &editorInfo = d->editorForIndex(topLeft);
        //we don't update the edit data if it is static
        if (!editorInfo.isStatic && editorInfo.widget) {
            QAbstractItemDelegate *delegate = d->delegateForIndex(topLeft);
            if (delegate) {
                delegate->setEditorData(editorInfo.widget.data(), topLeft);
            }
        }
        if (isVisible() && !d->delayedPendingLayout) {
            // otherwise the items will be update later anyway
            update(topLeft);
        }
    } else {
        d->updateEditorData(topLeft, bottomRight);
        if (isVisible() && !d->delayedPendingLayout)
            d->viewport->update();
    }

#ifndef QT_NO_ACCESSIBILITY
    if (QAccessible::isActive()) {
        QAccessibleTableModelChangeEvent accessibleEvent(this, QAccessibleTableModelChangeEvent::DataChanged);
        accessibleEvent.setFirstRow(topLeft.row());
        accessibleEvent.setFirstColumn(topLeft.column());
        accessibleEvent.setLastRow(bottomRight.row());
        accessibleEvent.setLastColumn(bottomRight.column());
        QAccessible::updateAccessibility(&accessibleEvent);
    }
#endif
    d->updateGeometry();
}

重要的一点是,根据信号是否指定单个信号,此代码的行为有所不同QModelIndex-- 例如topLeft是相同的bottomRight。如果他们are同样,视图会尝试确保仅更新该模型索引。但是,如果指定了多个模型索引,那么它将调用...

d->viewport->update();

这可能会导致查询所有可见模型索引的数据。

自从您实施以来Demo::data始终根据当前时间返回新数据,您将看到视图更新的整个可见部分,给人的印象是dataChanged所有行和列均发出信号。

因此,解决方案实际上是让您的数据模型更加“有状态”——它需要跟踪值,而不是简单地按需生成它们。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

QAbstractTableModel 并为单行发出 dataChanged 的相关文章

  • .NET 单点登录

    我一直在尝试使用 C 为 NET Web 应用程序实现 WEB SSO 服务提供程序插件 我将使用 shibboleth 身份提供商 我已经使用 OpenSAML 库为 java 应用程序实现了相同的功能 我想知道在 NET 应用程序中使用
  • Linq - 从表达式 创建表达式

    我有一个谓词Expression
  • 是否有可能劫持标准输出

    我正在尝试使用 C 重定向 Windows XP 上已运行进程的标准输出 我知道如果我自己生成进程 我可以做到这一点 但对于这个应用程序 我更喜欢一个 监听器 我可以附加到另一个进程 这在纯 Net 中可能吗 如果不可能 在 Win32 中
  • 为什么我会收到未找到分析器的警告?

    我创建了一个玩具项目来检查最新的 NET 7 预览版 5 和正则表达式代码生成 它效果很好 所以我对现有项目应用了相同的更改 不是为了生产 而是为了个人生产力 由于某种原因 我收到这些警告 CS8032 An instance of ana
  • .crt 部分?这个警告是什么意思?

    我最近收到此警告 VC 2010 warning LNK4210 CRT section exists there may be unhandled static initializers or terminators 我假设这是关键部分
  • STL之类的容器typedef快捷方式?

    STL 容器的常见模式是这样的 map
  • 将公历日期转换为儒略日期,然后再转换回来(随着时间)

    我正在编写一个程序 必须将当前的公历日期和时间转换为儒略日期 然后再转换回公历门 最终我需要添加能够添加年 月 日 小时 分钟和秒的功能 但我需要先解决这部分问题 现在我已经从公历日期转换为儒略日期 所以从逻辑上讲 我觉得我应该能够以某种方
  • 最新 .Net MongoDb.Driver 的连接问题

    我创建了一个 MongoLab 沙箱数据库 我与 MongoChef 连接 效果很好 我通过 Nuget 安装了 MongoDB Driver 2 2 2 我编写了一些简单的 C 演示代码 但就是无法使其工作 连接字符串是直接从 Mongo
  • 局部函数声明有什么用处吗?

    大多数像我这样的 C 程序员都曾犯过以下错误 class C int main C c declares a function c taking no arguments returning a C not as intended by m
  • 如何从 Qt 应用程序通过 ODBC 连接到 MySQL 数据库?

    我有一个新安装的 MySQL 服务器 它监听 localhost 3306 从 Qt 应用程序连接到它的正确方法是什么 原来我需要将MySQL添加到ODBC数据源 我在遵循这个视频教程后做到了这一点 https youtu be K3GZi
  • opencv中如何去除二值图像噪声?

    将图像转换为二值图像 黑白 后如果有任何噪音怎么办 我消除了那些不需要的噪音 您可以看到下图的黑色区域内有一些白噪声 我该如何去除噪声 使用opencv http img857 imageshack us img857 999 blackn
  • 应用程序处于中断模式。您的应用程序已进入中断状态,

    我发现自己遇到了同样的问题here https stackoverflow com questions 36204009 disable break mode page in vs2015 我在 dll 中使用 Windows 窗体 这是针
  • 配置:错误:无法运行C编译的程序

    我正在尝试使用 Debian Wheezy 操作系统在我的 Raspberry Pi 上安装不同的软件 当我运行尝试配置软件时 我尝试安装我得到此输出 checking for C compiler default output file
  • 您对“大规模 C++ 软件设计”的看法 [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 正在阅读亚马逊评论 https rads stackoverflow com amzn click com 0201633620 and ACC
  • 当需要不同数量和类型的参数时如何创建操作委托列表

    我们有一组大约两打的类 它们继承自具有抽象 Validate 方法的基类 当然 每个类都有不同的验证需求 但它们之间的不同组合需要规则 因此 正如您可以想象的那样 这导致了大量代码重复 例如 A 类需要规则 1 3 6 和 9B 类需要规则
  • 如何将System.Windows dll添加到Visual Studio 2010 Express?

    我正在开发一个小型应用程序C and VS2010 as IDE with NET框架4 我想用CaptureSource类以便从笔记本电脑的网络摄像头捕获视频 为此我需要添加一个命名空间System Windows DependencyO
  • 当我的进程被终止时到底会发生什么?

    我有一个包含本机代码和托管代码的混合进程 在 Windows Server 2003 上运行 当我从进程资源管理器中终止进程时 它会进入 100 cpu 的状态 并在消失之前保持这种状态一段时间 有时甚至 10 分钟 在此期间我无法 杀死
  • 从脚本启用/禁用 GameObject 组件 [Unity3D]

    我需要获取一个脚本中设置的布尔值 放入名为 bouclier 的变量 以启用或禁用游戏对象 该变量位于游戏对象 Player 中 此处右下角 我需要启用或禁用这个游戏对象 Bouclier01 为此 我将脚本附加到游戏对象 Bouclier
  • 将一个 IEnumerable 拆分为多个 IEnumerable

    我是 linq 新手 我需要根据指示器将 Couple string text bool Indicator 类型的 IEnumerable 拆分为多个 IEnumerable 我尝试使用skipWhile 和 TakeWhile 但没有找
  • 如何使用 C# 为 azure devops 变量赋值

    我有 selenium C 测试脚本 可以从浏览器获取令牌 我有两个 azure devops 任务 一个用于执行 selenium 测试 另一个用于执行 API 测试 我想将 selenium 测试获取的令牌传递给 API 测试执行任务

随机推荐

  • 每 4 件商品替换颜色 [重复]

    这个问题在这里已经有答案了 是否可以使用纯 CSS 创建一个每 4 个项目交替的颜色网格 例如 前 4 个项目为蓝色 接下来的 4 个为红色 然后接下来的 4 个项目为蓝色 依此类推 div Item 1 blue div div Item
  • T-SQL 将多行连接并分组为一行[重复]

    这个问题在这里已经有答案了 我正在寻找一种分组方法 同时还将行连接成逗号分隔的字符串 例子 Name Place Steve Jones New York Steve Jones Washington Albert Smith Miami
  • 将节点从 6 升级到最新版本时,npm i 在 React Native 项目中失败并显示 ENOENT

    在 React Native 项目上将 npm 从 6 14 升级到最新版本时 使用节点14 nvm切换节点版本 理想情况下我想转到节点16 但是特别是在更新npm时 无论14还是16都会发生类似的问题 我也在 mac M1 上使用自制程序
  • 如何计算交易的最低硬币找零?

    嘿大家 我有个问题 我正在使用 Visual Basic Express 我应该计算交易的变化 现在我会使用什么代码 我已经部分工作了 但它开始变得有点混乱 谢谢 对于那些想了解更多信息的人 假设我有一美元 我去商店买东西 我必须要求用户输
  • 无法禁用 OpenCart (PHP) 中的错误报告

    我似乎无法禁用 PHP 中的错误报告 我已经尝试了所有方法 但仍然显示 注意 错误 我的 php ini 有 display errors Off error reporting 0 我的 htaccess 有 php value erro
  • 如何将核心数据模型项传递到视图中进行编辑

    我有一个最小的示例项目CD传递Q https github com ericg xcode questions CDPassingQ 我的主要 内容视图 https github com ericg xcode questions CDPa
  • JSON 发布,我是否把 JSON 推得太远了?

    我只是想知道我是否把 JSON 推得太远了 如果有人以前打过这个 我有一个 xml 文件
  • 在 Spark Scala 中将时间戳转换为 UTC

    我的环境是Spark 2 1 Scala 这可能很简单 但我很伤脑筋 我的数据框 myDF 如下所示 orign timestamp origin timezone 2018 05 03T14 56 America St Johns 201
  • elasticsearch_dsl:聚合生成多个桶

    我想生成这个 GET packets 2017 09 25 search size 0 query match transport protocol tcp aggs clients terms field layers ip src ke
  • Excel宏来合并数据

    我的一个文件夹中有很多excel文件 我想要一个宏来遍历每个文件并复制名为最终成本并在目标文件中制作一个带有源文件名称的工作表 就像有三个文件 A B C 每个文件都有一个名为 最终成本 新文件将包含三个工作表 名称为 A B C 编辑后的
  • Bloc 7.2 迁移 - 在流内传递参数

    我目前正在将一个项目从 Bloc 7 0 迁移到 bloc 7 2 我曾经有一个流 我会yield 在不同的流中并每次传递不同的值作为参数 Stream
  • 什么是 BEM 方法? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我最近听说了 BEM 方法 BEM 方法到底有什么用途 BEM 在哪些方面让我们的工作变得更轻松 使用 BEM 是一个好的做法吗 BE
  • Rails3 中的 Ajax 回调

    在rails 2中 对于ajax表单 我们可以有ajax回调 例如之前 之后等 如何在rails 3中做到这一点 我也有同样的问题 并且这个帖子 http blancer com tutorials 105318 using unobtru
  • 将 BigQuery 数据导出为 CSV,而不使用 Google Cloud Storage

    我目前正在编写一个软件 用于导出大量 BigQuery 数据并将查询结果存储为本地 CSV 文件 我使用的是Python 3和google提供的客户端 我进行了配置和身份验证 但问题是 我无法在本地存储数据 每次我执行时 我都会跟随错误信息
  • 轮询成功,但出现错误:操作正在进行中 (29)。当 Xdebug 尝试从 docker 容器连接到 PhpStorm 时

    我正在尝试调试 CLI 脚本 但 Xdebug 无法连接到 PhpStorm 我看到错误Operation now in progress 29 在 Xdebug 远程日志中 我确信 Xdebug 配置正确 但我不知道如何调试 PhpSto
  • 如何删除焦点输入的默认值

    我有一个输入框 分配有默认值文本 当用户聚焦于该字段时 如何删除此文本 CoDE
  • 如何在python中随机化图像像素

    我对计算视觉和Python很陌生 我无法真正弄清楚出了什么问题 我尝试随机化 RGB 图像中的所有图像像素 但结果证明我的图像完全错误 如下所示 有人可以解释一下吗 from scipy import misc import numpy a
  • IIS7 部署 - 重复的“system.web.extensions/scripting/scriptResourceHandler”部分

    尝试在 IIS7 中的默认应用程序池 框架部分设置为 4 0 上部署 net 3 5 网站时 出现以下错误 有一个重复的 system web extensions scripting scriptResourceHandler 部分 定义
  • go 1.5 跟踪命令

    Go 1 5 发行说明说 新的 go tool trace 命令可以实现运行时中新跟踪基础设施生成的程序跟踪的可视化 这真的很令人兴奋 我想了解更多 但其官方文件位于https golang org cmd trace https gola
  • QAbstractTableModel 并为单行发出 dataChanged

    我从 QAbstractTableModel 派生了一个模型 现在我想通知 整行的数据已更改 例如 如果索引为 5 的行的数据发生更改 4 列 则使用以下代码可以按预期工作 emit dataChanged index 5 0 index