Getting multiple errors creating a model in Qt - c++

I'm creating a class in Qt. But everything was working until I built a tablemodel class. I'm now getting the errors "expected ( before * token" and "Creator does not name a type".
What's the problem? It seems very cryptic.
#ifndef OPENMODEL_H
#define OPENMODEL_H
#include <QAbstractTableModel>
#include <QString>
#include <QObject>
#include "creator.h"
namespace language
{
class OpenModel : public QAbstractTableModel
{
Q_OBJECT
public:
explicit OpenModel(Creator* creator, QObject *parent = 0); // Creater* throws a expected ) before * token
// QAbstractTableModel Model view functions
int rowCount(const QModelIndex &parent = QModelIndex()) const ;
int columnCount(const QModelIndex &parent = QModelIndex()) const;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
// QAbstractTableModel Model edit functions
bool setData(const QModelIndex & index, const QVariant & value, int role);
Qt::ItemFlags flags(const QModelIndex &index) const;
// Functions to manipulate creator
void add(QString name, QString file);
void remove(int index);
// Functions to move files up and down
void moveup(int index);
void movedown(int index);
private:
Creator* creator; // Creator does not name a type
};
}
#endif // OPENMODEL_H
this is creator.h
/*
This is the main file for the language-creator
It controls the addition, deletion and change of the centances (files)
It shall be passed by pointer to the models to be proccessed
*/
#ifndef CREATOR_H
#define CREATOR_H
#include <QObject>
#include <QVector>
#include "file.h"
#include "openmodel.h"
#include "setmodel.h"
namespace language
{
class Creator
{
public:
Creator();
void addFile(const File& f); // Adds a file to the vector
bool removeFile(int index); // Remove a file from the vector
bool replaceFile(int index, const File& f); // Replaces a file at index
const QVector<File>* getFiles() const; // Returns a list of the files
OpenModel getOpenModel() const; // Returns a pointer to the open model
SetModel getSetModel() const; // Returns a pointer to the set model
void reset(); // This resets the class to an initialized state
private:
QVector<File> files; // This holds all the files
};
}
#endif // CREATOR_H

You have a cyclic reference between these header-files. openmodel.h includes creator.h and the other way around. So, when creator.cpp (I presume there is such a file) gets compiled, it will include openmodel.h before the class Creator is declared (remember that #include means that the contents of the file will be pasted right there), hence you get the error.
To avoid this, you could remove the #include "creator.h" from openmodel.h, and instead add a forward declaration:
class Creator;
Put the declaration right before the class OpenModel. Since you only use pointers to Creator in that class, this will work fine.

Your creator.h file includes openmodel.h which uses the Creator identifier before createor.h has had a change to delclare it.
Put a class Creator; forward declaration in openmodel.h.

Related

Why I get an "use of delete function" from a class that inherits from QAbstractListModel?

I am trying to implement a ListView. So far, I have implemented a class named PacientModel that inherits of QAbstractListModel.
#ifndef PACIENTMODEL_H
#define PACIENTMODEL_H
#include <QAbstractListModel>
class PacientModel : public QAbstractListModel {
Q_OBJECT
public:
enum PacientRole {
CIRole,
NameRole,
LastNameRole
};
Q_ENUM(PacientRole)
PacientModel(QObject * parent = nullptr);
int rowCount(const QModelIndex & = QModelIndex()) const;
QVariant data (const QModelIndex &index, int role = Qt::DisplayRole) const;
QHash<int, QByteArray> roleNames() const;
Q_INVOKABLE QVariantMap get(int row) const;
Q_INVOKABLE void append (const QString &CI, const QString &name, const QString &lastName);
Q_INVOKABLE void set (int row, const QString & CI, const QString &name, const QString &lastName);
Q_INVOKABLE void remove (int row);
private:
struct Pacient {
QString CI;
QString name;
QString lastName;
};
QList<Pacient> m_pacients; };
#endif // PACIENTMODEL_H
I also have the implementation of the ListView, but when I compiled the code, I got this error.
C:\Qt\Qt5.8.0\5.8\android_armv7\include\QtCore\qmetatype.h:765: error: use of deleted function 'PacientModel::PacientModel(const
PacientModel&)'
return new (where) T(*static_cast(t));
How can I resolve this?
Per this Q&A QAbstractListModel's copy constructor is marked as private. That means that it is not copyable and therefore, as you inherited from it, your derived class is also not copyable by default.
If you want to make copies of your class then you need to manually define a copy constructor for the class instead of relying on the compiler doing it for you (since it won't).
After several days I discovered that the error wasn't in the class declaration, It was in the way I assigned the data to the listview... I was using this:
objetoLP->setProperty("modelList", QVariant::fromValue(pacientes));
instead of:
ctxt->setContextProperty("modelList", &pacientes);

how to add stylesheet in delegate class?

In my application I'm having a table widget. I created a new class to implement delegate for the table cells alignment as center. The delegate works fine, but stylesheet is not working properly. Below is how I implement the delegate class:
//i create new class with "QStyledItemDelegate" as base class
//QAlignmentDelegate.h
#ifndef QALIGNMENTDELEGATE_H
#define QALIGNMENTDELEGATE_H
#include <QStyledItemDelegate>
class QAlignmentDelegate : public QStyledItemDelegate
{
public:
QAlignmentDelegate(Qt::Alignment alignment);
virtual void paint(QPainter* painter,
const QStyleOptionViewItem& option,
const QModelIndex& index) const;
private:
Qt::Alignment m_alignment;
};
#endif // QALIGNMENTDELEGATE_H
//QAlignmentDelegate.cpp
#include "qalignmentdelegate.h"
QAlignmentDelegate::QAlignmentDelegate(Qt::Alignment alignment)
{
m_alignment=alignment;
}
void QAlignmentDelegate::
paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
QStyleOptionViewItem alignedOption(option);
alignedOption.displayAlignment = m_alignment;
QStyledItemDelegate::paint(painter, alignedOption, index);
}
//main.cpp
QTableWidgetItem * protoitem = new QTableWidgetItem();
protoitem->setTextAlignment(Qt::AlignRight);
QTableWidgetItem * newitem = protoitem->clone();
tableWidget->setItemPrototype(newitem);
Now how to implement stylesheet in this delegate class?

