关于QT的一些记录及源码(QThread&OpenGL)

这篇博客分享了如何在QT中利用QThread进行多线程操作,并提供了读取FEKO .mesh模型的源码,特别适合处理基于OpenGL的图形渲染和立体模型数据。
摘要由CSDN通过智能技术生成

//首先,如果大家大家需要用到OPENGL,可以使用QT,网上有个GLWidget的教程做得很不错

今天先是把QT多线程的代码粘上来,然后把读取立体模型的源码发一下(适用于FEKO的.mesh模型)

//让QT把控制台显示出来,请在pro文件中加入CONFIG   += console

//transactionthread.h

#ifndef TRANSACTIONTHREAD_H
#define TRANSACTIONTHREAD_H

#include <QImage>
#include <QMutex>
#include <QQueue>
#include <QThread>
#include <QWaitCondition>

class Transaction//用户可以对图片进行相关操作的抽象基类
{
public:
    virtual ~Transaction() { }//需要通过一个Transaction指针来删除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();//run()函数在线程内执行,其他函数(包括构造函数和析构函数均是在主线程中被调用)

private:
    QImage currentImage;//保存事务应用的图片
    QQueue<Transaction *> transactions;//待处理的事务队列
    QWaitCondition transactionAdded;//一个等待条件,当有新的事务添加到队列的时候,用于触发线程
    QMutex mutex;//防止currentImage和transactions成员变量并发访问
};

#endif

//transactionthread.cpp
#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()
{
    //清空事务队列,并给队列添加一个专门用的EndTransaction标记,然后在基类析构函数被隐式调用之前,触发线程并使用
    //QThread::wait函数等待它结束为止
    {
        QMutexLocker locker(&mutex);
        while (!transactions.isEmpty())
            delete transactions.dequeue();
        transactions.enqueue(EndTransaction);
        transactionAdded.wakeOne();
    }
    //调用wait之前,QMutexlocker的析构函数会在其内部程序模块的末尾解锁互斥量,调用wait函数之前解锁互斥量非常重要
    //否则程序以死锁的情况结束,次线程永远等待互斥量被解锁,而主线程则在进一步执行之前保持互斥量并等待次线程执行结束

    wait();
}

void TransactionThread::addTransaction(Transaction *transact)
{
    //所有对transaction成员变量的访问都由一个互斥量保护起来,因为主线程或许会在次线程遍历所有事务的同时通过addTransaction
    //修改这些成员变量(重要)
    QMutexLocker locker(&mutex);
    transactions.enqueue(transact);
    //把事务添加到事务队列,如果事务线程没有运行,就触发它
    transactionAdded.wakeOne();
}

void TransactionThr
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值