QT is a C + + library, QT has a little expansion on the basis of ANSI C + +.
But the domestic seems more impetuous, learning qt A lot even basic C + + How to compile seems to be not very clear. This article discards the constraints of the IDE or Qmake, CMake, and other tools, and attempts to transition from standard C + + to Qt compilation through a few examples.
This article is all about the most basic things, perhaps, as long as you use C + + Qt, regardless of which tool (Qmake, CMake, Boost.build, Qtcreator, vs2008, Eclipse 、...), the content of this article is to be understood ( Although we do not actually write the program, we do not directly use the C + + compiler to compile the QT program.
If you're afraid of the command line, maybe you'd like to take a look at my original GCC starter
Example one: Simple console program
A very simple example of a QT extension is useless: (that is, this is a normal C + + program)
#include <QtCore/QCoreApplication>#include <QtCore/QDebug>main(argcCharargv )app(argcargvqdebug()<<"Hello qt!" app. exec();}
As we all know, compiling a C + + program is nothing but compiling preprocessing, compiling, linking
- Compile preprocessor: Header file path and necessary macros
- Compiler: Some compilation parameters
- Linker: Some link parameters and libraries to link to
g++
Simple one-line command to generate Main.exe (under Linux, generate executable program main)
g++ Main.cpp-dqt_core_lib-ie:\qt\4.7.0\include-o Main-le:\qt\4.7.0\lib-lqtcore4
Single-line command, very simple:
- -I specify header file path
- -L Specify the library file path
- -l Specifies the library that needs to be linked
- -D define the necessary macros (in fact, this macro is not necessary for this applet)
- -o Specifies the generated executable file name
Cl
Simple one-line command to generate Main.exe
CL Main.cpp-id:/qt/4.7.0/include-dqt_core_lib-femain-link-libpath:d:/qt/4.7.0/lib QtCore4.lib
It's still simple.
- -I header file path
- -D Define necessary macros
- -fe specifying executable program file names
- -link is followed by linker parameters
- -libpath Library file path
Example two: a simple GUI program
This time it's a little bit more complicated, not a single console program, but a simple GUI program
-
Main.cpp
#include <qtgui/qapplication> #include "widget.h" int main (int argc char** argv) { qapplication app (argc argv); widget ww. Show (); return app. Exec () }
-
Widget.h
#include <qtgui/qwidget>class Widget : public qwidget{public< Span class= "O" >: widget (qwidget * Parent=null
Widget.cpp
#include "widget.h"widget::widget(parent):qwidget(parent){ }
Similarly, the program does not use QT extensions, which are compiled directly from the C + + compiler:
g++
g++ main.cpp Widget.cpp-dqt_core_lib-dqt_gui_lib-ie:\qt\4.7.0-beta2\include-o Main-le:\qt\4.7.0-beta2\lib- Lqtcore4-lqtgui4
Because we used the Qtgui module, we compared it with the previous:
- Added-dqt_gui_lib and-LQTGUI4.
- One more file Widget.cpp
Note: Under Windows
This command is available if you are on a non-Windows platform. But under Windows, you know: Sub-console and Windows two link subsystem, and the entry function is divided into main and WinMain.
This command, the compiled Main.exe, will pop up the console. To avoid the console, use the following command:
g++ main.cpp Widget.cpp-dqt_core_lib-dqt_gui_lib-dqt_needs_qmain-ie:\qt\4.7.0-beta2\include-o main-le:\qt\4.7.0- Beta2\lib-lqtcore4-lqtgui4-lqtmain-wl,-subsystem,windows
There are two more options:
- Qtmain a WinMain function in the library, it calls the main function of our code. That is, for the compiler: the name of the entry function has changed.
- -wl,-subsystem,windows you know, link windows subsystem
- For the MinGW, there is a macro qt_needs_qmain here, this thing is very interesting. We mentioned this in detail in the QT Windows link subsystem and entry function (the final version). (Here, but you can ignore it, it's not going to go wrong, and there's no difference to feel)
Cl
As with the g++ under Windows, with the console:
CL Main.cpp widget.cpp-id:/qt/4.7.0/include-dqt_core_lib-dqt_gui_lib-femain-link-libpath:d:/qt/4.7.0/lib QtCore4.lib QtGui4.lib
Without console:
CL Main.cpp Widget.cpp-id:/qt/4.7.0/include-dqt_core_lib-dqt_gui_lib-femain/md-link-libpath:d:/qt/4.7.0/lib- Subsystem:windows qtmain.lib QtCore4.lib QtGui4.lib
Ibid.: Specify link subsystem, enable WinMain entry function
How multi-file programs are managed
What's the downside of calling the compiler directly?
- Many parameters, each time the manual input, it is inevitable error. (for example, we've used as few parameters as possible, so you're probably dizzying).
- Second, it's important that everything is recompiled whenever a file is modified.
The traditional way to change this is to write Makefile, and then compile with just the input make, and he will determine which files are changed and need to be recompiled.
The other features that are provided by the IDE itself, such as vs. Here's a quick look at the corresponding makefile file for this example:
Mingw32-make's Makefile File
=-dqt_core_lib-dqt_gui_lib-ie:\qt\4.7.0\include=-le:\qt\4.7.0\LIB-LQTCORE4-LQTGUI4 -lqtmain-wl,-subsystem,windows= MAIN.O widget.o= Main$ (objects$ (Objects$ (ldflags )
NMAKE's Makefile file
=-ID:/QT/4.7.0/INCLUDE-DQT_CORE_LIB-DQT_GUI_LIB-MD=-libpath:d:/qt/4.7.0/lib-subsystem:windows Qtmain.lib QtCore4.lib QtGui4.lib= main.obj widget.obj = Main.exe $ (Objects $ (objects$ ( Ldflags)
Do not introduce this, because makefile writing is also a science. Very difficult to write, all have Qmake, cmake these tools to help us generate makefile files
Example three: introduction of MOC
The extension of Qt to C + + is mainly 3 aspects:
- Meta-object system, files that contain q_object macros (. h,. CPP, etc.) require MOC preprocessing
- Resource system,. qrc files require RCC for preprocessing
- Interface System,. ui files need to be preprocessed by UIC
Of these 3, the meta-object system is the most complex and important in the QT program. The other two you can not, but this is not a little bit outrageous (no it is called QT program?) As we wrote earlier, it's just a normal C + + program)
Talk less, see Example: (Modify the previous widget.h, add Q_object)
#include <QtGui/QWidget>qwidgetpublicWidget(parent=NULL ); };
How do I compile this program? Does the command in the example two still work? Try it:
Wow, the output is so rich!
Greetings from g++:
Main.o:main.cpp: (. Text$_zn6widgetd1ev[Widget::~widget ()]+0xb): Undefined reference to ' vtable for Widget 'main.o:main.cpp: (. Text$_zn6widgetd1ev[Widget::~widget ()]+0x15): Undefined reference to ' vtable for Widget 'widget.o:widget.cpp: (. text+0x39): Undefined reference to ' vtable for widget 'widget.o:widget.cpp: (. text+0x43): Undefined reference to ' vtable for Widget '
Greetings from CL:
Widget.obj:error LNK2001: unresolved external symbol "public:virtual struct qmetaobject const * __thiscall widget::metaobject (void) const ([email protected]@@[email protected] @XZ) widget.obj:error LNK2001: unresolved external symbol "public:virtual void * __thiscall Widge T::qt_metacast (Char const *) "([email protected]@@[email protected]) Widget.obj:error LNK2001: unresolved external symbol" Public:virtua l int __thiscall Widget::qt_metacall (enum qmetaobject::call,int,void *) "(Email protected]@@[email protected]@@[ Email protected]) what happened?
After adding a macro, what happens? Let's see what the compiler looks like when the macro expands:
#include <QtGui/QWidget>ClassWidgets:PublicQwidget{StaticConstQmetaobjectStaticmetaobject;VirtualConstQmetaobject*MetaObject()constvirtual void *qt_metacast ( Span class= "K" >const char *virtual int qt_metacall ( Qmetaobject::callintvoid ** ... public: widget (qwidget * parent=null) ;
All of a sudden out of so many functions, and there is no function body, it is not wrong to blame. How do I generate a function body? That's what the MOC did:
MoC Widget.h-o Moc_widget.cpp
In this way, these functions are implemented in moc_widget.cpp, as long as we compile the file with a link.
For g++, on the basis of example two, add a moc_widget.cpp file directly, then everything is OK:
g++ main.cpp widget.cpp Moc_widget.cpp-dqt_core_lib-dqt_gui_lib-ie:\qt\4.7.0-beta2\include-o main-le:\qt\4.7.0- Beta2\lib-lqtcore4-lqtgui4
For the CL compiler, just add a moc_widget.cpp.
Example four, RCC and UIC
It's a bit of a waste of the name, not an example in this section (because the RCC and UIC concepts are relatively simple)
If we use resources, then need a XXX.QRC file, this file, C + + compiler does not know, so
RCC Xxx.qrc-o Qrc_xxx.cpp
If we use the designer-designed interface, the UI. The C + + compiler does not recognize this file, so
UIC Xxx.ui-o Ui_xxx.h
In this way, we get is all the. h and. cpp files, and the rest of the work, you know, is given to the C + + compiler on the line.
Other
Now look at this picture: Is it very simple?
2015 update
For QT5 users, this article is basically applicable, just pay attention to
- Qt4 GUI in Qt5 mainly divided into Qt5gui, Qt5widget and other libraries.
Qt4 |
Qt5 |
QtCore4 |
Qt5core |
QtGui4 |
Qt5gui Qt5widget |
- Header file Qtgui/qwidget and so on need to become qtwidgets/qwidget
http://blog.debao.me/zh/2010/11/from-cpp-to-qt/
From C + + to QT (Command-line compilation, explaining the principle)