QT学习笔记(二)

以下是《C++ GUI QT4编程》的学习笔记。

第2章 创建对话框

  1. 创建对话框,需要子类化QDialog。#include 头文件

#include 头文件:该头文件包含了子类中所要用到的窗口系统集成、事件处理、OpenGL、2D图形、基本图像、字体和文本等相关功能的Qt类的定义。

  1. 对于所有定义了信号和槽的类,在头文件中类定义的开始处都需要添加Q_OBJECT宏。如:
    QT学习笔记(二)_第1张图片
    其中,Q_OBJECT是一个已经定义的宏,在qobjectdef.h中有下面的代码
    QT学习笔记(二)_第2张图片
    编译时,实际上使用上述代码段替换了Q_OBJECT。
  2. 定义信号时,前面一般使用signals:关键字。如
    在这里插入图片描述
    signals关键字实际上是一个宏,C++预处理器会在编译之前将其转换为标准C++代码。
    类似,定义槽时,前面要加上关键字slots。关键字slots就像signals一样也是一个宏,也可以扩展成C++编译程序可以处理的一种结构形式。
  3. 当类的定义中包含Q_OBJECT宏时,由qmake生成的makefile将会自动包含一些运行moc的规则,(moc是指Qt的元对象编译器, meta-object compiler)为了使moc能够正常运行,必须把类定义从实现文件中分离出来并放到头文件中。由moc生成的代码会包含这个头文件,并且会自动添加一些特殊的C++代码。
  4. QT中main()函数的基本格式
#include                     //头文件中包含了对QApplication类的定义

int main( int argc, char *argv[] )         //注意,在QT中main函数带参数,在接下来创建“app”对象时使用
{
    QApplication app( argc, argv );        //创建一个QApplication类的对象,用来管理整个应用程序所用到的资源。这个QApplication构造函数需要两个参数
    ...
    return app.exec();                     //将应用程序的控制权传递给Qt。此时,程序会进入事件循环状态,这是一种等待模式,程序会等待用户的动作。
    										 只有程序进入主事件循环后才能接收事件。
}
  1. 深入介绍信号和槽

信号和槽是QT编程的基础。

声明槽要用slots关键字,槽和普通的C++函数是一样的,可以是虚函数,可以被重载,可以是公有的、保护的、私有的,并且可以被其他C++成员函数直接调用。唯一不同的是:槽还可以和信号连接在一起。在这种情况下,每当发射这个信号的时候,就会自动调用这个槽。当槽作为信号响应函数被执行时,会忽略他的返回值。
声明一个信号要用 signals关键字,在signals前不能使用public,private,protect等限定符,因为信号默认是public函数。信号只用声明,不需要也不能对它进行定义实现。还要注意,信号没有返回值,只能是void类型。
通过connect()语句将信号和槽联系在一起,connect语句格式如下:

 connect(sender,SIGNAL(signal),receiver,SLOT(slot));

这里的sender和receiver是指向 QObject的指针,分别表示发射信号的对象和接收信号的对象。SINGAL()和SLOT()是宏,他们可以将他们的参数转化为const char*类型。在调用connect()函数时,信号和槽的参数只能有类型,不能有变量名。而且如果信号和槽都有参数,则信号中的参数类型要和槽中的参数类型相对应,信号中的参数可以多余槽中的参数,但不能反过来。信号中多余的参数将被忽略。
注意:
一个信号可以连接多个槽,发射这个信号时会以不确定的顺序一个接一个地调用这些槽。
多个信号可以连接一个槽,这时无论发射哪个信号都会调用这个槽。
一个信号可以与另外一个信号相连,当发射第一个信号时,也会发射第二个信号。如:

connect( lineEdit, SIGNAL(textChanged(const QString &)), this, SIGNAL(updateRecord(const QString & )));

连接可以被移除。如:disconnect( lcd, SIGNAL(overflow()), this, SLOT(handleMathError()) );这种情况较少用到,因为当删除对象时,Qt会自动移除和这个对象相关的所有连接。

要把信号成功连接到槽,它们的参数必须具有相同的顺序和相同的类型:

connect(ftp, rawCommandReply(int, const QString &), this, SLOT(processReply(int, const QString &)) );

这里有个意外,如果信号的参数比它所连的槽的参数多,那么多余的参数将被简单的忽略掉。

  1. QT的元对象系统

QT使用了一种机制对C++进行了扩展,这种机制称为元对象系统( meta-object system )。它提供了关键的两项技术:信号-槽以及内省( introspection)
QObject子类的“元信息”(meta-information),包括一个含有对象的类名以及它所支持的信号和槽列表。
标准C++没有对Qt的元对象系统所需要的动态元信息提供支持。Qt通过提供一个独立的moc工具解决这个问题,moc解析Q_OBJECT类的定义并且通过C++函数来提供可供使用的信息。由于moc使用纯C++来实现它的功能,所以Qt的元对象系统可以在任意C++编译器上工作。
这一机制是这样来工作的:

  • Q_OBJECT宏声明了在每一个QObject子类中必须实现的一些内省函数:metaObject()、tr()、qt_metacall(),以及其他一些函数。
  • Qt的moc工具生成了由Q_OBJECT宏声明的所有函数和所有信号的实现。
  • 像connect()和disconnect()这样的QObject子类的成员函数使用这些内省函数来完成他们的工作。
    由于这些工作都是由qmake, moc, 和QObject自动处理的,所以很少需要去考虑这些事情。
  1. 无论是使用手工编码还是Qt设计师界面,在创建对话框时总要包含以下这几个相同的步骤:
    1.创建并初始化子窗口部件。
    2.把子窗口部件放到布局中。
    3.设置Tab键顺序。
    4.建立信号和槽之间的连接。
    5.实现对话框中的自定义槽。
  2. 使用QT设计师(Qt Designer)开发工具快速设计对话框

