C++模板类与Qt信号槽混用

https://www.cnblogs.com/csuftzzk/p/qt_mix_with_template.html

一、正文

  目前正在做一个视频处理相关的项目。项目的技术栈是这样的,UI层采用Qt来实现基本的数据展示和交互,底层音视频采用的是一套基于FFmpeg的视频处理框架。这是一套类似Microsoft Media Foundation的处理框架,采用管道流进行架构,解复用、解码、复用、编码及用户自定义操作都采用Filter组件来实现,灵活度和可扩展性都比较好。(基本上常用音视频处理框架都采用了这一架构,如Microsoft Media FoundationDirectShow Filtergstreamer

  项目要求视频在处理的过程中,实时计算出当前的进度并展示在UI上,方便用户随时查看处理进度。想象中的处理方式是:负责Progress的Filter每一次计算进度的时候都发送一个信号给UI,方便更新进度条。于是ProgressFilter的实现大致如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

template<typename DataType>

class ProgressFilter : public ins::MediaFilter<DataType,DataType>, public  QObject{

    Q_OBJECT

public:

    ~ProgressFilter() = default;

 

    ProgressFilter(uint64_t totalFrames = 1) :

        mCurrentFrameIndex(0),

        mTotalFrames(totalFrames) {

 

    }

 

    bool Init(ins::MediaContext* ctx) {

        return this->next_filter_->Init(ctx);

    }

 

    bool Filter(ins::MediaContext* ctx, const DataType& data) { 

        double progress = std::min((double)(++mCurrentFrameIndex) / mTotalFrames, 0.99);

        emit progressChanged(progress);

        return this->next_filter_->Filter(ctx, data);

    }

 

    void Close(ins::MediaContext* ctx) {

        this->next_filter_->Close(ctx);

    }

 

    void Notify(ins::MediaContext* ctx, const ins::MediaNotify& notify) {

        if (notify.type == ins::kNotifyEOF) {

            double progress = std::min(std::ceil((double)mCurrentFrameIndex / mTotalFrames), 1.0);

            emit progressChanged(progress);

        }

        this->next_filter_->Notify(ctx, notify);

    }

signals:

    void progressChanged(double progress);

private:

    uint64_t mCurrentFrameIndex;

    uint64_t mTotalFrames;

};

  然而编译的时候却提示报错:

  错误提示已经很显然了,Q_OBJECT宏不支持C++模板类。Qt中一个类如果需要支持信号槽机制,那么必须要加一个Q_OBJECT做预处理。而项目当前使用的这套视频处理框架又大量使用了模板技术,改源码显然不大现实。那么就没有办法了吗?网上搜了一下就找到了一个解决办法。那就是实现一个普通的中间类,在这个类中定义信号槽。然后再让模板类继承这个中间类即可。所以我们实现一个中间类:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

class Proxy : public QObject {

    Q_OBJECT

 

public:

    explicit Proxy(QObject *parent = 0) : QObject(parent) {}

      

signals:

    void progressChanged(double progress);

};

 

template<typename DataType>

class ProgressFilter : public ins::MediaFilter<DataType,DataType>, public Proxy {

    public:

        ~ProgressFilter() = default;

    ......

     

}

  这样,我们的模板类就可以正常使用信号槽机制了。

二、参考链接

1. https://stackoverflow.com/questions/4397478/qt-templated-q-object-class

2. https://stackoverflow.com/questions/4238204/is-it-possible-to-mix-template-derived-c-classes-with-qts-q-object

作者:24K纯开源 
Email: zhangzhongke007@163.com 
出处:http://www.cnblogs.com/csuftzzk/ 
本文版权归24K纯开源和博客园共同拥有,欢迎转载,但未经作者同意必须保留此声明,且在文章明显位置给出原文链接,否则保留追究法律责任的权利。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值