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)
{
    // 加载显示一张破图?
}

猜你喜欢

转载自blog.csdn.net/e5max/article/details/79353600
今日推荐