一步步学Qt,第五天-Qt学习小结-Qt工作机制
学习Qt有些时间了,每天留下的是当天自己的学习心得,和问题处理。现在来小小的总结一下,这些天学习Qt,对Qt的个人认识。
Qt的工作机制:(这里借用一个QtGuiApplication来讲解分析)
1、使用QtSDK
新建一个工程QtAction(QMainWindow),工程结构如图
总共有五个文件:.pro工程文件:用于qmake生成Makefile,再使用make来编译工程,生成可执行文件
.h文件,main.cpp文件,mainwindow.cpp文件,还有maindwidow.ui文件
先来分析一下.h文件,看看文件内容:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
可以看到MainWindow类,public 继承了QMainWindow,在Mainwindow中有一个私有的Ui::MainWindow 的指针对象ui,这里的Ui::Mainwindow其实就是对于的.ui文件生成的class,在MainWindow中吧这个class的一个指针对像作为他的成员,是为了可以操作.ui文件中的每一个控件。
在Mainwindow public继承QMainWindow之后,在MainWindow中就可重新实现QMainWindow的所有的函数,当然这些函数只能是public的函数(C++知识,public继承,不可访问protected和private的函数),比如常有到的show()函数等。看看实现文件:
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
看到这里的ui调用了她的setupUi函数,这个函数从哪里来的呢?用Qtdesigner打开.ui文件,并查看她的源代码,如下:
/********************************************************************************
** Form generated from reading UI file 'mainwindowqy6396.ui'
**
** Created: Mon Aug 29 10:48:01 2011
** by: Qt User Interface Compiler version 4.7.3
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/
#ifndef MAINWINDOWQY6396_H
#define MAINWINDOWQY6396_H
#include <QtCore/QVariant>
#include <QtGui/QAction>
#include <QtGui/QApplication>
#include <QtGui/QButtonGroup>
#include <QtGui/QHeaderView>
#include <QtGui/QMainWindow>
#include <QtGui/QMenuBar>
#include <QtGui/QStatusBar>
#include <QtGui/QToolBar>
#include <QtGui/QWidget>
QT_BEGIN_NAMESPACE
class Ui_MainWindow
{
public:
QWidget *centralWidget;
QMenuBar *menuBar;
QToolBar *mainToolBar;
QStatusBar *statusBar;
void setupUi(QMainWindow *MainWindow)
{
if (MainWindow->objectName().isEmpty())
MainWindow->setObjectName(QString::fromUtf8("MainWindow"));
MainWindow->resize(400, 300);
centralWidget = new QWidget(MainWindow);
centralWidget->setObjectName(QString::fromUtf8("centralWidget"));
MainWindow->setCentralWidget(centralWidget);
menuBar = new QMenuBar(MainWindow);
menuBar->setObjectName(QString::fromUtf8("menuBar"));
menuBar->setGeometry(QRect(0, 0, 400, 21));
MainWindow->setMenuBar(menuBar);
mainToolBar = new QToolBar(MainWindow);
mainToolBar->setObjectName(QString::fromUtf8("mainToolBar"));
MainWindow->addToolBar(Qt::TopToolBarArea, mainToolBar);
statusBar = new QStatusBar(MainWindow);
statusBar->setObjectName(QString::fromUtf8("statusBar"));
MainWindow->setStatusBar(statusBar);
retranslateUi(MainWindow);
QMetaObject::connectSlotsByName(MainWindow);
} // setupUi
void retranslateUi(QMainWindow *MainWindow)
{
MainWindow->setWindowTitle(QApplication::translate("MainWindow", "MainWindow", 0, QApplication::UnicodeUTF8));
} // retranslateUi
};
namespace Ui {
class MainWindow: public Ui_MainWindow {};
} // namespace Ui
QT_END_NAMESPACE
#endif // MAINWINDOWQY6396_H
可以看到这里的内容是对那个.ui文件使用qt解析的结果,其实她本身的内容是:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralWidget"/>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>21</height>
</rect>
</property>
</widget>
<widget class="QToolBar" name="mainToolBar">
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
</widget>
<widget class="QStatusBar" name="statusBar"/>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>
看到这个,如果您熟悉Android的开发,或者Gtk的glade你会发现他们使用了一样的机制,把所有的控件序列化。
回到使用QtDesigner看到的.ui文件的code信息:
在Ui_MainWindow这个class中有两个函数,第一个就是我们之间见到的setupUi还这个函数,第二是retranslateUi,他们的形参都是QMainWindow的一个指针对象*Mainwindow,这里也正是在MainWindow的构造函数中使用ui->setupUi(this)的原因,这里的this,就是当前的窗口也就是Mainwindow,不过这个窗口继承了QMainWindow,也就是还是一个QMainWindow的指针对象作为了setupUi的形参。至于retranslateUi函数,这函数看她的实现,可以知道她是用于程序的国际化的时候会用到的。这里不多说。
小结:
在MainWindow 类中有一个这个Ui窗体的指针对象,她可以调用她的setupUi函数,来把ui的设计内容用于当前的Mainwindow,且可以使用ui来操作ui文件中的每一个控件。
使用方法是ui->objectname,注意这里使用的是“->”操作,不是“ .”操作,为什么呢?(C++知识,->用于class的指针对象或引用来调用其函数的,.是class的对象来调用class的函数的)。那么在MainWindow的构造函数中,我们可以设置ui中所有的控件的属性和对应的操作。
2、使用vs2008
与使用QtSDK开发生成的文件个数一样,但是每一个文件的具体功能不全是一样的:
总共有五个文件:.qrc项目资源文件(替换了.pro工程文件,而且没有了.pro文件)
.h文件,main.cpp文件,mainwindow.cpp文件,还有maindwidow.ui文件
首先来看看她的.h文件:
#ifndef QTACTION_H
#define QTACTION_H
#include <QtGui/QMainWindow>
#include "ui_qtaction.h"
class QtAction : public QMainWindow
{
Q_OBJECT
public:
QtAction(QWidget *parent = 0, Qt::WFlags flags = 0);
~QtAction();
private:
Ui::QtActionClass ui;
};
#endif // QTACTION_H
这个文件的内容与上面的没有太多的不一样,可以不要的就是Ui::QtActionClass的对象的类型,此处是一个仅对象,不是指针
再看看实现文件;
#include "qtaction.h"
QtAction::QtAction(QWidget *parent, Qt::WFlags flags)
: QMainWindow(parent, flags)
{
ui.setupUi(this);
}
QtAction::~QtAction()
{
}
此处与上面的也没有太大的不一样,在调用setupUi方法的时候使用的是"."操作运算符。