首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >QAbstractListModel和QList适配器

QAbstractListModel和QList适配器
EN

Stack Overflow用户
提问于 2012-01-17 21:30:20
回答 2查看 2.3K关注 0票数 5

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

当使用一般的添加、删除和多选功能将简单的std::vector<T>QList<T>包装到模型中时,这会生成相当多的重复代码。

这是QAbstractListModel应该使用的方式吗?还是有一些适配器类可以删除重复的代码(至少对于作为Qt一部分的容器)?

示例:我想将vector<ObjectA>vector<ObjectB>包装到一个模型中。insertRowsdeleteRowscolumnCount等的代码总是一样的,我想合并一下(使用一点元编程,甚至可以在tupledata上工作)。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-01-18 00:08:59

您必须在两个单独的类中执行此操作,因为Qt对c++的扩展(信号、插槽等)不要很好地使用模板。有关此问题的基本原理和解决方法,请访问:https://doc.qt.io/archives/qq/qq15-academic.html

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

1.执行Qt填充的抽象列表类

代码语言:javascript
复制
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.执行模板填充的抽象类

代码语言:javascript
复制
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.实际列表类

代码语言:javascript
复制
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. ...
};
票数 6
EN

Stack Overflow用户

发布于 2012-01-17 22:46:23

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

如果您有使用QList<T>std::vector<T>的重复代码,那么我建议您通过执行以下任一操作将两者转换为另一种:

代码语言:javascript
复制
QList<T> list = QList::fromVector(QVector::fromStdVector(vector));

或者用另一种方式。

代码语言:javascript
复制
std::vector<T> vector = qlist.toVector().toStdVector();

我会选择后者,但你可以任选一种。

根据您的其他评论,您可以采取以下两种操作方式:

路径1:

按如下方式实现objectAobjectB

代码语言:javascript
复制
class objectA : baseObject

代码语言:javascript
复制
class objectB : baseObject

其中,baseObject是:

代码语言:javascript
复制
struct baseObject
{
    virtual std::string toString() = 0;
};

转换成字符串可能比其他任何东西都更容易。

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

你必须考虑的一件事是,如果你的数据存储容器可以使数据表示变得通用,那么你所能做的是有限的,因为给出你视图的data()函数,元素必须返回QVariant,并且它受到构造它的限制。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8895458

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档