【问题标题】:How to let QTableView automatically update content even when it is not focused?如何让QTableView在没有聚焦的情况下自动更新内容?
【发布时间】:2019-08-20 09:27:29
【问题描述】:

我使用QTimer 对象扫描计算机内存以检测任何更改的数据,最后用QTableView 在GUI 中显示这些数据。
但问题是当程序窗口没有聚焦时,没有检测到任何变化。一旦窗口再次聚焦,Gui 中的数据就会立即发生变化。

我的问题是如何让tableview自动更新内容?

为了遵循 MVC 风格,我决定使用 QTableView 而不是 QTableWidget。确实,更新数据很方便,因为我只需要处理一个“模型”而不是 QTableView 绑定模型后。

QTableView 对象在 Gui 线程(视图级),QStandardItemModel 在另一个线程(控制级)中使用。对于这个问题,谷歌搜索后,我尝试了:

QModelIndex t1 = index(i, 3); 
QModelIndex t2 = index(i, 5);
emit dataChanged(t1, t2); 

在做dataChanged 时。它不起作用,当我发现模型方面没有问题时,我也尝试了:

connect(&timer, &QTimer::timeout, this, [&]() {
        ui.searchTableV->viewport()->update();
        });
    timer.start();

在 GUI 类构建的最开始。有时它可以工作,但通常会引发“访问冲突”。

就我个人而言,我从没想过会出现这样的问题,因为之前使用QTableWidget 一切正常。在我找到this on QT forum 之后,似乎我需要对子类QStyledItemDelegate 做一些事情以使QTableView 更加健壮。但我不想这样做,我认为应该有更简单的方法。

另外,我想知道这个问题是否是一个错误,或者它只是被设计成这样。

【问题讨论】:

  • QStandardItemModel 在另一个线程中使用 这可能是问题所在。 GUI 类通常不是线程安全的。我认为QStandardItemModel 也是如此。我做了google "QStandardItemModel thread safe",这让我相信了这一点。

标签: c++ qt crash


【解决方案1】:

我也尝试重现您描述的行为,但我无法做到。我的应用程序按预期工作,它是否会失去焦点并不重要。也没有崩溃。也许你正在做一些不同的事情。

Worker.h

#pragma once
#include <QObject>
#include <QThread>
#include <QStandardItemModel>

class Worker : public QObject {
    Q_OBJECT
public:
    Worker();
    void setModel(QStandardItemModel* model);

public slots:
    void addItems();

private:
    QStandardItemModel* mModel{ nullptr };
};

Worker.cpp

#include "Worker.h"

Worker::Worker()
{

}

void Worker::setModel(QStandardItemModel* model)
{
    mModel = model;
}

void Worker::addItems()
{
    for (;;) {
        mModel->appendRow(new QStandardItem("Item"));
        QThread::currentThread()->msleep(1000);
    }
}

ma​​in.cpp

#include <QApplication>
#include <QFrame>
#include <QHBoxLayout>
#include <QPushButton>
#include <QThread>
#include <QTreeView>
#include <QStandardItemModel>
#include "Worker.h"

int main(int argc, char* argv[])
{
    QApplication a(argc, argv);
    auto frame = new QFrame;
    frame->setLayout(new QHBoxLayout);
    auto view = new QTreeView;
    auto model = new QStandardItemModel;
    view->setModel(model);
    auto worker = new Worker;
    worker->setModel(model);
    auto thread = new QThread;
    worker->moveToThread(thread);
    thread->start();
    frame->layout()->addWidget(view);
    auto btnStart = new QPushButton("Start add items");
    QObject::connect(btnStart, &QPushButton::clicked, worker, &Worker::addItems);
    frame->layout()->addWidget(btnStart);
    frame->show();
    return a.exec();
}

【讨论】:

    猜你喜欢
    • 2019-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-05
    • 2012-09-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多