Bar*_*ark 9 c++ templates qt4 signals-slots
我正在使用Qt开发一个科学数据采集应用程序.由于我不是Qt的深度专家,我想从社区建议一些关于以下问题的建筑:
该应用程序支持多个硬件采集接口,但我想在这些接口之上提供通用API.每个接口都有一个样本数据类型和一个数据单位.所以我将每个设备的样本矢量表示std::vector为Boost.Units数量(即std::vector<boost::units::quantity<unit,sample_type> >).我想使用多播式架构,其中每个数据源将新接收的数据广播给一个或多个感兴趣的各方.Qt的信号/插槽机制非常适合这种风格.所以,我希望每个数据源发出一个信号
typedef std::vector<boost::units::quantity<unit,sample_type> > SampleVector
signals:
void samplesAcquired(SampleVector sampleVector);
Run Code Online (Sandbox Code Playgroud)
适用于该设备的unit和sample_type.由于QObject元对象编译器不支持tempalted 子类,因此似乎没有办法为定义samplesAcquiredSignal的所有数据源都有一个(tempalted)基类.换句话说,下面将不工作:
template<T,U> //sample type and units
class DataSource : public QObject {
Q_OBJECT
...
public:
typedef std::vector<boost::units::quantity<U,T> > SampleVector
signals:
void samplesAcquired(SampleVector sampleVector);
};
Run Code Online (Sandbox Code Playgroud)
我能够提出的最佳选择是双层方法:
template<T,U> //sample type and units
class IAcquiredSamples {
public:
typedef std::vector<boost::units::quantity<U,T> > SampleVector
virtual shared_ptr<SampleVector> acquiredData(TimeStamp ts, unsigned long nsamples);
};
class DataSource : public QObject {
...
signals:
void samplesAcquired(TimeStamp ts, unsigned long nsamples);
};
Run Code Online (Sandbox Code Playgroud)
该samplesAcquired信号现在给样本的时间戳和数量进行收购和客户端必须使用IAcquiredSamplesAPI来检索这些样品.显然,数据源必须是DataSource和IAcquiredSamples.
这种方法的缺点似乎是API中的简单性损失......如果客户端可以在连接的Slot中获取采集的样本,那将会更好.能够使用Qt的排队连接也会使线程问题更容易,而不必acquiredData在每个子类中的方法中管理它们.
另一种可能性是使用一个QVariant参数.这必然要求子类使用Q_REGISTER_METATYPE/ 来注册它们的特定样本向量类型qRegisterMetaType.没什么大不了的.但是,基类的客户端将无法知道QVariant值类型的类型,除非标签结构也与信号一起传递.我认为这个解决方案至少与上面的解决方案一样复杂,因为它强制抽象基类API的客户端处理类型系统的一些更加粗糙的方面.
那么,有没有办法实现模板化信号参数?有没有比我提出的更好的架构?
小智 2
有 QVariant 类型 - 您可以在其上创建自定义子类型
并将其用作信号中的参数(如果我理解您的权利,这就是您想要的)
http://doc.trolltech.com/qq/qq14-metatypes .html#customtypesinqvariant