2014-10-28 332 views
0

我是Qt中的新手,今天我一直在嘗試使我的應用程序適應QFuture,以便在主線程中同時運行一些任務。Qt:必須調用對非靜態成員函數的引用

我有一種方法,它可以改變QImage的飽和度值,該值返回一個QPixmap對象以便繪製到我的QGraphicsView。這一切都運行良好,沒有使用線程,但顯然它在主線程上非常密集,所以我想把它移走。

我看了Qt的有關線程幾篇文章,發現V5支持concurrent run functionality,這聽起來非常適合我的使用情況下,我想我只能夠派遣我的功能集成到一個新的線程,如下面的代碼片段:

void MainWindow::on_slideSaturation_valueChanged(int value) 
{ 
    QFuture<QPixmap> future = QtConcurrent::run(slider->modifySaturation, value, image); 
    future.waitForFinished(); 
    image = future.result(); 
    renderImageToCanvas(); 
    modified = true; 
} 

但是,我收到錯誤reference to non-static member function must be called。 這個錯誤是從我的Sliders類中調用的,我知道我沒有將該方法聲明爲靜態方法,但是當我這樣做時會導致整個堆錯誤 - 是否有任何方法可以將此方法傳遞給沒有它的併發調用被宣佈爲靜態?

Sliders.h

class Sliders 
{  
public: 
    Sliders(); 

    enum Member { RED, GREEN, BLUE, BRIGHTNESS, CONTRAST, HUE, SATURATION, LIGHTNESS }; 

    QPixmap modifySaturation(int, QPixmap); 
    void setMember(enum Member, int); 
    int getMember(enum Member); 

private: 
    int m_redValue; 
    int m_greenValue; 
    int m_blueValue; 
    int m_brightnessValue; 
    int m_contrastValue; 
    int m_hueValue; 
    int m_saturationValue; 
    int m_lightnessValue; 
}; 
+1

在主線程中使用'QPixmap'不安全。改爲使用'QImage'。 – thuga 2014-10-28 14:22:42

+0

你能否提出一個更好的方式來構建我的應用程序? – Alex 2014-10-28 14:27:47

回答

1

你應該叫QtConcurrent::run這樣的:

QFuture<QPixmap> future = QtConcurrent::run(slider, 
              &Sliders::modifySaturation, 
              value, image); 

但我認爲你正在使用它錯了反正。您假設在主線程中執行的on_slideSaturation_valueChanged插槽將被阻止,直到future.waitForFinished()返回。

+0

感謝漢克,關於如何改進這一點的任何建議?正如我所說我是Qt新手,發現整個體驗既有趣又令人困惑!謝謝。 – Alex 2014-10-28 13:24:49

+2

@Alex在您的場景中,我將使用完成任務時發出信號的工作對象。使用['QObject :: moveToThread'](http://qt-project.org/doc/qt-5/qobject.html#moveToThread)將此工作對象移動到新線程。使用該信號將'QImage'對象發送到主線程。然後使用這個'QImage'對象來更新你的GUI。 – thuga 2014-10-28 14:27:58

+0

謝謝你thuga,我會做更多的doc閱讀,並有另一個使用信號和插槽 – Alex 2014-10-28 14:28:43

相關問題