QAbstractListModel e QList Adaptador
-
29-10-2019 - |
Pergunta
Meu aplicativo armazena alguns objetos de um tipo que herda
QAbstractListModel
os objetos.
Isso gera um monte de código duplicado quando quebra um simples
std::vector<T>
ou um QList<T>
no modelo geral, adicionar,
excluir e multi-funcionalidade de seleção.
É que a maneira de QAbstractListModel
é suposto para ser usado ou não
alguns placa de classe, que pode remover o código duplicado (pelo menos para
os recipientes que são parte do Qt)?
Exemplo:Eu quero moldar vector<ObjectA>
e vector<ObjectB>
em um modelo.O código para insertRows
, deleteRows
, columnCount
etc.é sempre vai ser o mesmo e eu gostaria de consolidar-se que (com um pouco de meta-programação, que poderia até trabalhar, com tuple
e data
).
Solução
Você precisará fazer isso em duas classes separadas, porque Qt extensions para c++ (SINAIS, SLOTS, etc.) não jogar bem com modelos.O raciocínio e a solução para isso pode ser encontrada em: http://doc.qt.digia.com/qq/qq15-academic.html
Aqui está um esboço de uma solução.(Este é baseado no código estamos usando em nossa aplicação, e que está funcionando bem.)
1.Resumo lista de classe que faz Qt coisas
class FooListModelQt : public QAbstractTableModel {
Q_OBJECT
public:
// Non-template methods, signals, slots, etc. can be used here. For example...
QSet<int> SelectedRows() const;
// ... etc. ...
signals:
void SelectionChanged();
// ... etc. ...
protected:
explicit FooListModelQt(QObject *parent = NULL);
virtual ~FooListModelQt() = 0;
// ... etc. ...
};
2.Classe abstrata que faz coisas modelo
template <typename T>
class FooListModel : public FooListModelQt {
public:
const T* at(int index) const { return items_.at(index); }
int count() const { return items_.count(); }
void Append(T *item);
// ... etc. ...
protected:
explicit FooListModel(QObject *parent = NULL);
virtual ~FooListModel();
private:
QList<T*> items_;
};
3.Lista real de classe
class BarListModel : public FooListModel<Bar> {
Q_OBJECT
public:
explicit BarListModel(QObject *parent = NULL);
int columnCount(const QModelIndex &parent) const;
QVariant data(const QModelIndex &index, int role) const;
// ... etc. ...
};
Outras dicas
Normalmente eu teria de implementar o meu próprio modelo de herdar de QAbstractItemModel
diretamente e fornecer a minha própria implementação para a apresentação de funções, tais como data()
para lidar com o armazenamento de dados recipiente eu dou o modelo.
Se você tiver a duplicação de código para a utilização de QList<T>
e std::vector<T>
então eu gostaria de sugerir a conversão de um para o outro, fazendo:
QList<T> list = QList::fromVector(QVector::fromStdVector(vector));
ou outra maneira.
std::vector<T> vector = qlist.toVector().toStdVector();
Eu faria o último, mas você pode escolher qualquer um.
Com base em seus comentários adicionais há 2 caminhos de ação que você pode tomar:
Caminho 1:
Implementar objectA
e objectB
como segue:
class objectA : baseObject
e
class objectB : baseObject
onde baseObject
é:
struct baseObject
{
virtual std::string toString() = 0;
};
Provavelmente mais fácil para converter a seqüência de caracteres, em seguida, mais nada.
Caminho 2 será, basicamente, envolvem dentro do modelo usando std::vector<boost::any>()
como o armazenamento de dados recipiente, desta forma, você pode implementar um modelo único de subclassificação QAbstractListModel
.
A única coisa que você tem que considerar que, se seus dados de armazenamento de recipiente que você pode provavelmente fazer comum a apresentação de dados que você está limitado no que você pode fazer, porque data()
função que irá dar a sua opinião, o elemento tem que voltar QVariant
e ele é limitado no que você pode construí-lo a partir.