基类 'QAbstractListModel' 具有私有复制构造函数
Posted
技术标签:
【中文标题】基类 \'QAbstractListModel\' 具有私有复制构造函数【英文标题】:base class 'QAbstractListModel' has private copy constructor基类 'QAbstractListModel' 具有私有复制构造函数 【发布时间】:2014-03-03 22:51:21 【问题描述】:我有一个 QT QML 项目。 (还很小)
我首先在我的UScenario
模型上绑定一个列表视图,通过子类化QAbstractListModel
并且它工作得很好。
现在,每个UScenario
都有一个UTask
列表,其中也有一个UCondition
列表(因此,Utask
也是QAbstractListModel
的子类)。但是随后,QT Creator 给了我一个错误:
Core/Tasks/utask.h:6: erreur : base class 'QAbstractListModel' has private copy constructor
class UTask: public QAbstractListModel
^
所以我不确定我的问题出在哪里。我尝试阅读有关 QAbstractListModel
与 QAbstractItemModel
的文档,但我不知道。
我还尝试查看我是否曾经以错误的方式构造了UTask
;我认为不会。
// USCENARIO.h
#ifndef USCENARIO_H
#define USCENARIO_H
#include <QAbstractListModel>
#include "../Tasks/utask.h"
class UScenario : public QAbstractListModel
Q_OBJECT
public slots:
void cppSlot() // Used to test the insertion from UI
this->addTask(UTask());
public:
enum TaskRoles
IdRole = Qt::UserRole + 1
;
UScenario(QObject *parent = 0);
private:
QList<UTask> m_tasks;
public:
void addTask(const UTask &task);
virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
virtual QVariant data(const QModelIndex &index, int role) const;
virtual QHash<int, QByteArray> roleNames() const;
;
#endif // USCENARIO_H
// USCENARIO.CPP
#include "uscenario.h"
UScenario::UScenario(QObject *parent)
: QAbstractListModel(parent)
void UScenario::addTask(const UTask &task)
beginInsertRows(QModelIndex(), rowCount(), rowCount());
m_tasks.append(task);
endInsertRows();
int UScenario::rowCount(const QModelIndex & parent) const
return m_tasks.count();
QVariant UScenario::data(const QModelIndex & index, int role) const
if (index.row() < 0 || index.row() >= m_tasks.count())
return QVariant();
const UTask &task = m_tasks[index.row()];
if (role == IdRole)
return task.id();
return QVariant();
QHash<int, QByteArray> UScenario::roleNames() const
QHash<int, QByteArray> roles;
roles[IdRole] = "id";
return roles;
// UTASK.H
#ifndef UTASK_H
#define UTASK_H
#include <QAbstractListModel>
#include "../Conditions/ucondition.h"
class UTask: public QAbstractListModel
Q_OBJECT
public:
enum TaskRoles
typeRole = Qt::UserRole + 1
;
UTask(QObject *parent = 0);//:m_id(0)
int id() constreturn m_id;
private:
int m_id;
QList<UCondition> m_conditions;
// QAbstractItemModel interface
public:
void addCondition(const UCondition &cond);
virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
virtual QVariant data(const QModelIndex &index, int role) const;
virtual QHash<int, QByteArray> roleNames() const;
;
#endif // UTASK_H
// UTASK.cpp
#include "utask.h"
UTask::UTask(QObject *parent):
QAbstractListModel(parent), m_id(0)
void UTask::addCondition(const UCondition &cond)
beginInsertRows(QModelIndex(), rowCount(), rowCount());
m_conditions.append(cond);
endInsertRows();
int UTask::rowCount(const QModelIndex &parent) const
return m_conditions.count();
QVariant UTask::data(const QModelIndex &index, int role) const
if (index.row() < 0 || index.row() >= m_conditions.count())
return QVariant();
const UCondition &cond = m_conditions[index.row()];
if (role == typeRole)
return cond.type();
return QVariant();
QHash<int, QByteArray> UTask::roleNames() const
QHash<int, QByteArray> roles;
roles[typeRole] = "type";
return roles;
// MAIN
#include <QtGui/QGuiApplication>
#include "qtquick2applicationviewer.h"
#include <qqmlengine.h>
#include <qqmlcontext.h>
#include <qqml.h>
#include <QtQuick/qquickitem.h>
#include <QtQuick/qquickview.h>
#include "../uCtrlCore/Scenario/uscenario.h"
int main(int argc, char *argv[])
QGuiApplication app(argc, argv);
UScenario scenarioModel;
scenarioModel.addTask(UTask());
scenarioModel.addTask(UTask());
scenarioModel.addTask(UTask());
QtQuick2ApplicationViewer viewer;
QQmlContext *ctxt = viewer.rootContext();
ctxt->setContextProperty("myScenarioModel", &scenarioModel);
viewer.setMainQmlFile(QStringLiteral("qml/uCtrlDesktopQml/main.qml"));
QObject *item = viewer.rootObject()->findChild<QObject*>("btn");
QObject::connect(item, SIGNAL(qmlSignal()), &scenarioModel, SLOT(cppSlot()));
viewer.showExpanded();
return app.exec();
【问题讨论】:
【参考方案1】:问题在于如何将 UTask
对象存储在 UScenario
类中
QList<UTask> m_tasks
简单来说,当您调用m_tasks.append
时,它试图通过默认复制构造函数复制源UTask
对象来在QList
中分配一个新的UTask
对象。对于QAbstractListModel
,它是私有的。这就是您遇到错误的原因。
一个简单的解决方案是将存储类型更改为UTask
指针列表,QList< UTask* >
以及支持代码以在您的UScenario
对象被销毁时正确释放内存。
例如,这里有一些但不是全部的更改,但应该为您指明正确的方向。只需确保首先将m_tasks
更改为QList< UTask* >
:
int main(int argc, char *argv[])
...
UScenario scenarioModel;
scenarioModel.addTask( new UTask() );
scenarioModel.addTask( new UTask() );
scenarioModel.addTask( new UTask() );
...
return app.exec();
void UScenario::cppSlot()
// Used to test the insertion from UI
this->addTask( new UTask() );
// Change the signature to take a pointer
void UScenario::addTask( UTask* task )
beginInsertRows(QModelIndex(), rowCount(), rowCount());
m_tasks.append(task);
endInsertRows();
// Make sure you define a destructor for UScenario
UScenario::~UScenario()
QList< UTask* >::iterator task = m_tasks.begin();
while( m_tasks.end() != task )
// Release the memory associated with the task.
delete (*task);
++task;
m_tasks.clear();
【讨论】:
以上是关于基类 'QAbstractListModel' 具有私有复制构造函数的主要内容,如果未能解决你的问题,请参考以下文章
QMetaProperty::read: 无法处理未注册的数据类型 'QAbstractListModel*'
从 QAbstractListModel 中删除项目后 QML 崩溃
Qt入门教程数据模型篇 QAbstractListModel 抽象List模型