2014-01-15 38 views
1

我正在研究一个programm(notifyfs),它负责缓存目录条目并观察底层文件系统的变化。缓存存储在共享内存中,(gui)客户端可以非常轻松地使用缓存。使用QTreeView和QStandardItemModel的应用程序没有赶上

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

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

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

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

c。通过引用视图向服务器发送消息,并向其加载其内容的路径指示。这可能是一条路径,但如果可能的话,父项。 d)。服务器收到消息(进行一些检查),在目录上设置一个监视,并同步该目录。当目录尚未进入缓存时,这意味着它检测到的每个条目都存储在缓存中。在这样做的时候,它表示视图(共享内存中的数据)添加了一个条目,并将该事件存储在数组/队列中。

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

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

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

使用insertRow(row,list)调用来完成在某一行添加一行,其中row当然是行,list是项目的QList。

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

+0

你的问题太沉重。你可以简化它:“有时QTreeView不会更新,即使新项目被添加到模块中,如何解决它?”并提供最少的代码示例来重现您的问题。在大多数情况下,这些错误出现在不正确的模型实现之后。我可以添加一个代码示例,显示如何在从分离的线程扫描文件夹期间使用文件列表填充QTreeView。 –

+0

你的意思是太重?太多细节?我的问题有一些细节,因为我想在问题发生时提供信息,以及我已经做了什么来阻止我已经尝试过的建议。你的想法提出一个像“有时QTreeView不更新”这样的问题太短了。然后人们会自然而然地提出更多细节。 – user1388973

+1

@ user1388973:有时候一些自包含的代码比一千个词更好。 –

回答

0

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

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

感谢大家给予的建议,

燕姿苯教

相关问题