在其他 comp 上使用 QTableView 缓慢滚动
Posted
技术标签:
【中文标题】在其他 comp 上使用 QTableView 缓慢滚动【英文标题】:Slow scrolling with QTableView on other comp 【发布时间】:2011-10-31 03:45:30 【问题描述】:我目前正在使用 Qt 和 C++ 开发一个数据库浏览应用程序。数据库在我们的内部网络中。 我正在使用 Qt 4.7.3 + qodbc 驱动程序在 Win7 32 位上工作和编译。 我的项目目标是让这些数据可供我们的 ppl 使用,即使他们正在旅行,在这种情况下使用 ***。 连接非常慢(我的意思是:非常慢)。
所以,我有一个 QTableView,我填充了 2k 个结果。我只需要一个win7支持,它在我们公司的计算机上运行良好,这些计算机在网络中。 但在某些计算机上,事情真的很慢,即在我的 QTableView 上滚动。它似乎只在使用 *** 时发生。我用来填充 QTableView 的方式只是做一个 setQuery() 所以我想知道执行查询后是否执行了一些网络内容?如果是这样,可能是什么问题? 我在 Google 和 Qt 文档中都找不到任何答案。
编辑:问题似乎直接来自 QSqlQuery。我已经实现了以下模型作为试验以避免无用的查询(是的,它又快又脏):
class SqlAsyncModel : public QSqlQueryModel
public:
explicit SqlAsyncModel(QObject *parent = 0) : QSqlQueryModel(parent)
SqlAsyncModel(QSqlQueryModelPrivate &dd, QObject *parent)
: QSqlQueryModel(dd, parent)
void queryChange() _currRow = 0; qu = this->query(); qu.last();
virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole)
int r = index.row(); int c = index.column();
if(!index.isValid() || role & ~Qt::DisplayRole || r < 0 || c < 0)
return QVariant();
while (_currRow < r)
if (!nextValue()) goto ret;
while (_currRow > r)
if (prevValue()) goto ret;
ret: return (qu.record().value(c));
// Returns value or QVariant() if invalid QSqlRecord
private:
inline bool nextValue() _currRow++; return qu.next();
inline bool prevValue() _currRow--; return qu.previous();
int _currRow;
QSqlQuery qu;
这仍然给了我同样的行为。 注意:我也使用:
while (mysqlAsyncModel->canFetchMore())
mySqlAsyncModel->fetchMore();
【问题讨论】:
尝试在有问题的机器上运行 Wireshark 并查看用户滚动时发送/接收的网络流量(如果有)。结果可能会提供信息。 感谢您的想法。这样做之后,我的 QTableView 似乎在每次滚动/出现窗口时都在刷新项目,这显然是问题的根源。似乎在 QTableView 中没有办法设置刷新计时器之类的东西。我去看看其他的小部件... 我认为 QTableView 类很好,但您可能需要替换为更适合您目的的不同 QAbstractTableModel 子类(而不是您现在可能正在使用的 vanilla QSqlQueryModel 对象)。这篇文章可能会感兴趣:blog.wysota.eu.org/index.php/2006/12/26/remote-models 这也可能有帮助:linuxjournal.com/article/9602 有趣的链接。它让我深入研究 MVC 架构,并且学到了很多我不知道的东西。但是,它似乎并不真正适合我的需求。我的查询默认从服务器检索 256 个结果(现在我使用的是 fetchMore())。我在 15 到 20 秒内得到所有结果(使用 fetchMore()),这对我的客户来说是可以接受的。但是在滚动时,会执行额外的查询,这才是真正的问题。另一个问题是由于这种行为(实时更新),关闭与数据库的连接会导致清除模型。 【参考方案1】:所以问题来自 QODBCResult 行为。 我下载了 Qt 的 Sources,并编辑了 odbc 驱动程序。 对于那些对此感兴趣的人,您需要更改 QODBCResult::data(int) 和至少 QODBCResult::fetch(int) 的行为(如果您真的想要一些干净的东西,可能还有 QODBCResult::fetchprevious/next/last/first)功能。
我个人添加了一个 QList 缓冲区,用于在请求行时存储我的行。它与 Qt 的行为几乎相同(因为它不缓存所有内容,只缓存请求的行)。我的应用程序占用 38-40 Mbs 内存,用于 22k 行/55 列文本并在缓存中浮动。
【讨论】:
那么为什么现在还没有解决这个问题?在我看来,现在应该已经实现了请求行的简单缓存,因为这只是提供的人工制品的质量问题。例如,我有一个简单的查询加载 50 行乘 5 列,并且链接到该模型的每个视图都像地狱一样滞后。我应该实现自己的模型并在本地缓存数据,但是对于 50 行,为什么我不能使用标准模型并完成它,并且至少知道我的用户不会抱怨只有 50 行的性能低下. 我想这是你必须在 Qt 论坛/邮件列表中提出的问题;) 似乎观点是这里的问题。通过在模型中插入一些调试打印,我可以看到对data
成员函数的大量调用,每次视图与所有索引交互时,不仅仅是可见索引。主要是检查各种角色的新数据。在快速数据结构中本地缓存数据可以缓解延迟,但函数调用仍然像以前一样频繁,它们只需要更少的返回时间。应在视图内部进行进一步改进以实现虚拟化。以上是关于在其他 comp 上使用 QTableView 缓慢滚动的主要内容,如果未能解决你的问题,请参考以下文章
QSqlTableModel/ QTableView 解析查询到xml