使用QTreeView和QStandardItemModel的应用程序无法赶上

时间:2014-01-15 12:12:58

标签: qt shared-memory qtreeview qstandarditemmodel

我正在开发一个programm(notifyfs),它负责缓存目录条目并监视底层文件系统的变化。缓存存储在共享内存中,(gui)客户端可以非常容易地使用缓存。

服务器(notifyfs)和客户端之间的通信可以通过共享互斥锁和条件变量来使用套接字或共享内存自身。

当客户想要加载目录时,它会执行以下操作:

一个。选择一个“视图”,它是共享内存中的数据结构,由共享的互斥锁,条件变量和小队列(数组)组成,用于与客户端通信添加/删除/更改事件。

湾客户端使用已在共享内存中找到的内容填充他/她的模型

℃。通过对视图的引用向服务器发送消息,并指示要加载其内容的路径。这可能是一条路径,但如果可能的话是父条目。

d。服务器接收消息(进行一些检查),在目录上设置监视,并同步目录。当目录尚未进入缓存时,这意味着它检测到的每个条目都存储在缓存中。在执行此操作时,它会向视图(共享内存中的数据)发出一个条目,并添加一个条目,并将此事件存储在数组/队列中。

即gui客户端有一个特殊的线程在共享内存中持续观察这个视图,以便使用pthread_cond_wait调用进行更改。该线程是一个特殊的io线程,可以发送三个信号:添加条目,删除条目和更改条目。它从数组队列中读取的正确参数:对条目的引用以及操作的内容。这三个信号连接到我模型中的三个插槽,这是基于QStandardItemModel。

这完美无缺。它非常快。测试时我有很多调试输出。删除这些以测试它没有这个额外的慢速io,看起来QTreeView无法赶上变化。当加载一个目录时,它加载了三分之二的目录,当加载另一个目录时,它会越来越少。

我使用Qt :: QueuedConnection将来自特殊线程的不同信号连接到模型。

使用insertRow(row,list)调用在某行中添加行,其中row当然是行,而list是项的QList。

我一直在寻找这个问题已经有一段时间了,并且看到所有的变化都是由特殊的io线程检测到的,并且信号是由模型接收的。仅以某种方式不接收到QTreeView的信号。我一直在想,我是否必须将模型信号和树视图的接收槽之间的通信设置为“Qt :: QueuedConnection”?也许别的什么?

1 个答案:

答案 0 :(得分:0)

反应中建议将模型放在一个特殊的线程中。这很诱人,但不是解决这个问题的正确方法。模型和视图应该在同一个线程中。

我在通过特殊的io线程为模型提供数据时尽可能地解决了这个问题。我将一些填充模型的函数移动到这个特殊的io,并使用标准调用来插入或删除一行。这很有用。

感谢大家提出建议,

Stef Bon