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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM