Alex Rivera | Logout

Architecture for Qt SIGNAL with subclass-specific, templated argument type

Asked 2010-03-15T21:58:33.150
9

I am developing a scientific data acquisition application using Qt. Since I'm not a deep expert in Qt, I'd like some architecture advise from the community on the following problem:

The application supports several hardware acquisition interfaces but I would like to provide an common API on top of those interfaces. Each interface has a sample data type and a units for its data. So I'm representing a vector of samples from each device as a std::vector of Boost.Units quantities (i.e. std::vector<boost::units::quantity<unit,sample_type> >). I'd like to use a multi-cast style architecture, where each data source broadcasts newly received data to 1 or more interested parties. Qt's Signal/Slot mechanism is an obvious fit for this style. So, I'd like each data source to emit a signal like

typedef std::vector<boost::units::quantity<unit,sample_type> > SampleVector
signals:
    void samplesAcquired(SampleVector sampleVector);

for the unit and sample_type appropriate for that device. Since tempalted QObject subclasses aren't supported by the meta-object compiler, there doesn't seem to be a way to have a (tempalted) base class for all data sources which defines the samplesAcquired Signal. In other words, the following won't work:

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);
};

The best option I've been able to come up with is a two-layered approach:

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 n
Edit
Report

1 Answer

1

One simplification to your two-layered approach would be to have the QObject class as a non-templated base for the class template i.e. something like

class DataSourceBase : public QObject {
    Q_OBJECT
    ...
    signals:
      void samplesAcquired(TimeStamp ts, unsigned long nsamples);
};

template<T,U> //sample type and units
class DataSource : public DataSourceBase {
    public:
        typedef std::vector<boost::units::quantity<U,T> > SampleVector
        virtual shared_ptr<SampleVector> acquiredData(TimeStamp ts, unsigned long nsamples);
};

Note that the drawback to this approach is that since you cannot use the Q_OBJECT macro in the class template there is no information about it in Qt's meta-object system.

answered 2010-03-31T23:41:38.443

Your Answer