QTableView和QStandardItemModel问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了QTableView和QStandardItemModel问题相关的知识,希望对你有一定的参考价值。

我面临着将事物动态添加到我的QStandardItemModel并用QTableView显示它们的奇怪事情。如果事件之间的时间足够长(例如50毫秒),则视图可以滚动,但如果事件较快(10毫秒),则视图始终向下滚动,并且不允许我执行任何操作。

所以这是简单的代码片段:

main.cpp

#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])

    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();

mainwindow.h

#include <QMainWindow>
#include <QTimer>
#include <QTableView>
#include <QStandardItemModel>


QT_BEGIN_NAMESPACE
namespace Ui  class MainWindow; 
QT_END_NAMESPACE

class MainWindow : public QMainWindow

    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;

    QTimer dataTimer;

    QStandardItemModel *model;
    QTableView *view;

public slots:
    void insertData();
;

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QTime>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)

    ui->setupUi(this);

    view = new QTableView(this);
    this->setCentralWidget(view);

    model = new QStandardItemModel(this);
    model->setColumnCount(1);
    view->setModel(model);

    QObject::connect(&dataTimer, &QTimer::timeout, this, &MainWindow::insertData);
    dataTimer.start(10); // 50 here gives correct behaviour while 10 does not


MainWindow::~MainWindow()

    delete ui;


void MainWindow::insertData()

    QList<QStandardItem *> items;
    items.append(new QStandardItem(QTime::currentTime().toString("hh:mm:ss.zzz")));

    model->insertRow(0, items);
    if (model->rowCount() > 20)
        model->removeRow(model->rowCount()-1);
    

dataTimer.start(50)可以正常工作,而dataTimer.start(10)可以阻止行为。它用于我的笔记本电脑,也许对于其他人来说,数字会有所不同,但我认为逻辑很明确。

我以为这太快了,像beginInsertRows()之类的某些方法不能很好地工作。但这通常是针对定制模型的,在这里它只是一个标准模型。

有人可以告诉我为什么会这样吗?谢谢

答案

你好。好的,因此,当计时器设置为10毫秒时,每次屏幕刷新时都会添加和删除一行。

Qtimer与屏幕刷新率相关。这意味着如果计时器在不到16毫秒的时间内关闭,则在每次屏幕刷新时都会关闭。

[将项目添加到列表时,Qt在列表上运行其他UI事件以获取布局和视图范围。因为您要在每个屏幕上添加和删除,所以刷新列表会陷入运行这些事件的不断循环中。更不用说您的列表基本上每20帧被替换一次。

我不确定为什么您需要如此频繁地将项目添加到列表中,但是也许您应该将添加和删除项目批量添加到列表中,然后每100毫秒就可以批量添加和删除项目?这样可以解决问题。

另一答案

10 ms计时器在GUI线程中影响GUI元素本身不是一个好主意。例如,在Windows中,通过标准方式无法实现10毫秒的超时。您的用户真的需要每秒超过1次查看某些表数据的更新吗?他到底需要什么?基于此,您应该确定一种优化方法。

然后您可以选择:

  1. 减少计时器的超时,并在每个事件上影响几行。 似乎您仍然必须减少GUI计时器的超时。
  2. [例如,通过model->setRowCount(n)预先定期保留所需的行数;
  3. 通过setUpdatesEnabled()方法暂时禁用表刷新:

    setUpdatesEnabled(false);bigVisualChanges();setUpdatesEnabled(true);

  4. 对Qt模型类之一进行子类化,然后重新实现insertRows()或更多。

阅读Fetch More ExampleQt Model/View Programming

以上是关于QTableView和QStandardItemModel问题的主要内容,如果未能解决你的问题,请参考以下文章

QTableView() 仅在选择时更新更改

从 QTableView 读取和写入文件

QTreeView 和 QTableView 的 Qt 模型

QTableView:如何设置搜索栏

QTableView 和 QStandardItemModel 的问题

QTableView和QTableWidget翻页功能实现