QML TableView not calling QAbstractTableModel headerData()-function

I'm currently working with a QML / QtQuick TableView. The data is shown -> great. The only thing I am currently not getting to work, are the headers: As far as I understand the Qt Model concept, the TableView should automatically call the C++ QAbstractTableModel::headerData(int section, Qt::Orientation orientation, int role)-function. However, when I add a qDebug() << "Hello World!" at the beginning of the function (or using the debugger ;)), this function never gets called and the TableView's header doesn't show any text.
Has anyone got this working? Or is this not implemented (yet?) for some reason (Qt 5.3)? What would the alternatives be?
EDIT: Additions
mymodel.cpp
QVariant myModel::headerData(int section, Qt::Orientation orientation, int role) const
{
qDebug() << "Hello World!";
}
[... I left out the implementation of the other functions
here as they work as expected ...]
mymodel.h
#ifndef MYMODEL_H
#define MYMODEL_H
#include <QAbstractTableModel>
#include "inputvectors.h"
class MyModel : public QAbstractTableModel
{
Q_OBJECT
public:
MyModel (QObject *parent = 0);
// InputVectors is just another class I use but it basically
// contains two `QList`s
MyModel (InputVectors *inputData, QObject *parent=0);
int rowCount(const QModelIndex &parent) const;
int columnCount(const QModelIndex &parent) const;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
protected:
QHash<int, QByteArray> roleNames() const;
private:
InputVectors *inputData;
};
#endif // MYMODEL_H
main.qml
[...]
TableView {
id: myTableView
anchors.fill: parent
frameVisible: false
model: controller.getInputVectorsModel()
TableViewColumn {
role: "row_line_numbers"
width: 40
delegate: Item {
Text { text: styleData.value; anchors.left:parent.left;anchors.leftMargin: 12}
}
}
}
[...]

QML,How to dynamicaly change Item of Repeater from C++

