PDA

View Full Version : Understanding the Basics



phil_n
7th December 2015, 23:39
Hi all. I'm back trying to learn something about Qt. My c++ knowledge is very rudimentary so as a result I am having some difficulty picking up on what's going on in the code examples and tutorials on the web. Please bear with me as I expect to post numerous questions in the coming months. I'll start with this code from the bogotobogo "Qt5_QTableView_QItemDelegate_ModelView_MVC " tutorial which I'm trying to understand:




DelegateTableViewDialog
::DelegateTableViewDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::DelegateTableViewDialog)



Please point out where I am wrong here -

I think it's the constructor for the DelegateTableViewDialog class that expects a QWidget pointer to it's parent which it gets from the initialization list in the form of a QWidget and then instantiates ui as a DelegateTableViewDialog object. It's just the generic theory I'm wondering about. (I am going to try to use a TableView in my code but that'll be further on down the road.)

Thanks

d_stranz
8th December 2015, 00:31
Please point out where I am wrong here

Well, you're basically correct. This is the DelegateTableViewDialog constructor (or at least the first few lines of it). The declaration is more typically made on a single line:



DelegateTableViewDialog::DelegateTableViewDialog(Q Widget *parent) :


but compilers don't care about that.

In Qt, all classes derived from the QObject base class take an optional pointer to a parent class as a constructor argument. QWidget classes (which derive ultimately from QObject) usually take a QWidget pointer. This sets up a hierarchy of class instance ownership. An instance of a QWidget class created with a non-NULL QWidget pointer as parent becomes owned by that parent. When the parent is deleted (or goes out of scope), all of its children are recursively deleted as well. This is contrary to the general convention in C++, where an instance of a class created with "new" must be manually destroyed using "delete". The Qt ownership hierarchy takes care of the deletion part for you. Calling delete on a QObject instance that is owned by a parent may actually cause your program to crash.

The second line of the constructor (QDialog( parent )) is ensuring that the QDialog base class is initialized with the pointer to the parent widget. If this line were not present, the base class would go through its default construction (which would not set up the hierarchy properly, because the parent pointer would be ingnored.

The third line creates a new instance of the DelegateTableViewDialog's GUI class and assigns it to the DelegateTableViewDialog's ui member variable. This class (which is not the same as DelegateTableViewDialog) is a class created by the Qt meta-object compiler (MOC), which places it in the Ui namespace. Thus its full name is Ui:: DelegateTableViewDialog. MOC reads the .ui file (usually created through the use of Qt Designer) and generates C++ .cpp and .h files containing the UI class definition. These are compiled and linked into the executable program during the build process.

In the body of the constructor, the "ui" instance is initialized through a call to setupUi(). This initialization creates all of the child widgets defined in the .ui file, and because the "this" pointer is passed in the call, sets the DelegateTableViewDialog instance as the parent for all of the children.

phil_n
8th December 2015, 04:17
Thanks. That sounds like a good, clear (to me) description and should help as I (hopefully) progress. I am going to make an attempt to keep all this (and whatever other useful information that comes my way) in a document detailing my learning journey that I may post at some time on a web page in case it may be helpful to someone else.

But, in what sense do you mean that the second instance of DelegateTableViewDialog is not the same as the first? Are there now two classes with the same name just differentiated by the Ui namespace reference?

anda_skoa
8th December 2015, 10:51
This class (which is not the same as DelegateTableViewDialog) is a class created by the Qt meta-object compiler (MOC), which places it in the Ui namespace. Thus its full name is Ui:: DelegateTableViewDialog. MOC reads the .ui file (usually created through the use of Qt Designer) and generates C++ .cpp and .h files containing the UI class definition.

The tool is called UIC (User Interface Compiler) and it only generates a header file.

MOC is the code generator that works on markers in header files of QObject subclasses as input to add things like signals, slots, properties.


But, in what sense do you mean that the second instance of DelegateTableViewDialog is not the same as the first? Are there now two classes with the same name just differentiated by the Ui namespace reference?

The Ui class is, as d_stranz explained, a generated class based on the output of Qt Designer, it is the dialog's content.
The DelegateTableViewDialog is the class that you are creating, the dialog itself, empty unless filled with widgets (manually or by calling setupUi on an Ui class).

Cheers,
_

d_stranz
8th December 2015, 15:43
The tool is called UIC (User Interface Compiler) and it only generates a header file.

MOC is the code generator that works on markers in header files of QObject subclasses as input to add things like signals, slots, properties.

Yes, my mistake. UIC and MOC are things that just work, and I don't think about them much.


But, in what sense do you mean that the second instance of DelegateTableViewDialog is not the same as the first? Are there now two classes with the same name just differentiated by the Ui namespace reference?

Yes. This can be confusing, and I generally rename the Ui class to something else to lessen the confusion (which you can do in Qt Designer - it is the "objectName" property for the item at at the very top of the Object hierarchy).

phil_n
8th December 2015, 18:17
Thanks again. Now lets see if I have this right: Ui::DelegateTableViewDialog is basically DelegateTableViewDialog after the compile system adds in the graphical and signal/slot components that it picks up from Creator? And, if I were to instantiate a DelegateTableViewDialog for some reason this constructor would actually construct a Ui::DelegateTableViewDialog?

Also, if I were to hard code all the elements myself in a text editor and compile it would the compile system then also create the Ui namespace?

And.....why would I want to rename it?

anda_skoa
8th December 2015, 19:17
Ui::DelegateTableViewDialog is basically DelegateTableViewDialog after the compile system adds in the graphical and signal/slot components that it picks up from Creator?

No.

DelegateTableViewDialog is the dialog window.

Ui::DelegateTableViewDialog is a generated helper class that creates content for DelegateTableViewDialog when its setupUi() method is called.



And, if I were to instantiate a DelegateTableViewDialog for some reason this constructor would actually construct a Ui::DelegateTableViewDialog?

Yes, because DelegateTableViewDialog's constructor has this in its initialization list


ui(new Ui::DelegateTableViewDialog)




Also, if I were to hard code all the elements myself in a text editor and compile it would the compile system then also create the Ui namespace?

No.

Cheers,
_

d_stranz
9th December 2015, 01:33
And.....why would I want to rename it?

Because, as your comments illustrate, having two different classes with the same name (DelegateTableViewDialog), one of them in the global namespace and one of them in the Ui namespace is very confusing to a lot of people especially when first starting out in Qt. Naming one of them DelegateTableViewDialog and the other DelegateTableViewDialogGUI (for example) helps lessen the confusion.

And if you are writing Qt code commercially, at some point your code might be turned over to someone else to maintain. Likely they are less familiar with Qt than you would be by that point, so it aids in maintenance as well.