Qt GUI Dialog Initialization Confusion
I am learning GUI coding with Qt and hope to clear up some confusion on my part. When I create a dialog with Qt Creator it crea开发者_开发百科tes code for me like this...
#ifndef LISTDIALOG_H
#define LISTDIALOG_H
#include <QDialog>
#include "ui_listdialog.h" //Q1:Why was this auto paced in cpp file instead of h file?
//Q2: This is what I'm really confused about.
//Is Ui namespace wrapping ui_listdialog class or the ListDialog class?
namespace Ui {
class ListDialog;
}
class ListDialog : public QDialog
{
Q_OBJECT
public:
explicit ListDialog(QWidget *parent = 0); //Q3: Why is this constructor explicit?
~ListDialog();
//CUSTOM FUNCTIONALITY NOT ADDED BY CREATOR (IGNORE FOR MY POST)
private slots:
void addItem();
void editItem();
void deleteItem();
//END CUSTOM FUNCTIONALITY
private:
Ui::ListDialog *ui; //Placed on heap instead of stack.
};
#endif // LISTDIALOG_H
There are things in the above code that differ from my 3 Qt books (all 3 out of date and ignore Creator).
My main confusion comes from Q2. Is "Ui" wrapping "ui_listdialog.h" or the class I have posted here ( class ListDialog )? The syntax seems to imply to me that it is wrapping the latter but I feel it must be actually wrapping the ui_listdialog.h class instead. Very confused about this. Can someone explain this clearly?
I also don't understand why the constructor was made explicit by Creator. I have not seen that in any of the 3 books.
Q1. The #include is placed in the .cpp to avoid too many dependencies in the header file. This shortens compilation time, because if you change the dialog, the only thing you have to recompile is the .cpp and not everything that includes your header file. In general, if a forward declaration of a class is enough (i.e. you only have a pointer or a reference to it in your class), then it's better not to #include the class's definition.
Q2. Ui is a namespace that contains a different class called ListDialog. You can open the header file and see the definition of this other class. A bit confusing until you get used to it.
Q3. It's a good habit to use the explicit
keyword with constructors that take a single parameter. Otherwise the constructor can also be used as an automatic conversion operator, and this can cause problems if you're not aware of it. For example, if you have a function that takes a ListDialog parameter, and you pass a QWidget * parameter, it may call the constructor when in fact you want the compiler to shout (invalid parameter).
The ui_listdialog.h
contains implementation to generate your user interface based on Qt Designer. It isn't necessary when declaring the class -- that's why the file was #include
d in the .cpp
(Q1). Without the ui_listdialog.h
in the header, the class declaration is necessary (Q2).
As for Q3, it's probably there to make you use the constructor syntax. Else, you could write misleading statements like
ListDialog dialog = parentDialog ;
精彩评论