The Book of qt4 Translation: 2.1.1-2.1.2 dialog box and widgets

Source: Internet
Author: User
Tags qt designer

The Book of qt4 Translation

Qt programming Art

---------------------------------------------------------------------------------

Original Name: The Book of QT 4: The art of building QT applications

The Book of QT 4 Chinese version: QT programming Art

Zhang Xiaoke mcxiaoke@gmail.com

---------------------------------------------------------------------------------

 

Chapter 2 tools and methods for creating a dialog box

 

Now you have a rough understanding of QT, And we will turn to more practical examples to learn how these classes work together. Our first extension will convert numbers between decimal, hexadecimal, and binary markup. 2.1.
Users of this program can enter any single byte number (from 0 to 255) in any input box. This program will update the number of the other two row editors to the converted value.

**************************************** ****************************
* ***************** Differences between the dialog box and the widget ************** ***************
**************************************** ****************************

The main () function of this program and "Hello, world!" in section 1.1 !" Programs are almost the same:

// Byteconverter/Main. cpp
# Include <qapplication>
# Include "byteconverterdialog. H"
Int main (INT argc, char * argv [])
{
Qapplication A (argc, argv );
Byteconverterdialog BC;
BC. setattribute (QT: wa_quitonclose );
BC. Show ();
Return a.exe C ();
}

 

There is only one difference: the qlabel class is replaced by byteconverterdialog. This class is inherited from the qdialog class. Its Class is defined in byteconverterdialog. h In the header file. # The include command uses the (") Mark instead of the triangle brackets to integrate the header file into the program code, because the file and Main. cpp are in the same directory.

We also set the wa_quitonclose attribute of the dialog box to ensure that the dialog box is closed when the program is terminated. In the previous example, this is not necessary because we did not use any class inherited from qdialog as the main window. Since the dialog box usually only provides intermediate information, this attribute of qdialog is not activated by default. After all, closing a dialog box should not plant the entire program unless there are major errors.
We use byteconverterdialog. h file surrounded by include, which contains three pre-processing commands # ifndef mark, # define mark and # endif mark:

// Byteconverter/byteconverterdialog. h
# Ifndef byteconverterdialog_h
# Define byteconverterdialog_h
# Include <qdialog>
Class qlineedit;
Class byteconverterdialog: Public qdialog
{
Q_object
Public:
Byteconverterdialog ();
PRIVATE:
Qlineedit * decedit;
Qlineedit * hexedit;
Qlineedit * binedit;
};
# Endif

 

In C/C ++ programming, when multiple files attempt to contain a header file, using include guards is a standard method to avoid problems. This usually happens in a large program consisting of many independent development modules. When byteconverterdialog. H is included for the first time, the keyword byteconverterdialog_h is defined. If the source file contains the byteconverterdialog. h file again, the # ifndef... endif command causes the Preprocessor to skip the header file content. If there is no include guards, the compiler will notice that the keywords and classes are repeatedly defined and send an error signal. We include the header file qdialog because the byteconverterdialog class inherits from the qdialog class. To make the qdialog function available outside the byteconverterdialog class, we use the public access controller.

Class qlineedit is a pre-class declaration. The byteconverterdialog class object contains three private variables pointing to the qlineedit object. Therefore, the C ++ compiler needs to know that qlineedit is a class to process the byteconverterdialog declaration, however, it does not need to know the exact definition of the class.

