Inheriting from a QAbstractTableModel based class?
-
Hi,
would it be a good idea to inherit from a QAbstractTableModel based class? I tried it, but ran into some obscure syntax issues.
I put this in the .h file, but could not get the .cpp file to work, apparently because the parent's class has a parameter in the constructor other than "parent".class myChildTableModel : public myParentTableModel
{
Q_OBJECT
public:
explicit myChildTableModel(QObject *parent = nullptr);};
Anyhow, I'd like to know if it is worth the headache to get it to work, or should I just inherit from QAbstractTableModel, although it would be nice to save some typing in the future...?
Kind regards,
Andreas
Edit: "public" to the code that i've forgotten to type in before.
-
Hi,
would it be a good idea to inherit from a QAbstractTableModel based class? I tried it, but ran into some obscure syntax issues.
I put this in the .h file, but could not get the .cpp file to work, apparently because the parent's class has a parameter in the constructor other than "parent".class myChildTableModel : public myParentTableModel
{
Q_OBJECT
public:
explicit myChildTableModel(QObject *parent = nullptr);};
Anyhow, I'd like to know if it is worth the headache to get it to work, or should I just inherit from QAbstractTableModel, although it would be nice to save some typing in the future...?
Kind regards,
Andreas
Edit: "public" to the code that i've forgotten to type in before.
@andi456
I don't know what exactly your issue with your code is. You already seem to have done it for yourmyParentTableModel
, so what's the problem withmyChildTableModel
? Depending on your issue, you might wantclass myChildTableModel : public myParentTableModel
-
Well, the compiler tells me that there's something wrong with the constructor of the parent class, which has one parameter more than just "parent" and I haven't figured out so far, what i am doing wrong:
myChildTableModel::myChildTableModel(QObject *parent): myParentTableModel(parent) {
}doesn't work, because the number of arguments passed to the parent's class constructor is wrong - understandable. But if I put the parameter with exact type in there, the error changes to:
"Expected '(' for function-style cast or type construction" -
Well, the compiler tells me that there's something wrong with the constructor of the parent class, which has one parameter more than just "parent" and I haven't figured out so far, what i am doing wrong:
myChildTableModel::myChildTableModel(QObject *parent): myParentTableModel(parent) {
}doesn't work, because the number of arguments passed to the parent's class constructor is wrong - understandable. But if I put the parameter with exact type in there, the error changes to:
"Expected '(' for function-style cast or type construction"doesn't work, because the number of arguments passed to the parent's class constructor is wrong - understandable
Since you don't show whatever the declaration of your
myParentTableModel
is it's hard to say.But if I put the parameter with exact type in there, the error changes to:
"Expected '(' for function-style cast or type construction"
Since you don't show what you typed to cause the error it's hard to say. If you mean you wrote something like
myChildTableModel::myChildTableModel(QObject *parent): myParentTableModel(SomeClass *parent)
that would not be legal C++.
-
It's not too complicated, just a json parameter, so in the .h it looks like this:
explicit myParentTableModel(nlohmann::json j_list, QObject *parent = nullptr);and the .h file of the child looks like this:
explicit myChildTableModel(QObject *parent = nullptr);
I must admit that i'm not sure, if parent parameter is in order though.
-
It's not too complicated, just a json parameter, so in the .h it looks like this:
explicit myParentTableModel(nlohmann::json j_list, QObject *parent = nullptr);and the .h file of the child looks like this:
explicit myChildTableModel(QObject *parent = nullptr);
I must admit that i'm not sure, if parent parameter is in order though.
@andi456
So your parent class's constructor takes 2 parameters, the first being mandatory and the second being optional, and you declare a subclass whose constructor takes only the optional second parameter and from that call the base class with just the one (optional) parameter passed. And then you wonder why that doesn't compile? YourmyParentTableModel()
constructor requires anlohmann::json
parameter in first position, including if called frommyChildTableModel()
constructor.... -
It's not too complicated, just a json parameter, so in the .h it looks like this:
explicit myParentTableModel(nlohmann::json j_list, QObject *parent = nullptr);and the .h file of the child looks like this:
explicit myChildTableModel(QObject *parent = nullptr);
I must admit that i'm not sure, if parent parameter is in order though.
As @JonB pointed out, you need at least two constructors to make it work.
// default c'tor where myParentTableModel() is valid explicit myParentTableModel(QObject *parent = nullptr); // your enhanced, second c'tor, which requires a json arg explicit myParentTableModel(nlohmann::json j_list, QObject *parent = nullptr);
However, if your
myChildTableModel
can not serve the required args of its base class (
myParentTableModel(nlohmann::json, QObject *)
) the second c'tor, is never used, unless you maybe implement another child class which also accepts anlohmann::json
and therefore can use it to call your overloaded c'tor.class anotherTableModel : public myParentTableModel { Q_OBJECT public: explicit anotherTableModel (nlohmann::json j, QObject *parent = nullptr); };
Or you add this to your existing class:
class myChildTableModel : public myParentTableModel { Q_OBJECT public: explicit myChildTableModel(QObject *parent = nullptr); // matches parentTable = base class c'tor explicit myChildTableModel(nlohmann::json j, QObject *parent = nullptr); };
and implement it like:
myChildTableModel::myChildTableModel(nlohmann::json j, QObject *parent) : myParentTableModel(j, parent){}
-
No, i actually do not wonder, that it doesn't compile, because I do not know how to handle "QObject parent" stuff correctly.
In the .cpp of I got myParentTableModel::myParentTableModel(nlohmann::json j_list, QObject *parent)
: QAbstractTableModel(parent) {
initialization code
}
(The class works as expected in a QTableView.)
But the analogon for the child class is not clear to me. Do I need a parent parameter of the type myParentTableModel or of the type QObject? -
No, i actually do not wonder, that it doesn't compile, because I do not know how to handle "QObject parent" stuff correctly.
In the .cpp of I got myParentTableModel::myParentTableModel(nlohmann::json j_list, QObject *parent)
: QAbstractTableModel(parent) {
initialization code
}
(The class works as expected in a QTableView.)
But the analogon for the child class is not clear to me. Do I need a parent parameter of the type myParentTableModel or of the type QObject?@andi456 said in Inheriting from a QAbstractTableModel based class?:
But the analogon for the child class is not clear to me. Do I need a parent parameter of the type myParentTableModel or of the type QObject?
Check my comment above.
It propagates.
grandchildClass (int i, int x, QObject *parent) : child(x, parent)
// takes i, x, and potential parentchildClass (int x, QObject *parent) : parentClass(parent)
// takes x, and potential parentparentClass (QObject *parent) : QObject(parent)
// takes potential parent and is directly derived from QObject base class
Called top-down, where next "generation" is more specific.
You only invoke the matching constructor of the direct base class (doesn't matter how many times you've subclassed already).
All four are called, when calling something like:QMainWindow mw; grandchildClass *grandchild = new grandchildClass(42, 1337, &mw);
Btw: when grandchild's
QObject *parent
isnullptr
of course it does not mean that it has no "parent" (base- / "super"-) class... it is dependent on the classes where you derive from.QObject *parent = nullptr
means thatgrandchildClass
object is a standalone / toplevel object inQObject
/ Qt "terms". For example, then there is no otherQObject
which cleans it up when destroyed. -
No, i actually do not wonder, that it doesn't compile, because I do not know how to handle "QObject parent" stuff correctly.
In the .cpp of I got myParentTableModel::myParentTableModel(nlohmann::json j_list, QObject *parent)
: QAbstractTableModel(parent) {
initialization code
}
(The class works as expected in a QTableView.)
But the analogon for the child class is not clear to me. Do I need a parent parameter of the type myParentTableModel or of the type QObject?@andi456
Most Qt classes (QObject
/QWidget
-derived) take an optionalQObject *parent
argument. This has nothing to do withmyParentTableModel
. I imagine the use ofParent
in that name is confusing, it's not clear how it's a "parent" if you haveclass myChildTableModel : public myParentTableModel
. "Parentage" in terms of class-derivation is quite different from whatSomeClassConstructor(QObject *parent = nullptr);
is all about. The latter requires some other object (which itself is derived fromQObject
) to act as its parent at runtime (nothing to do with classes/compile time). That is used by Qt to create a hierarchy ofQObject
s. When you destroy aQObject
it destroys all its childQObhect
s for you. This is a very useful convenience to save you having to code carefully to achieve that.Please read Object Trees & Ownership. You need to understand this for Qt programming.
Just as an example. Say you have a
QMainWindow
for your top-level widget. And say you only create yourQAbstractModel
in that window's code (it's not used elsewhere). You want the model pointed to by yourQAbstractModel *model
member variable in your main window to get destroyed when the main window gets destroyed. If you don't that your code will leak memory. You could override the main window's destructor and destroy your model there explicitly yourself. Or from within your code you could construct the model viamodel = new QAbstractModel(theMainWindowInstance);
/ (theMainWindowInstance
would bethis
if you have derived fromQMainWindow
and write this code inside your derived class's code.) The main window instance would be the parent of the model, and whenever the main window is destroyed by whatever means it would destroy the model for you. -
-
I would question the need to inherit from a concrete model subclass. Are you sure a proxy model is not more appropriate?