2014-03-29 70 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

相關問題