Qt用線程渲染圖片(UI)

class TNImageLoadThread: public QThread
{
    Q_OBJECT

public:
    explicit TNImageLoadThread(const QString &filename, const QSize &targetSize, QObject *parent = Q_NULLPTR);

signals:
    void loadFailed(const QString &filename);
    void loadFinished(const QString &filename, const QImage &bigImage);

protected:
    virtual void run();

private:
    const QString m_fileName;
    const QSize m_targetSize;
    QImage m_targetImage;

    QMutex m_mutex;
};

實現文件:

TNImageLoadThread::TNImageLoadThread(const QString &filename, const QSize &targetSize, QObject *parent) :
    QThread(parent), m_fileName(filename), m_targetSize(targetSize)
{

}

void TNImageLoadThread::run()
{
    QMutexLocker mutexLocker(&m_mutex);
    m_targetImage = QImage(m_fileName).scaled(m_targetSize);
    if (m_targetImage.isNull())
    {
        emit loadFailed(m_fileName);
    }
    else
    {
        emit loadFinished(m_fileName, m_targetImage);
    }
}

調用端代碼,可以使用fileName作爲ID區分不同的線程返回了指定文件的結果。

QMap<QString, QImage> m_fileNameToImage;
QMap<QString, ImageToolButton*> m_fileNameToButton;

使用信號-槽連接來更新UI控件圖片:

        m_fileNameToButton[fileName] = imageButton;
        QThread *thread = new TNImageLoadThread(fileName, IconSize, this);
        connect(thread, SIGNAL(loadFinished(const QString&, const QImage&)), this, SLOT(addThumbnail(const QString&, const QImage&)));
        connect(thread, SIGNAL(loadFailed(const QString&)), this, SLOT(showError(const QString&)));
        thread->start();

槽函數實現:

void XXXX::addThumbnail(const QString &fileName, const QImage &buttonImage)
{
    if (m_fileNameToImage.contains(fileName) && m_fileNameToButton.contains(fileName))
    {
        m_fileNameToImage[fileName] = buttonImage;
        m_fileNameToButton[fileName]->setIcon(QIcon(QPixmap::fromImage(m_fileNameToImage[fileName])));
    }
}

void XXXX::showError(const QString &fileName)
{
    // 加載顯示一張破圖?
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章