I have QML Repeater on Grid, when i clicked on item i emit signal which processed by C++ class, and then changed array in C++ which then assign as model of QML Repeater. Is there a way to change just two elements of C++ model, not whole model as i did?
that's my qml file
Grid{
height:width
rows:8
columns: 8
Repeater{
id: chessPiecesRptr
...
signal chessfigureSelected(int index)
delegate: Item{
id:chessPiecesItm
Image{
...
}
MouseArea
{
anchors.fill:parent
onClicked: {
chessPiecesRptr.chessfigureSelected(index)
}
}
}
}
C++ method which update model of QML Repeater
void ChessFiguresClass::changeModel()
{
QStringList dataList;
for(int i=0;i<64;i++)
dataList.append(QChar(posArray[i]));
QQmlProperty::write(chessPiecesRptr, "model", QVariant::fromValue(dataList));
}
Contrary to the accepted answer it is indeed possible without going all the way to implement an entire QAbstractListModel.
It is true that QStringList doesn't have any way to notify for changes, but all you have to do is wrap it up in a property, something like this:
Q_PROPERTY(QVariant myModel READ myModel NOTIFY myModelChanged)
...
QVariant myModel() { return QVariant::fromValue(myStringList); }
...
void myModelChanged(); // signal
And just emit myModelChanged every time you want to reflect a change in the model, be that replacing it with a different model or changing it internally. And use the myModel property for the Repeater's model.
However, if you have a lot of items in the model or the delegates are complex, it is always a good idea to implement your own QAbstractListModel, because with the approach above, the repeater will recreate the entire model every time it "changes", whereas the QAbstractListModel will only update the actual changes.
I'm afraid it is not possible. QList (and QStringList) does not have inner mechanisms to notify Qml items about its changes. Only when model property from QML item is changed, the whole list is read again.
I had faced the same problem before and I implemented a string list using QAbstractListModel as base class. The header looks like this:
#ifndef _SIMPLEMODEL_H_
#define _SIMPLEMODEL_H_
#include <QtCore>
class SimpleStringModel : public QAbstractListModel
{
Q_PROPERTY(int count READ count NOTIFY countChanged)
Q_DISABLE_COPY(SimpleStringModel)
Q_OBJECT
public:
explicit SimpleStringModel(QObject* parent = 0);
SimpleStringModel(const QList<QString>& initList, QObject* parent = 0);
virtual ~SimpleStringModel();
private:
enum Roles{
ModelDataRole = Qt::UserRole+1
};
public:
int count() const;
public:
void append(const QString& item);
void insert(int index, const QString& item);
void append(const QList<QString>& items);
void insert(int index, const QList<QString>& items);
bool removeOne(const QString& item);
int removeAll(const QString& item);
void removeAt(int index);
QList<QString> list() const;
signals:
void countChanged();
// QAbstractItemModel interface
public:
virtual int rowCount(const QModelIndex &parent) const;
virtual QVariant data(const QModelIndex &index, int role) const;
virtual QHash<int, QByteArray> roleNames() const;
private:
QList<QString> m_data;
};
#endif //_SIMPLEMODEL_H_
You can get all the code here. I hope this help you.

QAbstractTableModel inheritance vtable problem

Here's another problem with qt:
I extend a QAbstractTableModel, but I get a compiling error ( I'm using cmake)
// file.h
#ifndef TABLEMODEL_H
#define TABLEMODEL_H
#include <QAbstractTableModel>
class TableModel : public QAbstractTableModel
{
Q_OBJECT
public:
TableModel(QObject *parent = 0);
int rowCount(const QModelIndex &parent = QModelIndex()) const;
int columnCount(const QModelIndex &parent = QModelIndex()) const;
};
#endif
// file.c
#include "tableModel.h"
TableModel::TableModel(QObject *parent)
: QAbstractTableModel(parent){}
int TableModel::rowCount(const QModelIndex & ) const
{ return 1; }
int TableModel::columnCount(const QModelIndex & ) const
{ return 1;}
when I compile I get:
In function TableModel':
/partd/unusedsvn/unusedpkg/iface/tableModel.cpp:4: undefined reference tovtable for TableModel'
/partd/unusedsvn/unusedpkg/iface/tableModel.cpp:4: undefined reference to vtable for TableModel'
collect2: ld returned 1 exit status
does anybody got the same trouble??
Make sure you're running your header through MOC, and are linking those MOC object files.
Solved adding to CMakeLists.txt the needed cpp file.
set(tutorial_SRCS app.cpp mainWin.cpp tableModel.cpp)
When I'll run cmake, the moc* will be automatically created
Almost 100% percent of vtable errors are caused by either missing headers/class definitions or by typoes in those definitions, so the first thing to do is to make sure you got the headers and sources right (and included in project). I've personally cursed Qt to the lowest hell for that and missed that tiny typo in project file, not fun :)
Yes, vtable errors are a bitch.
You have to implement the code() method which is a pure virtual method too.
From the QAbstractTableModel documentation :
Subclassing
When subclassing QAbstractTableModel, you must implement rowCount(), columnCount(), and data().
I'm having a vtable problem too, and I implemented data(), so I'm missing other virtual crap but I don't know whitch one.
This is a fairly common bug when an object isn't moc'ed. I'd read the whole debugging document to save yourself some time down the road.
To resolve this problem, i've remove Q_OBJECT from TableModel, made new class TableModelController, that derived from QObject and have TableModel inside
class TableModel : public QAbstractTableModel
{
public:
TableModel(QObject *parent = 0);
// Some overrided functions
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
};
class TableModelController : public QObject
{
Q_OBJECT
public:
explicit TableModelController(QObject *parent = nullptr);
TableModelController(TableModel *m, QObject *parent = nullptr);
TableModel *getModel() {
return model;
}
public slots:
void addRow();
void deleteRows();
private:
TableModel *model;
};
Then i use TableModelController to access TableModel throw get Methond and public slots. I'm use QtCreator