基类 '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
      ^

所以我不确定我的问题出在哪里。我尝试阅读有关 QAbstractListModelQAbstractItemModel 的文档,但我不知道。

我还尝试查看我是否曾经以错误的方式构造了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&lt; UTask* &gt; 以及支持代码以在您的UScenario 对象被销毁时正确释放内存。

例如,这里有一些但不是全部的更改,但应该为您指明正确的方向。只需确保首先将m_tasks 更改为QList&lt; UTask* &gt;

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 中删除行

从 QAbstractListModel 中删除项目后 QML 崩溃

Qt入门教程数据模型篇 QAbstractListModel 抽象List模型

Qt入门教程数据模型篇 QAbstractListModel 抽象List模型

在 Qt 5.0 中向 QML 公开 QAbstractListModel 元素属性