Analyzing a complete Qt project thoroughly
-
Correct. But this way the compiler provides checking as well, in case you accidentally overloaded the method instead of having an override.
Very good, thanks.
Worth to know that when I writeoverride
as with the above post of me for the definition part, the compiler doesn't recognise it. Should I merely write it in the declaration?Say my library gives you a pointer to the base class -
A *
, can you tell if I created the object as an instance ofA
or as an instance ofB
?I suppose, no, because it's not yet been addressed.
Assuming you want to copy the object, how can this be achieved if you don't know the actual type of the object behind the pointer? Here's where
clone()
makes sense, because in the method you know exactly the type of the object, that is to say:A * x = methodFromLibrary(); A * copy = x->clone();
Works properly because if you have an object of type
A
behind the pointer, thenA::clone()
is going to be called, conversely if the actual object is of typeB
thenB::clone
is going to be called. Meaning you're going to get the correct method called to make a copy. Remove thevirtual
out ofA::clone
and you can't copy the object anymore, because you'd always getA::clone()
called.I know of
virtual functions
in C++, but the whole thing is rather mess in the use of this program.
Thank you.I also set override for
setData
anddata
functions inCell
.@tomy said in Analyzing a complete Qt project thoroughly:
Worth to know that when I write override as with the above post of me for the definition part, the compiler doesn't recognise it. Should I merely write it in the declaration?
Yes, the
override
specifier goes only in the declaration, it's not part of the function prototype so it makes no sense in the definition.I suppose, no, because it's not yet been addressed.
Incorrect. The object is there it's real, the handle to it (i.e. the pointer) is what hides the actual implementation. Notice the following is correct:
A * x = new A; A * y = new B;
Both these objects can be addressed through a pointer to the base class. Implicit upcasting is expected and normal. In the end
B
ISA
. -
@tomy said in Analyzing a complete Qt project thoroughly:
Worth to know that when I write override as with the above post of me for the definition part, the compiler doesn't recognise it. Should I merely write it in the declaration?
Yes, the
override
specifier goes only in the declaration, it's not part of the function prototype so it makes no sense in the definition.I suppose, no, because it's not yet been addressed.
Incorrect. The object is there it's real, the handle to it (i.e. the pointer) is what hides the actual implementation. Notice the following is correct:
A * x = new A; A * y = new B;
Both these objects can be addressed through a pointer to the base class. Implicit upcasting is expected and normal. In the end
B
ISA
.How to see the definition of
virtual QTableWidgetItem *clone() const;
in qtablewidget.cpp on Qt Creator, please?In the Docs, it's only written it creates a copy of the item. I want firstly see the way it's defined in qtablewidget.cpp.
-
How to see the definition of
virtual QTableWidgetItem *clone() const;
in qtablewidget.cpp on Qt Creator, please?In the Docs, it's only written it creates a copy of the item. I want firstly see the way it's defined in qtablewidget.cpp.
-
How to see the definition of
virtual QTableWidgetItem *clone() const;
in qtablewidget.cpp on Qt Creator, please?In the Docs, it's only written it creates a copy of the item. I want firstly see the way it's defined in qtablewidget.cpp.
@tomy You have to install the Qt sources to see the cpp files - can be done with MaintenanceTool.
Or have a look at https://code.woboq.org/qt5/qtbase/src/widgets/itemviews/qtablewidget.cpp.html
-
So starting from the main.cpp file, where all Qt and QML programs start executing all of their statements from, we begin by creating a new object of the project "MainWindow" using new on heap as below,
#include <QApplication> #include "mainwindow.h" int main(int argc, char *argv[]) { QApplication app(argc, argv); MainWindow* mainWin = new MainWindow; mainWin->show(); return app.exec(); }
In the constructor of MainWindow we have:
MainWindow::MainWindow() { spreadsheet = new Spreadsheet; setCentralWidget(spreadsheet); createActions(); createMenus(); createContextMenu(); createToolBars(); createStatusBar(); readSettings(); findDialog = nullptr; setWindowIcon(QIcon(":/images/icon.png")); setCurrentFile(""); }
By
spreadsheet = new Spreadsheet;
the constructor ofSpreadsheet
is called, as shown below:Spreadsheet::Spreadsheet(QWidget *parent) : QTableWidget(parent) { autoRecalc = true; setItemPrototype(new Cell); setSelectionMode(ContiguousSelection); connect(this, SIGNAL(itemChanged(QTableWidgetItem *)), this, SLOT(somethingChanged())); clear(); }
then we specify the item prototype for the table to be
new Cell
. This, in turn, call's Cell's constructor:Cell::Cell() { setDirty(); }
Up to now, we have a spreadsheet table created on the main screen of the project's window and its cells' prototype is of a
Cell
, that is, they're by default dirty.All right up to here?
Now, let me re-ask this question, please:
where/when in code the overridden functionclone
is called? -
So starting from the main.cpp file, where all Qt and QML programs start executing all of their statements from, we begin by creating a new object of the project "MainWindow" using new on heap as below,
#include <QApplication> #include "mainwindow.h" int main(int argc, char *argv[]) { QApplication app(argc, argv); MainWindow* mainWin = new MainWindow; mainWin->show(); return app.exec(); }
In the constructor of MainWindow we have:
MainWindow::MainWindow() { spreadsheet = new Spreadsheet; setCentralWidget(spreadsheet); createActions(); createMenus(); createContextMenu(); createToolBars(); createStatusBar(); readSettings(); findDialog = nullptr; setWindowIcon(QIcon(":/images/icon.png")); setCurrentFile(""); }
By
spreadsheet = new Spreadsheet;
the constructor ofSpreadsheet
is called, as shown below:Spreadsheet::Spreadsheet(QWidget *parent) : QTableWidget(parent) { autoRecalc = true; setItemPrototype(new Cell); setSelectionMode(ContiguousSelection); connect(this, SIGNAL(itemChanged(QTableWidgetItem *)), this, SLOT(somethingChanged())); clear(); }
then we specify the item prototype for the table to be
new Cell
. This, in turn, call's Cell's constructor:Cell::Cell() { setDirty(); }
Up to now, we have a spreadsheet table created on the main screen of the project's window and its cells' prototype is of a
Cell
, that is, they're by default dirty.All right up to here?
Now, let me re-ask this question, please:
where/when in code the overridden functionclone
is called? -
Hi
Unless you added new code to sample to call it, ( from to p post)
Its not called as i can rename it to cloneX() and it still compiles meaning
its not used at all. (currently) -
So starting from the main.cpp file, where all Qt and QML programs start executing all of their statements from, we begin by creating a new object of the project "MainWindow" using new on heap as below,
#include <QApplication> #include "mainwindow.h" int main(int argc, char *argv[]) { QApplication app(argc, argv); MainWindow* mainWin = new MainWindow; mainWin->show(); return app.exec(); }
In the constructor of MainWindow we have:
MainWindow::MainWindow() { spreadsheet = new Spreadsheet; setCentralWidget(spreadsheet); createActions(); createMenus(); createContextMenu(); createToolBars(); createStatusBar(); readSettings(); findDialog = nullptr; setWindowIcon(QIcon(":/images/icon.png")); setCurrentFile(""); }
By
spreadsheet = new Spreadsheet;
the constructor ofSpreadsheet
is called, as shown below:Spreadsheet::Spreadsheet(QWidget *parent) : QTableWidget(parent) { autoRecalc = true; setItemPrototype(new Cell); setSelectionMode(ContiguousSelection); connect(this, SIGNAL(itemChanged(QTableWidgetItem *)), this, SLOT(somethingChanged())); clear(); }
then we specify the item prototype for the table to be
new Cell
. This, in turn, call's Cell's constructor:Cell::Cell() { setDirty(); }
Up to now, we have a spreadsheet table created on the main screen of the project's window and its cells' prototype is of a
Cell
, that is, they're by default dirty.All right up to here?
Now, let me re-ask this question, please:
where/when in code the overridden functionclone
is called?@tomy said in Analyzing a complete Qt project thoroughly:
Now, let me re-ask this question, please:
where/when in code the overridden function clone is called?Qt calls it when it needs a new object. That's why you call
setItemPrototype
. It (Qt) uses the object you passed to use it as item factory to create new items. It's unimportant for all practical purposes where exactly the call originates. -
@tomy Put a break point inside your clone() and run through debugger. When debugger stops inside clone() you will have a stack trace where you can see from where it was called.
I did it and it was the output. I think the stack trace part is the bottom-left window.
1- What can be gained from this?@mrjj, I didn't understand your sentences at all, sadly! -_-
As I've said earlier, in effect
clone
will be called only when we put some data into a cell of the table for the first time.Qt calls it when it needs a new object. That's why you call setItemPrototype.
2- Do you mean when we call
setItemPrototype(new Cell);
Qt callsclone
? That is, whenever in the code we create a new cell usingnew
thatclone
function is called.It (Qt) uses the object you passed to use it as item factory to create new items. It's unimportant for all practical purposes where exactly the call originates.
I see, but for a learner of Qt, like me, it's good to boost their Qt abilities by finding answers even for small/detailed questions too.
3- How do you know, when we create anew Cell
, Qt calls thatclone
function? Where is it specified in the code, please?I numbered my questions so that you helpers don't ignore a question.
4- Previously I asked, "All right up to here?". It's important for me, because I want to thoroughly understand the program's code, even step-by-step.Thanks to all.
-
I did it and it was the output. I think the stack trace part is the bottom-left window.
1- What can be gained from this?@mrjj, I didn't understand your sentences at all, sadly! -_-
As I've said earlier, in effect
clone
will be called only when we put some data into a cell of the table for the first time.Qt calls it when it needs a new object. That's why you call setItemPrototype.
2- Do you mean when we call
setItemPrototype(new Cell);
Qt callsclone
? That is, whenever in the code we create a new cell usingnew
thatclone
function is called.It (Qt) uses the object you passed to use it as item factory to create new items. It's unimportant for all practical purposes where exactly the call originates.
I see, but for a learner of Qt, like me, it's good to boost their Qt abilities by finding answers even for small/detailed questions too.
3- How do you know, when we create anew Cell
, Qt calls thatclone
function? Where is it specified in the code, please?I numbered my questions so that you helpers don't ignore a question.
4- Previously I asked, "All right up to here?". It's important for me, because I want to thoroughly understand the program's code, even step-by-step.Thanks to all.
@tomy said in Analyzing a complete Qt project thoroughly:
What can be gained from this?
That clone was called from QTableModel::createItem, which was called from QTableModel::setData and so on.
"2- Do you mean when we call setItemPrototype(new Cell); Qt calls clone? That is, whenever in the code we create a new cell using new that clone function is called." - please read https://doc.qt.io/qt-5/qstandarditemmodel.html#setItemPrototype It is explained there.
3- How do you know, when we create a new Cell, Qt calls that clone function? Where is it specified in the code, please? - clone() is NOT called when you create an instance of Cell. Please read the link above. It is called whenever new item needs to be created:
"Whenever QStandardItemModel needs to create an item on demand (for instance, when a view or item delegate calls setData()))" -
@tomy said in Analyzing a complete Qt project thoroughly:
What can be gained from this?
That clone was called from QTableModel::createItem, which was called from QTableModel::setData and so on.
"2- Do you mean when we call setItemPrototype(new Cell); Qt calls clone? That is, whenever in the code we create a new cell using new that clone function is called." - please read https://doc.qt.io/qt-5/qstandarditemmodel.html#setItemPrototype It is explained there.
3- How do you know, when we create a new Cell, Qt calls that clone function? Where is it specified in the code, please? - clone() is NOT called when you create an instance of Cell. Please read the link above. It is called whenever new item needs to be created:
"Whenever QStandardItemModel needs to create an item on demand (for instance, when a view or item delegate calls setData()))"Thank you for your explanations, they're beneficial. But since the subject is somehow sophisticated and I myself am tackling various topics and these days very busy, I have some delay to come to this thread. sorry.
I got much about
clone()
by now and will postpone further studying when I get to it in the code, when after the app is run completely.Back to studying the code via the step-by-step approach, I reached the statement
setDirty();
inCell
.==> After
setDirty();
, we step forward toitemChanged(QTableWidgetItem *)
which is a signal to signify that the content of the item/cell is changed. Right? (1)Then we see the slot
somethingChanged
whererecalculate()
is called where all the cells in the spreadsheet there, will be set as dirty if they contain something. But why 'all' the cells? (2)The the
viewport()
function returns the viewport widget and theupdate()
function updates (cleans) the rectangle inside the widget which is a cell here. Right? (3)The next question (4) is about
emit modified();
. What does it do or where is it used? I couldn't find somewhere it is used in code.