Bonjour,
Pour la conception d'une application d'affichage de données issues de trames réseaux, je souhaiterais faire quelque chose d'assez générique.
Je suis donc parti sur l'utilisation de templates et ai procédé de la sorte :
Une classe pour représenter des données de type traces :
Un template pour décoder/encoder les données :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 class QTraceData { public : quint8 m_type; QString m_date; QString m_time; QString m_file; quint32 m_line; QString m_msg; };
Une classe dérivée pour décoder/encoder les traces :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 template <typename T> class QDataDecoder { public : virtual ~QDataDecoder() {} virtual T* decode(bool&, const QByteArray&) const = 0; virtual bool encode(const T*, QByteArray&) const = 0; };
Un template pour représenter le modèle de données :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 class QTraceDecoder : public QDataDecoder<QTraceData> { public : virtual QTraceData* decode(bool&, const QByteArray&) const; virtual bool encode(const QTraceData*, QByteArray&) const; };
Une classe dérivée pour représenter le modèle de traces :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 template <typename T> class QDataTableModel : public QAbstractTableModel { public : QDataTableModel(QObject* parent = 0) : QAbstractTableModel(parent) {} virtual int rowCount(const QModelIndex&) const { return m_data.size(); } virtual bool insertRow(const T* data) { // insert data in m_data } protected : QList<const T*> m_data; };
Cette partie pour l'instant me plaisait bien, mais voilà, elle entraîne un manque de généricité au niveau du module ou de la façade censée être le point d'entrée pour la communication avec les autres modules.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 class QTraceTableModel : public QDataTableModel<QTraceData> { public : QTraceTableModel(QObject* parent = 0); virtual int columnCount(const QModelIndex&) const; virtual QVariant data(const QModelIndex&, int) const; QVariant headerData(int, Qt::Orientation, int) const; bool setData(const QModelIndex&, const QVariant&, int); };
J'ai, au départ, une classe pour la façade :
Ensuite, et c'est ici que ça se gâte
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 class QModelFacade : public Common::QFacade { public : QModelFacade() : Common::QFacade() {} public slots : virtual void interpretData(const QByteArray&) = 0; // appelée lors de la réception d'une trame réseau par le module Network };, comme je n'arrivais pas à implémenter de façon générique la méthode interpretData avec les templates QDataDecoder et QDataTableModel (car je dois leur définir un type précis), j'ai créé, à contre coeur^^, une classe dérivée pour manipuler QTraceDecoder et QTraceTableModel :
Au passage, je retrouve la même difficulté avec QTraceTableModelFacade, créée faute d'avoir trouvé le moyen de garder une classe générique QTableModelFacade.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 class QTraceModelFacade : public QIModelFacade { public : QTraceModelFacade(); ~QTraceModelFacade(); public slots : virtual void interpretData(const QByteArray&); public : QTraceTableModelFacade* m_tableModelFacade; private : QTraceDecoder* m_decoder; };
Ce manque de généricité entraîne, pour un changement de type de données, beaucoup de modifications à faire.. Encore devoir refaire une classe pour décoder ou une classe pour le modèle de ces nouvelles données d'accord, mais devoir recréer une classe façade ce n'est pas normal.
Je ne maîtrise surement pas assez bien les templates pour contourner cette difficulté et c'est pourquoi je me permets de faire appel à vos connaissances.
Merci![]()
Partager