Qt QAbstractListModel和QList适配器

Qt QAbstractListModel和QList适配器,qt,qabstractitemmodel,qabstractlistmodel,Qt,Qabstractitemmodel,Qabstractlistmodel,我的应用程序存储一些继承自的类型的对象 QAbstractListModel对象 当包装一个简单的 std::vector或aQList添加到模型中, 删除和多选功能 这是应该使用的方式还是存在的方式 某些适配器类可以删除重复的代码(至少对于 属于Qt的容器) 示例:我想将vector和vector包装到一个模型中。insertRows、deleteRows、columnCount等的代码总是一样的,我想巩固这一点(使用一些元编程,甚至可以处理元组和数据).通常,我会直接实现从qabstract

我的应用程序存储一些继承自的类型的对象
QAbstractListModel
对象

当包装一个简单的
std::vector
或a
QList
添加到模型中, 删除和多选功能

这是应该使用的方式还是存在的方式 某些适配器类可以删除重复的代码(至少对于 属于Qt的容器)


示例:我想将
vector
vector
包装到一个模型中。
insertRows
deleteRows
columnCount
等的代码总是一样的,我想巩固这一点(使用一些元编程,甚至可以处理
元组和
数据
).

通常,我会直接实现从
qabstractemmodel
继承的我自己的模型,并为表示函数(如
data()
)提供我自己的实现,以处理我给模型的数据存储容器

如果您在使用
QList
std::vector
时有代码重复,那么我建议通过执行以下操作之一将一个转换为另一个:

QList<T> list = QList::fromVector(QVector::fromStdVector(vector));

其中
baseObject
是:

struct baseObject
{
    virtual std::string toString() = 0;
};
转换成字符串可能比其他任何东西都容易

路径2基本上涉及模型内部,使用
std::vector()
作为数据存储容器,这样您就可以实现单个模型子类化
QAbstractListModel


<>你必须考虑的是,如果你的数据存储容器可能会使数据呈现变得常见,那么你就只能在你可以做的事情上受到限制,因为<代码>数据()函数将给出视图,元素必须返回<代码> qSuffs。它的限制是从你可以构造的。

你必须在两个单独的类中这样做,因为Qt对C++的扩展(信号、时隙等)不能很好地使用模板。有关这方面的基本原理和解决方法,请访问:

下面是解决方案的大致轮廓。(这是基于我们在应用程序中使用的代码,并且运行良好。)

1。执行Qt操作的抽象列表类

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. ...

};
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_;
};
class-dublistmodelqt:public-QAbstractTableModel{
Q_对象
公众:
//这里可以使用非模板方法、信号、插槽等。例如。。。
QSet SelectedRows()常量;
//……等等。。。
信号:
void SelectionChanged();
//……等等。。。
受保护的:
显式傻瓜模型QT(QObject*parent=NULL);
virtual~foulistmodelqt()=0;
//……等等。。。
};
2。完成模板内容的抽象类

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. ...

};
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_;
};
模板
类傻瓜模型:公共傻瓜模型Qt{
公众:
const T*at(int index)const{return items_u.at(index);}
int count()常量{return items..count();}
无效追加(T*项);
//……等等。。。
受保护的:
显式模型(QObject*parent=NULL);
虚拟模型();
私人:
QList项目;
};
3。实际列表类

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. ...
};
class BarListModel:公共模型{
Q_对象
公众:
显式BarListModel(QObject*parent=NULL);
int columnCount(常量QModelIndex&parent)常量;
QVariant数据(常量QModelIndex&index,int角色)常量;
//……等等。。。
};

你是指
QAbstractListModel
还是
qabstractemodel
?@Karlson的确,ModelView框架中大量相似的名称让我感到困惑。我将保留标签
abstractitemmodel
标签,因为它似乎是框架的主标签。关键是实现boiler板的基类必须是模板。我稍微润色了一下我的问题,以便更好地反映我的问题。因此,如果我跳过
Q_对象
macro
moc
,我总是会忽略这个类,让我继续我的模板业务吗?(这篇文章只是一篇道歉的文章,没有给出去掉核心语言特性的理由。特别是在信号和插槽的实现没有施加这些约束的情况下。)这将是我的假设,是的。如果您不使用任何需要Q_对象的东西(信号、插槽、转换等),那么您应该可以。我在这方面已经浪费了几个小时,因此建议:如果您要将最终的模型对象公开给QML/声明性GUI,请确保特定模型的确切类用Q_对象标记。它本身必须用它来标记,它不是从base“继承”的。参见Dave示例中的BarListModel?有一个Q_对象重复出现。此外,还需要qmlRegisterType。这意味着您的最终类不能是模板,它必须是一个普通类,如BarListModel。
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. ...
};