首先,使用Qt Designer工具设计对话框及窗口部件,保存后会生成界面文件 xxx.ui(一种基于XML的文件格式),然后将.ui文件添加到项目文件夹目录中。
Qt Creator编译时会自动调用Qt的用户界面编译器(user interface compiler,uic),将 xxx.ui 文件转换成C++格式,并将结果存储在 ui_xxx.h 文件中。
在 ui_xxx.h 文件中存放了生成对话框的类定义,其中包含了一些成员变量,它们存储着窗体中的子窗口部件以及子布局,另外,还包含了一个用于初始化窗体的 setupUi()函数。在main.cpp文件中使用该窗体时,可以创建一个QDialog对象,然后调用setupUi()函数,将QDialog对象作为setupUi()函数的参数。
注:在自定义对话框子类的构造函数中调用setupUi()函数来初始化窗体。在创建了用户接口后,setupUi()函数还会自动将那些符合on_objectName_signalName()命名惯例的任意槽与相应的objectName的 signalName()信号 连到一起。

  1. Qt的父-子对象机制是在QObject中实现的。

当利用一个父对象创建一个子对象时,父对象会把这个子对象添加到自己的子对象列表中。当删除这个父对象时,它会遍历子对象列表并删除每一个子对象。然后,这些子对象再去删除它们自己所包含的每个子对象。如此反复递归调用,直至清空所有子对象为止。并且,如果在删除一个父对象之前先删除了它的子对象,Qt会自动地从它的父对象的 子对象列表中将其移除。
这种机制可以很大程度上简化内存管理工作,降低内存泄漏的风险。需要明确删除的是那些使用new创建的并且没有父对象的对象。
对于窗口部件,父对象还有另外一层含义:子窗口部件会显示在它的父对象所在的区域中。当删除这个父窗口部件时,不仅子对象会从内存中消失,而且它也会在屏幕上消失。

  1. 可改变形状的对话框–扩展对话框

需要一个切换按钮、一些信号-槽连接以及一个不可以改变尺寸大小的布局。
要改变窗口形状:选择toggled(bool)作为信号,选择setVisible(bool)作为槽。—>>toggled意为“切换”
layout()-> setSizeConstraint( QLayout::SetFixedSize);//此语句使用户不能再重新修改这个对话框窗体的大小。这样一来,布局就会负责对话框重新定义大小的职责,并且也会在显示或隐藏子窗口部件的时候自动重新定义这个对话框的大小,从而可以确保对话框总是能以最佳的尺寸显示出来。

  1. Qt内置的窗口部件类和对话框类:

4种类型的按钮:QPushButton、QToolButton、QCheckBox、QRadioButton

容器窗口部件:QGroupBox、 QFrame (容器窗口部件可以包含其他的窗口部件)

多页窗口部件:QTabWidget、QToolBox (在多页窗口部件中,每一页都是一个子窗口部件,并从0开始编号这些页)

项视图窗口部件:QListView、QTreeView、QTableView (为处理较大的数据量常使用项视图窗口部件,且通常伴随使用滚动条,滚动条机制是在QAbstractScrollArea中实现的)

显示信息的窗口部件:QLabel、QLCDNumber(液晶数字显示器)、QTextBrowser (QLabel是这些窗口部件中最总要的一个,它可以用来显示普通文本、HTML和图片) QProgressBar (进度条显示)

数据输入窗口部件:QLineEdit、QTextEdit (这两个部件主要用于文本输入,可以通过检验器对输入进行限定,支持剪切板复制粘贴) QComboBox (通过下拉菜单进行数据输入)QSpinBox (通过上下按钮进行数据选择与输入)QScrollBar、QSlider(通过滚动条,滑块进行数据选择与输入)

通用对话框类:QInputDialog、QPrograssDialog、QMessageBox、QErrorMessage、QFileDialog
这些内置的窗口部件和常用对话框为用户提供了很多可以直接使用的功能。通过设置窗口部件的属性,或者通过把信号和槽连接起来并在槽里实现自定义的行为,可以很方便的使用这些内置器件。

  1. label = new QLabel( “Find &what:” );
    该语句创建了一个标签部件。第2行语句在字符串周围调用了tr()函数,作用是把字符串翻译成其他语言的标记。尽管你并没有将你的应用程序立即翻译成其他语言的打算,但是在每一个用户可见的字符串周围使用tr()函数还是一个很不错的习惯。

注意:本例实际上对应C++中使用new关键字创建动态变量,label是QLabel *型指针,通过使用new以及QLabel类的构造函数动态创建了一个指向类对象的指针。

上一篇:QT学习笔记(一) https://blog.csdn.net/weixin_44787158/article/details/99086296
下一篇:QT学习笔记(三)https://blog.csdn.net/weixin_44787158/article/details/99089676

你可能感兴趣的:(QT)