如何在运行时使用QThread将QWidget添加到布局中



我使用的是Qt5.0.1与Visual Studio 2010集成,

我使用ffmpeg渲染视频文件中的视频帧,Qt作为QImage,实际上我需要在运行时使用QThread显示渲染的视频帧。

我是Qt的新手,请提供一些建议。

任何片段都会有所帮助。

我不熟悉带qt的VC++。。但是使用心轴brot示例

和财富线程示例在此处输入链接描述

使用信号来发射视频帧阵列或QImage。

还有这个代码片段

#include <QImage>
#include <QMutex>
#include <QQueue>
#include <QThread>
#include <QWaitCondition>
class Transaction
{
public:
    virtual ~Transaction() { }
    virtual QImage apply(const QImage &image) = 0;
    virtual QString message() = 0;
};
class FlipTransaction : public Transaction
{
public:
    FlipTransaction(Qt::Orientation orientation);
    QImage apply(const QImage &image);
    QString message();
private:
    Qt::Orientation orientation;
};
class ResizeTransaction : public Transaction
{
public:
    ResizeTransaction(const QSize &size);
    QImage apply(const QImage &image);
    QString message();
private:
    QSize size;
};
class ConvertDepthTransaction : public Transaction
{
public:
    ConvertDepthTransaction(int depth);
    QImage apply(const QImage &image);
    QString message();
private:
    int depth;
};
class TransactionThread : public QThread
{
    Q_OBJECT
public:
    TransactionThread();
    ~TransactionThread();
    void addTransaction(Transaction *transact);
    void setImage(const QImage &image);
    QImage image();
signals:
    void transactionStarted(const QString &message);
    void allTransactionsDone();
protected:
    void run();
private:
    QImage currentImage;
    QQueue<Transaction *> transactions;
    QWaitCondition transactionAdded;
    QMutex mutex;
};

#include <QtGui>
#include "transactionthread.h"
Transaction * const EndTransaction = 0;
FlipTransaction::FlipTransaction(Qt::Orientation orientation)
{
    this->orientation = orientation;
}
QImage FlipTransaction::apply(const QImage &image)
{
    return image.mirrored(orientation == Qt::Horizontal,
                          orientation == Qt::Vertical);
}
QString FlipTransaction::message()
{
    if (orientation == Qt::Horizontal) {
        return QObject::tr("Flipping image horizontally...");
    } else {
        return QObject::tr("Flipping image vertically...");
    }
}
ResizeTransaction::ResizeTransaction(const QSize &size)
{
    this->size = size;
}
QString ResizeTransaction::message()
{
    return QObject::tr("Resizing image...");
}
QImage ResizeTransaction::apply(const QImage &image)
{
    return image.scaled(size, Qt::IgnoreAspectRatio,
                        Qt::SmoothTransformation);
}
ConvertDepthTransaction::ConvertDepthTransaction(int depth)
{
    this->depth = depth;
}
QImage ConvertDepthTransaction::apply(const QImage &image)
{
    QImage::Format format;
    switch (depth) {
    case 1:
        format = QImage::Format_Mono;
        break;
    case 8:
        format = QImage::Format_Indexed8;
        break;
    case 24:
    default:
        format = QImage::Format_RGB32;
    }
    return image.convertToFormat(format);
}
QString ConvertDepthTransaction::message()
{
    return QObject::tr("Converting image depth...");
}
TransactionThread::TransactionThread()
{
    start();
}
TransactionThread::~TransactionThread()
{
    {
        QMutexLocker locker(&mutex);
        while (!transactions.isEmpty())
            delete transactions.dequeue();
        transactions.enqueue(EndTransaction);
        transactionAdded.wakeOne();
    }
    wait();
}
void TransactionThread::addTransaction(Transaction *transact)
{
    QMutexLocker locker(&mutex);
    transactions.enqueue(transact);
    transactionAdded.wakeOne();
}
void TransactionThread::run()
{
    Transaction *transact = 0;
    QImage oldImage;
    forever {
        {
            QMutexLocker locker(&mutex);
            if (transactions.isEmpty())
                transactionAdded.wait(&mutex);
            transact = transactions.dequeue();
            if (transact == EndTransaction)
                break;
            oldImage = currentImage;
        }
        emit transactionStarted(transact->message());
        QImage newImage = transact->apply(oldImage);
        delete transact;
        {
            QMutexLocker locker(&mutex);
            currentImage = newImage;
            if (transactions.isEmpty())
                emit allTransactionsDone();
        }
    }
}
void TransactionThread::setImage(const QImage &image)
{
    QMutexLocker locker(&mutex);
    currentImage = image;
}
QImage TransactionThread::image()
{
    QMutexLocker locker(&mutex);
    return currentImage;
}

最新更新