QT界面编程(1)
QT编程基础
1.QT简介
1.1. 简介
(1)Qt是Trolltech公司的标志性产品,是一个跨平台的C++图形用户界面(GUI)工具包。它提供给应用程序开发者建立艺术级的图形用户界面所需的所有功能。Qt是完全面向对象的很容易扩展,并且允许真正地组件编程。
(2)Qt支持下述平台:
MS/Windows - 95、98、NT 4.0、ME、2000
Unix/X11 - Linux、Sun Solaris、HP-UX、Compaq Tru64 UNIX、IBM AIX、SGI IRIX和其它X11平台Macintosh - Mac OS X
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,为Visual Studio 生成一个应用程序工程。仅仅用语Windos操作系统.
⑤VC库vclib,为Visual Studio生成一个应用程序库工程,仅仅用语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,如
果你使用Visual Studio),然后运行你的第一个Qt 应用程序!
1.4. 程序实例
#include
int main(int argc,char* argv[])
{
QApplication app(argc,argv);
QTextCodec::setCodecForTr(QTextCodec::codecForLocale());
QWidget* w = new QWidget;
QPushButton* pushButton = new QPushButton (tr(“退出”), w);
w->show();
QObject::connect(pushButton, SIGNAL( clicked()), w, SLOT( close() ));
return app.exec();
}
(1)初始化
QApplication a(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=new QWidget();
QWidget是所有用户接口对象的基类。部件是用户接口的基础:它从窗口系统接收鼠标、键盘和其它事件,并在屏幕上绘制自身。每个部件都是矩形的,并且以Z-order排列。每个部件都处于其父部件和子部件之间。
一个没有父部件的部件称为一个窗口。通常,窗口有一个边框和标题栏,当然也可以使用合适的标志来创建一个没有这些元素的窗口. 在Qt中, QMainWindow 以及Qdialog的各种子类是最常用的窗口类型。
每个部件的构造函数接受一个或两个标准的参数:
①第一个参数QWidget *parent = 0是此部件的父部件,如果取默认值0,则新部件是一个窗口;如果不为0则它是parent的子部件,会被限制在parent的几何范围之内。
②第二个参数Qt::WindowFlags f = 0设置窗口标志,默认值适应几乎所有的部件。不过如果需要没有边框的窗口,则需要设置特殊的标志。
(4)创建组件
QPushButton* pushButton = new QPushButton (tr(“退出”), w);
添加子组件pushButton到父组件pWidget中;也可以用setWidget()方法实现。
pWidget->show();
从顶层部件开始,依次显示窗口中的各部件。组件创建时一般是不可见的,这样的好处在于避免大量组件创建时造成的屏幕闪烁现象,要使组件可见需要调用QWidget类的成员
函数show()来显示组件。
(5)注册事件(信号槽)
QObject::connect(pushButton, SIGNAL( clicked()), w, SLOT( close() ));
给按钮pushButton对象添加clicked信号的处理事件槽close,关闭窗口。
(6)执行返回
return app.exec();
进入主事件循环,直到调用exit(), quit()或关闭主窗口,程序必须调用此函数进入事件处理,主事件循环从窗口系统接收事件,并派送给相应的部件。
1.5. 执行过程
整个Qt应用程序的执行过程
2.信号槽
(1)机制:QT提供了信号和槽机制。信号是一个特定的标识:一个槽就是一个函数,与一般的函数不同,槽函数既能够和信号关联,又可以象普通函数一样直接调用。当某个事件出现时,通过发送信号,可以将与之相关的槽函数激活,即执行槽函数代码。
信号和槽是宽松地联系在一起的:一个发射信号的类不用知道也不用注意哪个槽要接收这个信号。Qt的信号和槽的机制可以保证如果你把一个信号和一个槽连接起来,槽会在正
确的时间使用信号的参数而被调用。信号和槽可以使用任何数量、任何类型的参数。它们是完全类型安全的:不会再有回调核心转储(core dump)。
槽实际上是标准的成员函数(作为类成员的函数),因此可以直接调用它们;而且它们增加了一些特殊的功能使它们能够连接到信号。每当槽所连接的信号被发射时,槽(函数)就被执行。
信号也是成员函数,但是,它们的实现有一点不同。当对象内部发生某些事件时,它能够发出信号。如果这个信号连接到槽,那么那个槽(函数)就被执行。可以将多个槽连接到同一个信号,那么这些槽就将一个接一个地被执行,其执行顺序是任意的。因此,信号是一种特殊类型的函数。它们被定义为当某个事件发生时就被发射。
(2)前提:信号/槽技术非常特殊。实际上,需要特殊的编程语句才能创建信号和槽。因此C++编译器不能理解这些语句,因此,完成这两项工作必须使用特殊的工具,即元对象编译器(meta object complier,MOC)。这一工具扫描源文件中用于创建信号和槽的特殊语句,并将它生成为有效的C—++代码。
使用元对象编译器时,将自定义类声明放在头文件中,并在第一句加上宏Q_OBJECT;再使用qmake工具生成makefile,则makefile会自动调用moc工具对自定义信号和槽进行处理。
2.1. 声明定义
Class MyMainwindow:public QWidget
{
Q_OBJECT
Public:
MyMainwindow();
Void setValue(int);
Public slots:
Void ChangeValue(int);
Signals:
Void ValueChanged(int);
}
注意:
(1)需要将类的声明单独放在一个头文件中
(2)凡是包含signal和slot的类中都要加上Q_OBJECT的定义
(3)使用qmake工具生成makefile,或者手动使用moc工具进行编译链接
(4)slots函数修饰符可以是private、protected、public,其意义和C++中相同。
(5)通常情况下,信号和槽的参数应该是匹配的,但有时一个信号所给出的信息比其已连接槽所需要的信息要多,则可根据需要配置参数类型(或无参数)。
V oid MyMainWindow::setValue(int value)
{
if(value!=oldvalue)
{
oldvalue=value;
emit valueChanged(value);
}
}
注意:信号和槽一类的普通函数不同,它只能使用emit关键字发射。
2.2. 连接与取消
2.2.1.信号槽连接
在signal和slot声明以后,需要使用connect()函数将它们连接起来。connect()函数属于QObject类的成员函数,它能够连接signal和slot,也可以用来连接signal和signal 。
函数原形如下:
bool Connect(const Qobject* sender, const char* signal, const Qobject* receiver, const char* method, Qt::ConnectionType type=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)), recver 2, 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 就能够自动进行关联: void on_<部件对象名>_<信号名>(<信号参数>);
例如:
private slots:
void on_browsePushBtn_clicked();
等价于
Connect(browsePushBtn,SIGNAL(clicked()),this,SLOT(browse()));
注意:(自动连接的其它两个必要条件)
1.自动连接时,“on_”后面为对象名,而非对象变量名;也就是说,对象名和对象变量名
可以不相同;对象变量通过setObjectName()方法来指定对象名。
2.要使用自动连接,就必须指定连接方式;通过调用QMetaObject::connectSlotsByName()
方法指明由对象名来解析信号槽连接。且该方法必须放在对象定义之后才可使用。
2.4. 扩展
(1)信号槽应用于对象间通信。
(2)信号槽的处理借助于moc(Meta Object Compiler)工具,Q_OBJECT 宏通知compiler使用moc工具进行moc扩展。
(3)对象中的信号不是真正的函数,编译时由moc自动产生,返回类型void,槽是函数。
(4)多个被触发者执行顺序随机。
(5)在非跨线程场景下,槽返回后,emit()才返回。此时Object::connect 函数的ConncetionType参数为Qt::DirectConnection。
(6)槽参数不能有缺省值。
(7)public slots:任何对象的信号或槽都可以触发;protected slots:当前类中的对象与子类中的对象的信号或槽可以触发;private slots:
本类中定义的信号或槽可以触发。
(8)信号形参会全部传递给槽,但后者不一定全部接收。
(9) moc 不扩展宏,所以信号与槽参数中不能包含宏。
(10)构造函数、嵌套类与友元类,不能在 signals: or slots: 区域内声明。
(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 }
选择器(selector)部分通常是一个类名(例如QComboBox),当然也还有其他的语法形式。它确定哪些窗口部件受规则影响。
属性(attribute)部分是一个样式表属性的名字,值(value)部分是赋给该属性的值。它说明了在窗口部件上应用哪些属性。
为了使用方便,我们还可以使用一种简化形式:
selector1, selector2, ..., selectorM {
attribute1: value1;
attribute2: value2;
...
attributeN: valueN;
}
注:
1.在有的资料中,选择器被叫作选择符;属性被叫作定义。
2.Qt样式表对大小写不敏感;但对类名、对象名和属性名大小写敏感。(即对属性值不区
分大小写)
4.2. 特殊样式规则
4.2.1.伪状态样式
部件的外观可以按照用户界面元素状态的不同来分别定义,这在样式表中被称为“伪状态”。选择器可以包含伪状态来表示窗口部件的状态,如以下定义了鼠标在QPushButton上悬停时的规则:QPushButton:hover {color:white}
下面是可用的伪状态列表:
伪状态描述
:checked button部件被选中
:disabled 部件被禁用
:enabled部件被启用
:focus 部件获得焦点
:hover鼠标位于部件上
:indeterminate checkbox或radiobutton被部分选中
:off 部件可以切换,且处于off状态
:on部件可以切换,且处于on状态
:pressed部件被鼠标按下
:unchecked button部件未被选中
4.2.2.子部件微观样式
许多部件都包含有子元素,这些元素可以称为“子部件”。Spin box的上下箭头就是子部件最好的例子。
子部件可以通过“::”来指定,例如QDateTimeEdit::up-button。定义子部件的样式与定义部件非常相似,它们可以拥有自己的边框、背景等,并且也可以和伪状态联合使用(例如QSpinBox::up-button:hover)。
下表列出了可用的子部件类型:
子部件描述
::down-arrow combo box或spin box的下拉箭头
::down-button spin box的向下按钮
::drop-down combo box的下拉箭头
::indicator checkbox、radio button或可选择group box的指示器
::item menu、menu bar或status bar的子项目
::menu-indicator push button的菜单指示器
::title group box的标题
::up-arrow spin box的向上箭头
::up-button spin box的向上按钮
通过指定subcontrol-position和subcontrol-origin属性,子部件可以被放置在部件内的任何位置。并且,子部件的位置还可以使用相对或绝对的方式进一步的调整。具体选择何种
调整方式取决于子部件具有固定的大小,还是会随着父部件而变化。
4.2.2.1.相对定位
相对定位适合于子部件具有固定大小的情形(通过width和height指定子部件大小)。使用这种方式,子部件可以以相对于subcontrol-position和subcontrol-origin属性定义的原始位置进行移动调整。例如:
QPushButton::menu-indicator {
image: url(menu_indicator.png);
width: 13px;
height: 13px;
subcontrol-origin: padding;
subcontrol-position: bottom right;
}
当按下按钮时,我们可以把菜单指示器从原来的位置向右下方移动几个像素来模拟按钮按下的状态。
QPushButton::menu-indicator:pressed {
position: relative;
top: 2px;
left: 2px;
}
4.2.2.2.绝对定位
绝对定位适合于子部件的位置随父部件的变化而变的情形。与前面的例子相同,subcontrol-origin定义了父部件的参考矩形。子部件的矩形区域则可以随后通过相对于这个参考矩形四边的偏移量来定义。
QPushButton::menu-indicator {
border: 2px solid red;
subcontrol-origin: padding;
position: absolute;
top: 2px;
right: 2px;
bottom: 2px;
left: 40px;
}
对于宽度或高度固定的子部件,subcontrol-position被用来说明其在subcontrol-origin指定矩形内的对其方式:
QPushButton::menu-indicator {
image: url(menu_indicator.png);
width: 13px;
subcontrol-origin: padding;
subcontrol-position: bottom right;
position: absolute;
top: 2px;
bottom: 2px;
right: 2px;
}
4.2.3.层叠样式
样式表可以在QApplication级别设置,也可以在父窗口部件,子窗口部件级别设置。实际应用样式时,则合并这几个级别的样式。当有冲突时,窗口部件自身的样式优先使用,接下来是父窗口部件,祖先窗口部件,依次类推。
4.3. 样式冲突解决
当不同的规则应用到相同的属性时,样式表就产生了冲突。在这种情况下,特定的规则比通用的规则优先;伪状态比没有伪状态的优先,如果级别相同,则最后一个规则优先。
5.Qt组件类
5.1. 主要基类
5.1.1.Qobject类
QObject类是所有能够处理signal、slot和事件的Qt对象的基类,原形如下:QObject::QObject ( QObject * parent =0, const char * name = 0 ) 创建带有父对象及其名字的对象,对象的父对象可以看作为这个对象的所有者。比如,对话框是其中的ok和cancel按钮的父对象。
在上面的函数中如果parent为0则构造一个无父的对象,如果对象是一个组件,则它就会成为顶层的窗口。
QApplication和QWidget都是QObject类的子类。
5.1.2.Qapplication类
QApplication类负责GUI应用程序的控制流和主要的设置,它包括主事件循环体,负责处理和调度所有来自窗口系统和其他资源的事件,并且处理应用程序的开始、结束以及会话管理,还包括系统和应用程序方面的设置。对于一个应用程序来说,建立此类的对象是必不可少的。
5.1.3.Qwidget类
QWidget类是所有用户接口对象的基类,它继承了QObject类的属性。组件(或部件)是用户界面的单元组成部分,它接收鼠标、键盘和其它从窗口系统来的事件,并把它自己绘制在屏幕上.
QWidget类有很多成员函数,但一般不直接使用,而是通过子类继承来使用其函数功能。如,QPushButton、QlistBox等都是它的子类.
5.2. 常用组件类
常用组件类几乎都继承至QWidget类,可调用其继承来的方法。常用组件类都可直接使用其对象,也可继承自定义类对象。
5.2.1.QLebal类
标签类QLebal,为输出组件类;可将组件内容输出显示在屏幕上。
常用方法:
QLabel(QWidget *parent=0, Qt::WindowFlags f=0);
QLabel(const QString &text, QWidget *parent=0, Qt::WindowFlags f=0);
QString text() const;
const QPixmap *pixmap() const;
槽:
void setText(const QString &);
void setPixmap(const QPixmap &);
5.2.2.QlineEdit类
文本框类QlineEdit,为输入组件类;可从组件中获取输入内容。
常用方法:
QLineEdit(QWidget* parent=0);
QLineEdit(const QString &, QWidget* parent=0);
QString text() const;
QString displayText() const;
int maxLength() const;
void setMaxLength(int);
bool isReadOnly() const;
void setReadOnly(bool);
槽:
void setText(const QString &);
void clear();
void selectAll();
信号:
void textChanged(const QString &);
void textEdited(const QString &);
5.2.3.QTextEdit类
文本编辑区类QtextEdit,为输入组件类;可获取组件内文本编辑区中的内容。常用方法:
QTextEdit(QWidget *parent = 0);
QTextEdit(const QString &text, QWidget *parent = 0);
void setTextCursor(const QTextCursor &cursor);
QTextCursor textCursor() const;
bool isReadOnly() const;
void setReadOnly(bool ro);
槽:
void setPlainText(const QString &text);
void setText(const QString &text);
void cut();
void copy();
void paste();
void clear();
void selectAll();
void append(const QString &text);
信号:
void textChanged();
void copyAvailable(bool b);
void selectionChanged();
5.2.4.QComboBox类
下拉列表框类QcomboBox,为输入组件类;可获取用户选择的列表项。常用方法:
QComboBox(QWidget *parent = 0);
int count() const;
void setIconSize(const QSize &size);
bool isEditable() const;
void setEditable(bool editable);
int currentIndex() const;
QString currentText() const;
QString itemText(int index) const;
QIcon itemIcon(int index) const;
void addItems(const QStringList &texts)
void insertItems(int index, const QStringList &texts);
void removeItem(int index);
槽:
void clear();
void setCurrentIndex(int index);
信号:
void activated(int index);
void activated(const QString &);
void currentIndexChanged(int index);
void currentIndexChanged(const QString &);
5.2.5.QpushButton类
按钮类QpushButton,通常为信号(或事件)发起者。
常用方法:
QPushButton(QWidget *parent=0);
QPushButton(const QString &text, QWidget *parent=0);
QPushButton(const QIcon& icon, const QString &text, QWidget *parent=0); void setText(const QString &text);
QString text() const;
void setIcon(const QIcon &icon);
QIcon icon() const;bool isChecked() const;
槽:
void click();
void setChecked(bool);
信号:
void pressed();
void released();
void clicked(bool checked = false);
5.2.
6.QDialog类
(1)文件对话框QfileDialog,常用方法:
static QString getOpenFileName(QWidget *parent = 0,
const QString &caption = QString(),
const QString &dir = QString(),
const QString &filter = QString(),
QString *selectedFilter = 0,
Options options = 0);
static QString getSaveFileName(QWidget *parent = 0,
const QString &caption = QString(),
const QString &dir = QString(),
const QString &filter = QString(),
QString *selectedFilter = 0,
Options options = 0);
(2) 颜色对话框QcolorDialog,常用方法:
static QColor getColor(const QColor &initial = Qt::white, QWidget *parent = 0);
(3) 字体对话框QfontDialog,常用方法:
static QFont getFont(bool *ok, QWidget *parent = 0);
5.2.7.QMessageBox类
(1)Question询问消息框,常用方法:
static int question(QWidget *parent, const QString &title,
const QString& text,
int button0, int button1 = 0, int button2 = 0);
(2)Information操作提示消息框,常用方法:
static int information(QWidget *parent, const QString &title,
const QString& text,
int button0, int button1 = 0, int button2 = 0);
(3)Warning警告消息框,常用方法:
static int warning(QWidget *parent, const QString &title,
const QString& text,
int button0, int button1, int button2 = 0);
(4)Critical严重错误消息框,常用方法:
static int critical(QWidget *parent, const QString &title,
const QString& text,
int button0, int button1, int button2 = 0);
(5)About信息提示框,常用方法:
static void about(QWidget *parent, const QString &title, const QString &text);
(6)aboutQt QT信息提示框,常用方法:
static void aboutQt(QWidget *parent, const QString &title = QString());
5.2.8.QMainWindow类
QmainWindow类提供了一个应用程序主窗口,包括一个菜单栏,多个工具栏,多个锚接部件,一个状态栏,以及一个中心部件。
菜单是一系列命令的列表.为了实现菜单,工具栏按钮,键盘快捷方式等命令的一致性,QT 使用Action来表示这些命令。QT的菜单就是由一系列的Qaction动作对象构成的列表.
状态栏通常显示GUI应用程序的一些状态信息,它位于主窗口的最底部.可以在状态栏上添加使用QT窗口部件。一个主窗口最多只有一个状态栏。
工具栏是由一系列的类似于按钮的动作排列而成的面板.它通常有一些经常使用的命令(动作)组成.一个主窗口可以包含多个工具栏。
锚接部件作为一个窗口来使用,以包容其他窗口部件来实现某些功能.一个主窗口可以包含多个锚接部件.
中心部件处在锚接部件的内部,主窗口的中心.一个主窗口只有一个中心部件.
注意:
主窗口具有自己的布局管理器,因此有QMainWindow窗口上设置布局管理器或者创建一个父窗口部件为QMainWindow的布局管理器都是不允许的.
常用方法:
QMenuBar *menuBar() const;
void setMenuBar(QMenuBar *menubar);
QStatusBar *statusBar() const;
void setStatusBar(QStatusBar *statusbar);
QWidget *centralWidget() const;
void setCentralWidget(QWidget *widget);
void addToolBar(QToolBar *toolbar);
void removeToolBar(QToolBar *toolbar);
6.事件处理
在程序中,敲击键盘,鼠标指针在窗口中的移动或鼠标按键动作等,都是事件;大多数事件是作为用户行为的响应而产生的,但也有例外,如定时器、网络数据之类的事件则是由系统单独产生的。
6.1. 事件机制
通常图形界面系统采用回调的事件处理方式。它通过翻译表,将事件映射为相应的动作,当组件得到事件通知,就去表中找出相应的动作例程进行处理。这种机制需要应用程序注册有关组件的回调函数或普通的事件处理函数,以分发循环的事件。 Qt 中事件是从QEvent 继承来的对象,它表示应用程序内部或外部发生了某些应用程序所必须知道的事情。任何从QObject 类派生出的对象均可同过Qobject::event()方法接收事件。事件产生时,Qt 会创建一个合适的Qevent 对象或子对象,然后通过调用Qobject 类的event()函数将这个事件对象传给特定的Qobject 对象或子对象。需要说明的是,event()函数自身并不处理事件,而是根据事件类型调用相应的事件处理器,其返回值告知这个事件是否被接受并进行处理。 Qt 事件的处理过程:QApplication 的事件循环体从事件队列中拾取本地窗口系统事件或其他事件,译成QEvent(),并送给QObject::event(),最后送给QWidget::event()本别对事件处理
需要注意是的,不应该混淆事件和信号这两个概念。通常在使用已有部件时,信号是十分有用的;而自定义新的窗口部件时,事件则更为重要。举例来讲,当使用QpushButton 类时,我门往往只关注其clicked 信号,而很少关心其底层鼠标或键盘事件;但当自定义时,则需要编写代码来处理鼠标或键盘事件,并发送clicked 信号。从这个角度讲,事件比信号更底层。
6.2. 事件处理方法
Qt 提供了处理事件的五种方式: 1. 重新实现特定是事件处理器
事件处理循环部分
重新实现已定义的事件处理器是进行事件处理的最简单方式。
2.重新实现Qobject::event()函数.
通过重新实现event()函数,可以在事件到达特定的事件处理器之前截获并处理它们。这种方法可以用来覆盖已定义事件的默认处理方式,也可以用来处理QT中尚未定义特定事件处理器的事件。
3.在Qobject中注册事件过滤器
如果对象使用installEventFilter()函数注册了事件过滤器,目标对象中的所有事件将首先发给这个监视对象的eventFilter()函数。
4.在Qapplication中注册事件过滤器
如果一个事件过滤器被注册到程序中唯一的Qapplication对象,应用程序中所有对象的每一个事件都会在它们被送达其它事件过滤器前,首先抵达这个eventFilter()函数。它可以用来处理一些通常被Qapplication忽略的事件,如发给生效窗口的鼠标事件。
5.继承Qapplication并重新实现notify()函数
Qt调用Qapplication来发送一个事件。重新实现notify()函数是在事件过滤器得到所有事件之前获得它们的唯一方法。但事件过滤器更为便利,因为可以有多个事件过滤器,而notify()函数只有一个。
6.3. 事件过滤器
QT事件模型中一项非常强大的功能是一个Qobject对象可以监视另一个Qobject对象的事件,实现方法是在目标对象中安装事件过滤器。这样事件过滤器将在事件到达目标对象之前首先截获该事件,从而起到监视目标对象事件的效果。
6.4. 加快用户界面响应
Qt中加快用户界面响应有三种方法:
(1) 使用线程;一个线程处理应用程序用户界面的响应,另一线程处理特定事件的耗时操作。
(2) 在处理耗时操作时,频繁调用Qapplication::processEvents();
(3) 推迟耗时事件处理,直到应用程序空闲下来。
6.5. 事件与信号的区别
(1)事件处理函数的返回值是有意义的,我们要根据这个返回值来确定是否还要继续事件的处理,比如在QT中,事件处理函数如果返回true,则这个事件处理已完成,QApplication会接着处理下一个事件,而如果返回false,那么事件分派函数会继续向上寻找下一个可以处理该事件的注册方法。信号处理函数的返回值对信号分派器来说是无意义的。