The q_object macro must be used in all classes inherited from the base class qobject, including indirectly inherited classes. Because the function defined by q_object does not exist, the signal-Slot Mechanism cannot work. (For more information, see section 2.1.1)
The constructor is the only public function of this class. The pointer to the row editor object to be displayed in the converter component is stored in three member variables (decedit, hexedit, and binedit, because we want to update the input box when the user does not enter data, make sure that the three row editors display the same text. Since this is a detailed implementation of the byteconverterdialog class, we declare them as private variables.

2.1.1 inherited from qobject

As mentioned above, when a class inherits from qobject directly or indirectly, you must always use the q_object macro. This macro defines several functions used to implement the signal-slot mechanism. Unfortunately, if the q_object macro is missing in the class definition inherited from the qobject, the compiler and connector will not report errors. As a result, QT still does not know the signals and slots of this class, but the corresponding connections will not work during the runtime.
When a compiled program with debugging information is executed, a runtime warning will be issued: attempting to access unknown signals or slots. The error message is as follows:
Object: CONNECT: no such slot qobject: decchanged (qstring)

However, this error message is a bit uncertain. If you have written an incorrect name for the signal or slot, or the parameter list is incorrect, you may also see it.
Every file that uses the q_object macro must be submitted to the command line program MOC. MoC converts the code to pure C ++ code through the signal-slot mechanism.
If you use qmake to create a project, qmake searches for the q_object macro in the header files and source files contained in all. Pro files. When it is found, qmake automatically generates necessary build commands for MoC based on the content of those files.

Of course, to make qmake work correctly, you must specify the header file in the project file. Use the headers variable of qmake to specify the header file, just as you use the sources variable to specify the source file:
# Byteconverter/byteconverter. Pro
Template = app
Sources = Main. cpp \
Byteconverterdialog. cpp
Headers = byteconverterdialog. h

If the original containing q_object is not processed by MOC, the linker will complain about the unknown symbol and GCC will send the following error message:
Ld: undefined symbols:
Vtable for byteconverterdialog
Byteconverterdialog: staticmetaobject


If you are reading this error message, check the following items:
Is the headers variable specified in the project file?
If you use qmake to regenerate the MAKEFILE file, is the problem solved?

2.1.2 more complex Layout

Now let's start to implement the byteconverterdialog class. When you create an instance of this class, the constructor creates a byteconverterdialog object to generate all the row editor components to be displayed and insert them into a layout. However, this is not as simple as before: to make the program perform well in the user change dialog box, we need to use nested layout. Figure 2.2 shows how QT ensures that the input box always appears at the top of the window, while the exit button always appears at the bottom right corner of the window.

Figure 2.2: QT layout response to size change in the dialog box
But don't be alarmed: although the source code of this constructor is a bit long, it only uses simple functions:

// Byteconverter/byteconverterdialog. cpp
# Include "byteconverterdialog. H"
# Include <qlabel>
# Include <qlineedit>
# Include <qpushbutton>
# Include <qvboxlayout>
# Include <qhboxlayout>
# Include <qgridlayout>
Byteconverterdialog: byteconverterdialog ()
{
// Generate the necessary layouts
Qvboxlayout * mainlayout = new qvboxlayout (this );
Qgridlayout * editlayout = new qgridlayout;
Qhboxlayout * buttonlayout = new qhboxlayout;
Mainlayout-> addlayout (editlayout );
Mainlayout-> addstretch ();
Mainlayout-> addlayout (buttonlayout );
// Generate the labels and line-edits and add them
// To the object pointed at by editlayout
Qlabel * declabel = new qlabel (TR ("decimal "));
Qlabel * hexlabel = new qlabel (TR ("hex "));
Qlabel * binlabel = new qlabel (TR ("binary "));
Decedit = new qlineedit;
Hexedit = new qlineedit;
Binedit = new qlineedit;
Editlayout-> addwidget (declabel, 0, 0 );
Editlayout-> addwidget (decedit, 0, 1 );
Editlayout-> addwidget (hexlabel, 1, 0 );
Editlayout-> addwidget (hexedit, 1, 1 );
Editlayout-> addwidget (binlabel, 2, 0 );
Editlayout-> addwidget (binedit, 2, 1 );
// Create the Quit button and add it to the object pointed
// At by buttonlayout
Qpushbutton * exitbutton = new qpushbutton (TR ("quit "));
Buttonlayout-> addstretch ();
Buttonlayout-> addwidget (exitbutton );

...
Figure 2.3 shows the widget and its layout. Do not forget the code when we explain it.

The mainlayout object is a vertical box layout that is responsible for the layout of the entire dialog box. Therefore, when we call its constructor, we will pass the pointer to the byteconverterdialog object to it. To do this, we use the this pointer because we use the byteconverterdialog class's own function.
Figure 2.3: layout used by byteconverterdialog

The editlayout object is responsible for the layout of labels and row editor components. To neatly stacked these elements and columns side by side, we use a grid layout.

The third new call to create the buttonlayout will be responsible for managing the exit button. However, before we generate this button and other components and add them to editlayout and buttonlayout, we must use the addlayout () method to add these two layout. The addlayout () method of the layout is equivalent to the addwidget () method of the window component. If you add a widget to a layout that is not bound to a widget, you will receive a runtime error in the terminal window:
Qlayout: addchildwidget: Add layout to parent before adding children to layout.

The widget remains invisible. Therefore, you should always first generate the basic layout of your class and then add other la S ".
To ensure that the input box is always at the top of the byteconverterdialog window, the exit button is always at its bottom right corner. We use a scaling bar.
Figure 2.4: dialog box after the scaling bar is not used

The scaling bar occupies the space that is not required by the window components, so you can create a blank space in your dialog box. If you want to ignore the scaling bar in our example, the window parts occupy the whole space. When a user expands a dialog box that does not use a scaling bar, he can see a dialog box similar to Figure 2.4.

To avoid this, we add a scaling entry between editlayout and buttonlayout using the addstretch () function.

Now we can create tags and line editors and delegate them to editlayout. the aocun row editor objects in the private variables decedit, hexedit, and binedit, because we want to change their content through the code of other functions. We can manage all other objects without corresponding pointers, because we do not need to access them outside the constructor.
To ensure that the exit button is always displayed in the lower-right corner of the dialog box, before adjusting the button itself, we first fill the horizontal layout with a scaling bar.

By using the qobject: addwidget () and qobject: addlayout () methods, we add all the widgets and sub-layout to mainlayout or its sub-layout, this ensures that all objects generated by the constructor are inherited from the byteconverterdialog object. Because they now form a heap allocation object level, QT memory management will manage them for us, and we do not need to manually delete any of them. When the byteconverterdialog object is deleted, all the self objects will automatically disappear.

Just to create a very simple dialog box, we have to write so much irrelevant code. Have you ever been disappointed? The better way is in chapter 3, which explains how to use the QT designer to create a dialog box and automatically generate code. More details about the layout and background are provided in chapter 5.

Author: Zhang Xiaoke
Source: http://mcxiaoke.cnblogs.com/
Reprint: Original translation. You are welcome to reprint it. It cannot be used for commercial purposes. You must keep the signature of this article, Zhang Xiaoke (including links ).

Tag tags: translation, C ++, qt4, Gui, The Book of QT 4

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.