专栏首页24K纯开源C++模板类与Qt信号槽混用

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

一、正文

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

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

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做预处理。而项目当前使用的这套视频处理框架又大量使用了模板技术,改源码显然不大现实。那么就没有办法了吗?网上搜了一下就找到了一个解决办法。那就是实现一个普通的中间类,在这个类中定义信号槽。然后再让模板类继承这个中间类即可。所以我们实现一个中间类:

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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 选择QT作为Windows客户端开发框架

    当你的产品决定使用C++进行Windows客户端开发时,也许QT是非常适合您产品的C++开发框架,框架选型时不容错过。其跨平台、功能丰富、文档齐全,稳定、已广泛...

    gaigai
  • 初学Qt(一)

    如果是一个小白,那么该如何学习Qt呢?接下来我从自己的学习经历中总结一下,希望对初学Qt的同志能有一点儿帮助。

    用户5908113
  • C++面试题

    岗位职责: 1、参与需求分析、模块开发等相关工作; 2、在windows平台下进行C/C++应用程序设计、开发、测试; 3、参与软件系统或模块的联调,协助...

    ccf19881030
  • QT signal / slot mechanism

    QT 是一个跨平台的 C++ GUI 应用构架,它提供了丰富的窗口部件集,具有面向对象、易于扩展、真正的组件编程等特点,更为引人注目的是目前 Linux 上最...

    ke1th
  • 集成Qt Webkit 到cocos2d-x

    近期倒腾下客户端,想搞个cocos2d的工具。 之前的那个集成到Win32工具下的调试辅助工具是直接用的windows api。拓展起来巨麻烦。而且Windo...

    owent
  • 聊聊C、C++、Boost、Qt与嵌入式开发

    C语言大家都比较熟悉了,是属于底层编程语言了,计算机行业里有句话说“C生万物”!不得不说,C语言的出现,改变了计算机的编程语言世界。

    用户8662056
  • Qt 第二步 熟悉文件结构组成(二)

    目录导航: 《Qt 第一步 HelloWorld 的第一个程序》 《Qt 第二步 槽与信号(一) 实现点击按钮并弹窗》

    公众号 碧油鸡
  • Qt 第二步 槽与信号(一) 实现点击按钮并弹窗

    信号与槽是Qt中的核心,也是Qt的特有的。在Qt中信号与槽的关键字为slots、signals、emit。 具体信号与槽将会在下一节中详细说明,因为担心一些读...

    公众号 碧油鸡
  • Qt 第二步 槽与信号(一) 实现点击按钮并弹窗

    信号与槽是Qt中的核心,也是Qt的特有的。在Qt中信号与槽的关键字为slots、signals、emit。

    公众号 碧油鸡

扫码关注云+社区

领取腾讯云代金券