2014-03-29 41 views
0

我有一个程序依赖于添加到文件夹中的文件。即使用户将MANY(> 200)文件添加到此文件夹,也不会注册任何文件。Qt:我应该在一个线程上运行QFileWatcher吗?

当收到来自QFileWatcher的信号时,我正在读取并创建一部分数据的图像,并且执行此操作可能需要几秒钟的时间。 QFileWatcher和处理信号的函数都驻留在同一个类中。我担心这个类有时可能会很忙,并可能导致QFileWatcher不注册某些文件。

我应该将QFileWatcher添加到线程以确保数据注册?

我在做什么截至目前

在main.cpp中:

... 
MainWindow w; 
w.setupFolderMonitoring(); 
... 

在mainwindow.h:

... 
public: 
    void setupFolderMonitoring(); 
    void detectFolderChanges(); 
private: 
    QString monitoredPath; 
    QFileSystemWatcher watcher; 
... 

在mainwindow.cpp:

... 
void MainWindow::setupFolderMonitoring() { 
    watcher.addPath(monitoredPath); 
    QObject::connect(&watcher, SIGNAL(directoryChanged(QString)), this, 
    SLOT(detectFolderChanges())); 
} 
void MainWindow::detectFolderChanges() { 
    qDebug() << "Dir was changed"; 
} 
... 
+0

文件监视功能由操作系统内核以及可能的系统范围的文件监视服务提供。所有这些都是异步工作的,并且您的应用程序不会因繁忙而失去任何事件 - API旨在处理这一问题。不过,您应该担心为您的用户提供流畅的用户界面感受。在Qt中,没有“丢失”信号的概念。直接连接的信号只是间接的函数调用,排队的槽调用放在事件循环中。没有什么会“失去”。 –

+0

谢谢你澄清这一点。围绕这些主题中的一些可能会很困难。 – Attaque

回答

2

一般来说,如果您的数据处理时间可能会超过一秒,那么您应该不会在主线程中执行此操作,以避免无响应的GUI。

此外,在Windows中处理文件夹监视时,我发现如果监视线程正忙于处理数据,Windows文件监视机制将开始删除事件。所以这是将数据处理转移到自己的线程的另一个很好的理由。

我以前采用的方法是创建一个数据处理QObject,将它“移动”到一个新线程(使用QObject::moveToThread(...)),并使用信号和插槽将它连接到文件系统监视器和GUI。

说实话,我没有使用Qt的文件系统监控,因为我需要比Qt提供的文件重命名事件更多的信息。所以我不得不直接使用Windows文件系统监控API。但我不认为Qt可以在处理大规模变化方面解决操作系统的限制。

+0

我会争论在GUI线程中做任何事情,在i5机器上阻塞超过50ms是不可接受的。在目前的大多数桌面硬件上,全屏幕blit的时间不到50ms,因此即使在使用小部件API时,也可以在另一个线程中进行全部渲染。使用C++ 11和Qt 5,即使不使用'QObject'工具,编写大量多线程代码也相当容易。 'QtConcurrent :: run'拯救:) –

+0

谢谢你回答我的另一个问题deGoot :)所以,如果我有另一个线程上的数据处理,并且主线程上的文件系统监视器应该没问题?如果我在detectFolderChanges()中添加一个dir迭代器,用QTimer模拟数据处理并添加200个文件,程序崩溃 - 这是我希望程序能够处理的场景。 – Attaque

+0

我很确定我以前处理过200多个文件。自从我运行这些测试已经有一段时间了。您可能不想为每次更改创建一个新线程(可能会有一些性能损失)。我创建了一个队列来跟踪更改,我的'detectFolderChanges'会将更改排入队列,并通知数据处理器可以处理更多更改。数据处理器然后将文件更改信息出队,根据需要处理它,并通知GUI处理完成。 – deGoot

相关问题