基类"QAbstractListModel"具有私有副本构造函数 [英] base class 'QAbstractListModel' has private copy constructor

查看:96
本文介绍了基类"QAbstractListModel"具有私有副本构造函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个QT QML项目. (仍然很小)

I have a QT QML project. (still very small)

我首先通过将QAbstractListModel子类化,在我的UScenario模型上绑定一个列表视图,然后对其进行了罚款.

I started by binding a listview on my UScenario model, by subclassing QAbstractListModel and it worked fined.

现在,每个UScenario都有一个UTask列表,这些列表也有一个UCondition列表(因此,Utask也是子类QAbstractListModel).但是,QT Creator给我一个错误:

Now, each UScenario has a list of UTask, which also have a list of UCondition (so, Utask also subclasses QAbstractListModel). But then, QT Creator gives me an error:

Core/Tasks/utask.h:6: erreur : base class 'QAbstractListModel' has private copy constructor
class UTask: public QAbstractListModel
      ^

所以我不确定我的问题在哪里.我尝试阅读有关QAbstractListModelQAbstractItemModel的文档,但我没有头绪.

So I'm not sure where is my problem. I tried reading the doc about QAbstractListModel vs QAbstractItemModel, but I have no clue.

我还试图查看我是否以错误的方式构造了UTask;我认为不是.

I also tried to see if I ever constructed a UTask in a wrong way; I think not.

// 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() const{return 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();
}

推荐答案

如何将UTask对象存储在UScenario类中

QList<UTask> m_tasks

简单来说,当您调用m_tasks.append时,它试图通过默认复制构造函数复制源UTask对象,从而在QList中分配新的UTask对象.对于QAbstractListModel,它是私有的.这就是为什么您会得到错误.

In simple terms when you call m_tasks.append it is attempting to allocate a new UTask object in the QList by copying the source UTask object via the default copy constructor. In the case of QAbstractListModel it is private. This is why you're at getting the error.

一个简单的解决方案是将存储类型更改为UTask指针列表,QList< UTask* >以及支持代码,以在销毁UScenario对象时正确释放内存.

A simply solution is to change the storage type to a list of UTask pointers, QList< UTask* > along with the supporting code to properly release the memory when your UScenario object is destroyed.

例如,这是部分更改,但不是全部更改,但应为您指明正确的方向.只需确保首先将m_tasks更改为QList< UTask* >:

For example here are some but not all of the changes but should point you in the right direction. Just make sure to change m_tasks to QList< UTask* > first:

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"具有私有副本构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