QT界面编程1解读.docx
- 文档编号:23985829
- 上传时间:2023-05-23
- 格式:DOCX
- 页数:44
- 大小:85.71KB
QT界面编程1解读.docx
《QT界面编程1解读.docx》由会员分享,可在线阅读,更多相关《QT界面编程1解读.docx(44页珍藏版)》请在冰豆网上搜索。
QT界面编程1解读
QT编程基础
1.QT简介
1.1.简介
(1)Qt是Trolltech公司的标志性产品,是一个跨平台的C++图形用户界面(GUI)工具包。
它提供给应用程序开发者建立艺术级的图形用户界面所需的所有功能。
Qt是完全面向对象的很容易扩展,并且允许真正地组件编程。
(2)Qt支持下述平台:
MS/Windows-95、98、NT4.0、ME、2000
Unix/X11-Linux、SunSolaris、HP-UX、CompaqTru64UNIX、IBMAIX、SGIIRIX和其它X11平台
Macintosh-MacOSX
Embedded-有帧缓冲(framebuffer)支持的Linux平台。
(3)Trolltech公司采用双重授权模式,一种用于商业性质的授权,一种用于免费的开源授权。
Qt企业版和Qt专业版提供给商业软件开发。
它们提供传统商业软件发行版并且提供免费升级和技术支持服务。
Qt自由版是Qt仅仅为了开发自由和开放源码软件提供的Unix/X11版本。
在GPL协议下,它是免费的。
Qt/E自由版是Qt为了开发自由软件提供的嵌入式版本。
在GPL协议下,它是免费的。
1.2.特点
(1)可移植性:
QT不仅适用于UNIX,同样适用于Windows。
为了同时拥有世界上几百万UNIX用户以及几百万的Windows用户,最好的办法是采用一个既适用于UNIX,又适用于Windows的GUI工具包,其答案是QT。
(2)易用性:
Qt为专业应用提供了大量的函数,在Qt的API中含有大约250个C++类,大多数的类都是GUI专有。
而且QT是基于C++构造,所以QT也具有面向对象编程的所有优点。
(3)构件支持:
Qt提供信号(signal)和插槽(slot)概念,这是一种类型安全的方法,它允许回调,并支持对象之间在彼此不知道对方信息的情况下进行合作,这使得Qt非常适合于真正的构件编程。
(4)国际化:
Qt为本地化应用提供了完全的支持,所有用户界面文本都可以基于消息翻译表被翻译成各国语言,Qt还支持双字节16bit国际字符标准。
(5)运行速度:
QT非常容易使用,且也具有很快的速度。
QT的易用性和快速是密不可分的。
这一优点要归功于QT开发者的辛苦工作,他们花费了大量的时间来优化他们的产品。
QT比其他许多GUI工具包运行速度快的原因是其实现方式。
QT是一个GUI仿真工具包,即它不使用本地工具包作调用,而是使用各自平台上的低级绘图函数,从而提高程序速度。
1.3.QT工程
1.3.1.Qt工程编辑
以下是编写Qt工程文件(*.Pro)的变量说明:
(1)TEMPLATE
变量TEMPLATE描述了为建立目标文件而采用何种模板,即生成何种形式的Makefile文件。
qmake工具定义了5种模板:
①应用程序App,为建立一个Qt应用程序创建Makefile文件;
②库lib,为建立引用程序库而创建Makefile文件;
③子工程subdirs,为建立子目录下的目标文件创建一个Makefile文件,子目录通过变量SUBDIRS指定(子目录下的工程文件也需要指出使用何种模板);
④VC应用程序vcapp,为VisualStudio生成一个应用程序工程。
仅仅用语Windos操作系统.
⑤VC库vclib,为VisualStudio生成一个应用程序库工程,仅仅用语Windows操作系统.
(2)TARGET
描述了目标文件的名称,也就是应用程序的名字(或者说exe文件的名称)。
如果不设置,与pro文件名称相同。
(3)DEPENDPATH
描述了建立应用程序所依赖的其他文件所在的路径.
(4)INCLUDEPATH
描述了编译该工程时编译器需要搜索的#include路径.
HAND
(5)SOURCES
告诉编译器,源代码文件路径及其文件名字.
(6)DESTDIR
定义了exe文件的路径.
(7)CONFIG
定义了编译选项
debug:
表示建立的目标代码是调试版本,如果没有则为Release版本.
warn_on:
要求编译器在编译应用程序时打开警告开关.
(8)OBJECTS_DIR
描述了存放中间文件(.o)文件的位置.
(9)VERSION
描述软件版本
例如:
PROJECT=QESPTA
TEMPLATE=app//subdirs表示在app.pro工程在子文件中还包含工程
SUBDIRS=src //子工程文件的目录由SUBDIRS指定
DEPENDPATH+=.
INCLUDEPATH+=../..
QMAKE_LIBDIR+=../../build
OBJECTS_DIR=obj
MOC_DIR=moc
UI_DIR=uic
CONFIG+=qt\
thread\
warn_on
HEADERS+=MainWindow.h\
MessageWindow.h\
QespTest.h\
CommandWindow.h\
defs.h
SOURCES+=main.cpp\
MainWindow.cpp\
MessageWindow.cpp\
QespTest.cpp\
CommandWindow.cpp
TARGET=../bin/builtin
CONFIG(debug,debug|release):
LIBS+=-lqextserialportd
else:
LIBS+=-lqextserialport
unix:
DEFINES=_TTY_POSIX_
win32:
DEFINES=_TTY_WIN_
1.3.2.Qt工程编译
编译一个C++应用程序,你需要创建一个makefile。
创建一个Qt的makefile的最容易的方法是使用Qt提供的连编工具qmake。
如果你已经把main.cpp保存到它自己的目录了,你所要做的就是这些:
qmake-project
qmake
第一个命令调用qmake来生成一个.pro(项目)文件。
第二个命令根据这个项目
文件来生成一个(系统相关的)makefile。
你现在可以输入make(或者nmake,如
果你使用VisualStudio),然后运行你的第一个Qt应用程序!
1.4.程序实例
#include
intmain(intargc,char*argv[])
{
QApplicationapp(argc,argv);
QTextCodec:
:
setCodecForTr(QTextCodec:
:
codecForLocale());
QWidget*w=newQWidget;
QPushButton*pushButton=newQPushButton(tr(“退出”),w);
w->show();
QObject:
:
connect(pushButton,SIGNAL(clicked()),w,SLOT(close()));
returnapp.exec();
}
(1)初始化
QApplicationa(argc,argv);
在Qt应用程序中,首先要创建一个QApplication对象,QApplication类负责图形用户界面应用程序的控制流和主要设置。
它包含在main()函数的事件循环体中,对所有来自Window系统和其它源文件的事件进行处理和调度,还包括处理应用程序的初始化和结束,并且提供会话管理。
它还处理系统级和应用程序级的设置。
在Qt应用程序中,不管有多少个窗口,QApplication对象只能有一个,而且必须在其他对象之前创建。
(2)国际化
QTextCodec:
:
setCodecForTr(QTextCodec:
:
codecForLocale())
setCodecForTr函数可以设置QObject:
:
tr()的编码方式,如果采用默认值,则会是Latin-1.假若程序中出现的字符不是Latin-1编码方式,这个函数可以用来设置正确的编码方式。
而codecForLocale函数返回了本地区的编码方式的codec指针。
Qt使用Unicode(统一编码)来存储,绘制及操作字符串。
但在很多情况下你可能希望用不同的编码来处理数据。
所以Qt提供了一组QTextCodec类族来帮助用户将非Unicode格式与Unicode格式进行转换.你也可以创建自己的codec类。
(3)创建窗口
QWidget*pWidget=newQWidget();
QWidget是所有用户接口对象的基类。
部件是用户接口的基础:
它从窗口系统接收鼠标、键盘和其它事件,并在屏幕上绘制自身。
每个部件都是矩形的,并且以Z-order排列。
每个部件都处于其父部件和子部件之间。
一个没有父部件的部件称为一个窗口。
通常,窗口有一个边框和标题栏,当然也可以使用合适的标志来创建一个没有这些元素的窗口.在Qt中,QMainWindow以及Qdialog的各种子类是最常用的窗口类型。
每个部件的构造函数接受一个或两个标准的参数:
①第一个参数QWidget*parent=0是此部件的父部件,如果取默认值0,则新部件是一个窗口;如果不为0则它是parent的子部件,会被限制在parent的几何范围之内。
②第二个参数Qt:
:
WindowFlagsf=0设置窗口标志,默认值适应几乎所有的部件。
不过如果需要没有边框的窗口,则需要设置特殊的标志。
(4)创建组件
QPushButton*pushButton=newQPushButton(tr(“退出”),w);
添加子组件pushButton到父组件pWidget中;也可以用setWidget()方法实现。
pWidget->show();
从顶层部件开始,依次显示窗口中的各部件。
组件创建时一般是不可见的,这样的好处在于避免大量组件创建时造成的屏幕闪烁现象,要使组件可见需要调用QWidget类的成员函数show()来显示组件。
(5)注册事件(信号槽)
QObject:
:
connect(pushButton,SIGNAL(clicked()),w,SLOT(close()));
给按钮pushButton对象添加clicked信号的处理事件槽close,关闭窗口。
(6)执行返回
returnapp.exec();
进入主事件循环,直到调用exit(),quit()或关闭主窗口,程序必须调用此函数进入事件处理,主事件循环从窗口系统接收事件,并派送给相应的部件。
1.5.执行过程
整个Qt应用程序的执行过程
2.信号槽
(1)机制:
QT提供了信号和槽机制。
信号是一个特定的标识:
一个槽就是一个函数,与一般的函数不同,槽函数既能够和信号关联,又可以象普通函数一样直接调用。
当某个事件出现时,通过发送信号,可以将与之相关的槽函数激活,即执行槽函数代码。
信号和槽是宽松地联系在一起的:
一个发射信号的类不用知道也不用注意哪个槽要接收这个信号。
Qt的信号和槽的机制可以保证如果你把一个信号和一个槽连接起来,槽会在正确的时间使用信号的参数而被调用。
信号和槽可以使用任何数量、任何类型的参数。
它们是完全类型安全的:
不会再有回调核心转储(coredump)。
槽实际上是标准的成员函数(作为类成员的函数),因此可以直接调用它们;而且它们增加了一些特殊的功能使它们能够连接到信号。
每当槽所连接的信号被发射时,槽(函数)就被执行。
信号也是成员函数,但是,它们的实现有一点不同。
当对象内部发生某些事件时,它能够发出信号。
如果这个信号连接到槽,那么那个槽(函数)就被执行。
可以将多个槽连接到同一个信号,那么这些槽就将一个接一个地被执行,其执行顺序是任意的。
因此,信号是一种特殊类型的函数。
它们被定义为当某个事件发生时就被发射。
(2)前提:
信号/槽技术非常特殊。
实际上,需要特殊的编程语句才能创建信号和槽。
因此C++编译器不能理解这些语句,因此,完成这两项工作必须使用特殊的工具,即元对象编译器(metaobjectcomplier,MOC)。
这一工具扫描源文件中用于创建信号和槽的特殊语句,并将它生成为有效的C—++代码。
使用元对象编译器时,将自定义类声明放在头文件中,并在第一句加上宏Q_OBJECT;再使用qmake工具生成makefile,则makefile会自动调用moc工具对自定义信号和槽进行处理。
2.1.声明定义
ClassMyMainwindow:
publicQWidget
{
Q_OBJECT
Public:
MyMainwindow();
VoidsetValue(int);
Publicslots:
VoidChangeValue(int);
Signals:
VoidValueChanged(int);
}
注意:
(1)需要将类的声明单独放在一个头文件中
(2)凡是包含signal和slot的类中都要加上Q_OBJECT的定义
(3)使用qmake工具生成makefile,或者手动使用moc工具进行编译链接
(4)slots函数修饰符可以是private、protected、public,其意义和C++中相同。
(5)通常情况下,信号和槽的参数应该是匹配的,但有时一个信号所给出的信息比其已连接槽所需要的信息要多,则可根据需要配置参数类型(或无参数)。
VoidMyMainWindow:
:
setValue(intvalue)
{
if(value!
=oldvalue)
{
oldvalue=value;
emitvalueChanged(value);
}
}
注意:
信号和槽一类的普通函数不同,它只能使用emit关键字发射。
2.2.连接与取消
2.2.1.信号槽连接
在signal和slot声明以后,需要使用connect()函数将它们连接起来。
connect()函数属于QObject类的成员函数,它能够连接signal和slot,也可以用来连接signal和signal。
函数原形如下:
boolConnect(constQobject*sender,constchar*signal,constQobject*receiver,
constchar*method,Qt:
:
ConnectionTypetype=Qt:
:
AutoConnection)
(其中第参数1和参数3分别指出signal和slot是属于那个对象或组件,参数5为连接类型)
也可以使用SIGNAL()和SLOT()这两个宏,方法如下:
QObject:
:
connect(sender,SIGNAL(valueChanged(int)),recver,SLOT(setNum(int)));
(参数1为信号发送者,参数2为发送的信号,参数3为信号接收者,参数4为信号接收者的槽函数)
2.2.1.1.连接类型
信号槽的连接类型Qt:
:
connectionType有三种:
(1)Qt:
:
DirectConnection(立即连接):
信号发送后立即传递给相关的槽,只有槽函数执行完毕后返回后,发送信号emit之后的代码才被执行。
(2)Qt:
:
QueuedConnection(排队连接):
信号发送后排队,直到事件循环有能力将它传递给槽;而不管槽函数有无执行,发送信号之后的代码都会立即得到执行。
(3)Qt:
:
AutoConnection(自动连接):
如果信号和槽在同一线程,则等同于DirectConnection,如果不在同一线程,则信号将排队,等待事件循环的处理,等同于QueuedConnection。
2.2.1.2.连接方式
(1)一个信号连接一个槽
QObject:
:
connect(sender,SIGNAL(valueChanged(int)),recver,SLOT(setNum(int)));
(2)一个信号连接多个槽
QObject:
:
connect(sender,SIGNAL(valueChanged(int)),recver1,SLOT(setNum(int)));
QObject:
:
connect(sender,SIGNAL(valueChanged(int)),recver1,SLOT(change(int)));
QObject:
:
connect(sender,SIGNAL(valueChanged(int)),recver2,SLOT(update(int)));
(3)多个信号连接多一个槽
QObject:
:
connect(sender1,SIGNAL(valueChanged(int)),recver,SLOT(setNum(int)));
QObject:
:
connect(sender1,SIGNAL(update(int)),recver,SLOT(setNum(int)));
QObject:
:
connect(sender2,SIGNAL(valueChanged(int)),recver,SLOT(setNum(int)));
(4)一个信号连接另一个信号
QObject:
:
connect(sender,SIGNAL(valueChanged(int)),recver,SIGNAL(update(int)));
2.2.2.信号槽取消
函数原形如下:
QObject:
:
disconnect(sender,SIGNAL(overflow()),recver,SLOT(handleMathError()));
取消一个连接不是很常用,因为Qt会在一个对象被删除后自动取消这个对象所包含的所有的连接。
2.3.使用方法
2.3.1.手动连接
直接使用上述信号槽连接方式连接:
QObject:
:
connect(sender,SIGNAL(valueChanged(int)),recver,SLOT(setNum(int)));
2.3.2.自动连接
Qt的元对象提供了信号和槽的自动关联。
如果能够按照以下的规则命名槽函数,那么QT就能够自动进行关联:
voidon_<部件对象名>_<信号名>(<信号参数>);
例如:
privateslots:
voidon_browsePushBtn_clicked();
等价于
Connect(browsePushBtn,SIGNAL(clicked()),this,SLOT(browse()));
注意:
(自动连接的其它两个必要条件)
1.自动连接时,“on_”后面为对象名,而非对象变量名;也就是说,对象名和对象变量名可以不相同;对象变量通过setObjectName()方法来指定对象名。
2.要使用自动连接,就必须指定连接方式;通过调用QMetaObject:
:
connectSlotsByName()方法指明由对象名来解析信号槽连接。
且该方法必须放在对象定义之后才可使用。
2.4.扩展
(1)信号槽应用于对象间通信。
(2)信号槽的处理借助于moc(MetaObjectCompiler)工具,Q_OBJECT宏通知compiler使用moc工具进行moc扩展。
(3)对象中的信号不是真正的函数,编译时由moc自动产生,返回类型void,槽是函数。
(4)多个被触发者执行顺序随机。
(5)在非跨线程场景下,槽返回后,emit()才返回。
此时Object:
:
connect函数的ConncetionType参数为Qt:
:
DirectConnection。
(6)槽参数不能有缺省值。
(7)publicslots:
任何对象的信号或槽都可以触发;protectedslots:
当前类中的对象与子类中的对象的信号或槽可以触发;privateslots:
本类中定义的信号或槽可以触发。
(8)信号形参会全部传递给槽,但后者不一定全部接收。
(9)moc不扩展宏,所以信号与槽参数中不能包含宏。
(10)构造函数、嵌套类与友元类,不能在signals:
orslots:
区域内声明。
(11)typedef之前,函数指针与模板类不能作为槽的参数。
3.布局管理
QT中提供了布局管理器,可以使用它将子部件按水平或垂直方向排列起来。
它可以根据上层布局管理器或上层部件的空间来计算并分成若干个小盒子,然后将相应的部件放置其中(即可以自动调整子部件大小)。
3.1.布局类型
创建布局管理器最简单的方法是使用派生类,当然也可以直接使用基类来创建,然后指定其方向为LeftToRight,RightToLeft,TopToBottom,或者BottomToTop。
常用布局管理器的派生类:
(1)水平布局:
QHBoxLayout
(2)垂直布局:
QVBoxLayout
(3)网格布局:
QGridLayout(多行多列)
3.2.常用方法
(1)添加子布局管理器:
如果QBoxLayout不是顶层的布局管理器,则必须将其加入到它的上层布局管理器当中。
最常用的方法是:
parentLayout->addLayout().
(2)布局管理器添加部件:
⏹addWidget():
加入部件并设置其部件的拉伸系数。
⏹addSpacing():
创建一个空的小盒子,使得窗口部件之间布局更合理美观
⏹addStretch():
创建一个空的,可拉伸的小盒子。
⏹addLayout():
添加另一个布局管理器并设置其拉伸系数。
(3)布局管理器设置边距:
⏹setContentsMargins():
设置一个部件的外框与布局管理器四周的距离。
.
⏹setSpacing():
设置相邻的两个部件之间的间距。
(可以使用addSpacing()来加添间距)
(4)布局管理器移除部件:
⏹removeWidget():
移除一个部件
⏹QWidget:
:
hide():
也可以将部件从布局管理器移除,除非再次调用QWidget:
:
show()
4.Qt样式表
QT样式表是从QT4.2开始引入的窗口部件外观的机制,类似于HTML的层叠样式表。
通过调用QWidget:
:
setStyleSheet()或Application:
:
setStyleSheet(),你可以为一个独立的子部件、整个窗口,甚至是整个个应用程序指定一个样式表。
样式表是通过QStyle的一个叫做QStyleSheetStyle的特殊子类来实现的。
这个特殊的子类实际上是其他的系统特定风格类的包裹类,它会把通过样式表指定的自定义外观风格应用在底层的系统特定风格之上。
4.1.样式规则
样式表由一系列的样式规则构成,一个样式规则由选择器和属性组成。
语法形式如下:
selector{attribute:
value}
选择器(selecto
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- QT 界面 编程 解读
![提示](https://static.bdocx.com/images/bang_tan.gif)