问题描述
我有一个 QT QML 项目.(还很小)
I have a QT QML project. (still very small)
我首先在我的 UScenario
模型上绑定一个列表视图,通过子类化 QAbstractListModel
并且它工作得很好.
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
^
所以我不确定我的问题出在哪里.我尝试阅读有关 QAbstractListModel
与 QAbstractItemModel
的文档,但我不知道.
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();
}
推荐答案
问题在于您如何在 UScenario
类中存储 UTask
对象
There problem is with how you're storing the UTask
objects in your UScenario
class
QList<UTask> m_tasks
简单来说,当您调用 m_tasks.append
时,它会尝试通过复制源代码在 QList
中分配一个新的 UTask
对象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
指针列表,QListUScenario
对象被销毁时,UTask* > 以及支持代码以正确释放内存.
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' 具有私有复制构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!