第1章基本对话框.docx
《第1章基本对话框.docx》由会员分享,可在线阅读,更多相关《第1章基本对话框.docx(45页珍藏版)》请在冰豆网上搜索。
第1章基本对话框
第1章基本对话框
本章的实例对Qt编程的基本流程、标准对话框的使用方法以及Qt Designer的使用方法等进行了分析,包括11个实例:
1HelloWorld!
1标准对话框的使用
1各类位置信息
1使用标准输入框
1各种消息框的使用
1实现QQ抽屉效果
1表格的使用
1使用进度条
1利用QtDesigner设计一个对话框
1在程序中使用ui
1动态加载ui
实例1HelloWorld!
知识点:
1开发Qt程序的基本流程和编译运行方式
1信号和槽机制(Signal&Slot)
本实例实现一个“HelloWorld!
”例子,简单介绍Qt编程的基本流程,以及Qt程序的编译运行方式。
实例效果图如图1-1所示。
图1-1HelloWorld!
这是一个简单的例子,整个对话框只有一个按钮,单击该按钮,对话框关闭,退出程序。
实现代码如下:
1#include
2#include
3intmain(intargc,char*argv[])
{
4QApplicationapp(argc,argv);
5QPushButtonb("HelloWorld!
");
6b.show();
7QObject:
:
connect(&b,SIGNAL(clicked()),&app,SLOT(quit()));
8returnapp.exec();
}
第1行包括,所有Qt图形化应用程序都必须包含此文件,它包含了Qt图形化应用程序的各种资源、基本设置、控制流以及事件处理等,若是Qt的非图形化应用程序,则需包含。
小贴士:
Qt最初的框架只有关于图形化应用的类,随着它的一步步发展,Qt已独立发展出了许多非图形化的类库,如数据库应用、XML解析等。
第2行包含了程序中要应用到的按钮控件的头文件。
小贴士:
在Qt4中,头文件的包含可以采用类似和的形式,也可以写成和的形式。
第3行为应用程序的入口,所有Qt程序都必须有一个main()函数,以argc和argv作为入口参数。
第4行新创建了一个QApplication对象,每个Qt应用程序都必须有且只一个QApplication对象,采用argc、argv作为参数,便于程序处理命令行参数。
第5行创建了一个QPushButton对象,并设置它的显示文本为“HelloWorld!
”,由于此处并没有指定按钮的父窗体,因此以自己作为主窗口。
第6行调用show()方法,显示此按钮。
控件被创建时,默认是不显示的,必须调用show()函数来显示它。
第7行的QObject:
:
connect()方法是Qt最重要的特征,即信号与槽的机制。
当按钮被按下则触发clicked()信号发射,与之相连的QApplication对象的槽quit()响应按钮信号,执行退出应用程序的操作。
关于信号与槽机制在本实例最后将进行详细的分析。
最后调用QApplication的exec()方法,程序进入消息循环,等待可能输入进行响应。
Qt完成事件处理及显示的工作,并在应用程序退出时返回exec()的值。
Qt程序的编译运行很简单,利用Qt提供的qmake工具能够很方便地对程序进行编译,编译流程如下:
qmake–project
qmake
make
./hello
其中,qmake–project命令用于生成程序的项目文件(*.pro);qmake用于生成程序的Makefile文件;make编译Makefile文件得到可执行文件;最后执行程序即可出现图1-1所示的对话框,一个简单的HelloWorld!
例子完成。
小贴士:
确保Qt的环境变量路径设置正确,程序编译时若出现连接错误,请首先检查有关Qt的环境变量,保证调用的qmake为相应的Qt版本。
信号与槽机制(signal&slot)作为Qt最重要的特性,提供了任意两个Qt对象之间的通信机制。
其中,信号会在某个特定情况或动作下被触发,槽是用于接收并处理信号的函数。
例如,要将一个窗口中的变化情况通知给另一个窗口,则一个窗口发送信号,另一个窗口的槽接收此信号并进行相应的操作,即可实现两个窗口之间的通信。
这比传统的图形化程序采用回调函数的方式实现对象间通信要简单灵活得多。
每个Qt对象都包含预定的信号和槽,当某一特定事件发生时,一个信号被发射,与信号相关联的槽则会响应信号完成相应的处理。
信号与槽机制常用的连接方式为:
connect(Object1,SIGNAL(signal),Object2,SLOT(slot));
signal为对象Object1的信号,slot为对象Object2的槽,Qt的窗口部件都包含若干个预定义的信号和若干个预定义的槽。
当一个类被继承时,该类的信号和槽也同时被继承。
开发人员也可以根据需要定义自己的信号和槽。
信号与槽机制可以有多种连接方式,图1-2中描述了信号与槽的多种可能连接方式。
图1-2信号与槽的连接方式
①一个信号可以与另一个信号相连。
connect(Object1,SIGNAL(signal1),Object2,SIGNAL(signal1));
即表示Object1的信号1发射可以触发Object2的信号1发射。
②表示同一个信号可以与多个槽相连。
connect(Object1,SIGNAL(signal2),Object2,SIGNAL(slot2));
connect(Object1,SIGNAL(signal2),Object3,SIGNAL(slot1));
③表示同一个槽可以响应多个信号。
connect(Object1,SIGNAL(signal2),Object2,SIGNAL(slot2));
connect(Object3,SIGNAL(signal2),Object2,SIGNAL(slot2));
实例2标准对话框的使用
知识点:
1标准通用文件对话框的使用
1标准通用颜色对话框的使用
1标准通用字体对话框的使用
和大多数操作系统一样,Linux也提供了一系列的标准对话框,如文件选择、字体选择、颜色选择等,这些标准对话框为应用程序提供了一致的观感。
Qt对这些标准对话框都定义了相关的类,这些类让使用者能够很方便地使用标准对话框进行文件、颜色以及字体的选择。
标准对话框在软件设计过程中是经常需要使用的。
小贴士:
Qt提供的标准对话框除了本实例提到的,还有QErrorMessage、QInputDialog、QMessageBox、QPrintDialog、QProgressDialog等,这些标准对话框的使用在本书的后续部分将会陆续介绍。
本实例主要演示上面几种标准对话框的使用,如图1-3所示。
图1-3标准对话框
在图1-3中,单击“文件对话框”按钮,会弹出文件选择对话框,选中的文件名将显示在右边;单击“颜色对话框”按钮,会弹出颜色选择对话框,选中的颜色将显示在右边;单击“字体对话框”按钮,会弹出字体选择对话框,选中的字体将更新右边显示的字符串。
具体实现代码如下所示。
头文件standarddialogs.h:
classStandardDialogs:
publicQDialog
{
Q_OBJECT
public:
StandardDialogs(QWidget*parent=0,Qt:
:
WindowFlagsf=0);
~StandardDialogs();
public:
QGridLayout*layout;
QPushButton*filePushButton;
QPushButton*colorPushButton;
QPushButton*fontPushButton;
QLineEdit*fileLineEdit;
QLineEdit*fontLineEdit;
QFrame*colorFrame;
privateslots:
voidslotOpenFileDlg();
voidslotOpenColorDlg();
voidslotOpenFontDlg();
};
头文件定义了实例中需要用到的各种窗体控件以及各种操作的槽函数。
实现文件standarddialogs.cpp:
StandardDialogs:
:
StandardDialogs(QWidget*parent,Qt:
:
WindowFlagsf)
:
QDialog(parent,f)
{
1setWindowTitle(tr("StandardDialogs"));
2layout=newQGridLayout(this);
3filePushButton=newQPushButton;
4filePushButton->setText(tr("FileDialog"));
5colorPushButton=newQPushButton;
6colorPushButton->setText(tr("ColorDialog"));
7fontPushButton=newQPushButton;
8fontPushButton->setText(tr("FontDialog"));
9fileLineEdit=newQLineEdit;
10colorFrame=newQFrame;
11colorFrame->setFrameShape(QFrame:
:
Box);
12colorFrame->setAutoFillBackground(true);
13fontLineEdit=newQLineEdit;
14fontLineEdit->setText(tr("HelloWorld"));
15layout->addWidget(filePushButton,0,0);
16layout->addWidget(fileLineEdit,0,1);
17layout->addWidget(colorPushButton,1,0);
18layout->addWidget(colorFrame,1,1);
19layout->addWidget(fontPushButton,2,0);
20layout->addWidget(fontLineEdit,2,1);
21layout->setMargin(15);
22layout->setSpacing(10);
23connect(filePushButton,SIGNAL(clicked()),this,SLOT(slotOpenFileDlg()));
24connect(colorPushButton,SIGNAL(clicked()),this,SLOT(slotOpenColorDlg()));
25connect(fontPushButton,SIGNAL(clicked()),this,SLOT(slotOpenFontDlg()));
}
第1行设置主窗体的标题。
第2~8行分别创建各个按钮控件。
第9行创建一个QLineEdit类实例fileLineEdit,用来显示选择的文件名。
第10~12行创建一个QFrame类实例colorFrame,当用户选择不同的颜色时,colorFrame会根据用户选择的颜色更新其背景。
第13、14行创建一个QLineEdit类实例fontLineEdit,当用户选择不同的字体时,fontLineEdit会根据用户选择的字体更新其内容。
第15~22行将各个控件进行布局。
第23~25行将各个按钮的clicked事件与相应的槽进行连接。
voidStandardDialogs:
:
slotOpenFileDlg()
{
QStrings=QFileDialog:
:
getOpenFileName(
this,
"openfiledialog",
"/",
"C++files(*.cpp);;Cfiles(*.c);;Headfiles(*.h)");
lineEditFile->setText(s.toAscii());
}
getOpenFileName()是QFileDialog类的一个静态函数,返回用户选择的文件名,如果用户选择取消(Cancel),则返回一个空串。
函数形式如下:
QStringQFileDialog:
:
getOpenFileName(QWidget*parent=0,constQString&caption=QString(),constQString&dir=QString(),constQString&filter=QString(),QString*selectedFilter=0,Optionsoptions=0)
调用getOpenFileName()函数将创建一个模态的文件对话框,如图1-4所示。
dir参数指定了默认的目录,如果dir参数带有文件名,则该文件将是默认选中的文件;filter参数对文件类型进行过滤,只有与过滤器匹配的文件类型才显示,filter可以同时指定多种过滤方式供用户选择,多种过滤器之间用“:
:
”隔开,用户选择的过滤器通过参数selectedFilter返回。
图1-4标准文件对话框
文件对话框的文件类型选择如图1-5所示。
图1-5文件对话框的文件类型选择
QFileDialog类还提供了类似的其他静态函数,如表1-1所示,通过这些函数,用户可以很方便地定制自己的文件对话框。
表1-1QFileDialog的静态函数
静态函数
说明
getOpenFileName
获得用户选择的文件名
getSaveFileName
获得用户保存的文件名
getExistingDirectory
获得用户选择的已存在的目录名
getOpenFileNames
获得用户选择的文件名列表
voidStandardDialogs:
:
slotOpenColorDlg()
{
QColorcolor=QColorDialog:
:
getColor(Qt:
:
blue);
if(color.isValid())
{
frameColor->setPalette(QPalette(color));
}
}
getColor()是QColorDialog的一个静态函数,返回用户选择的颜色值,函数形式如下:
QColorgetColor(constQColor&initial=Qt:
:
white,QWidget*parent=0)
调用getColor()函数将创建一个模态的颜色对话框,如图1-6所示。
initial参数指定了默认选中的颜色,默认为白色。
通过QColor:
:
isValid()可以判断用户选择颜色是否有效,若用户选择取消(Cancel),QColor:
:
isValid()将返回false。
图1-6标准颜色对话框
voidStandardDialogs:
:
slotOpenFontDlg()
{
boolok;
QFontfont=QFontDialog:
:
getFont(&ok);
if(ok)
{
lineEditFont->setFont(font);
}
}
getFont()是QFontDialog的一个静态函数,返回用户选择的字体,函数形式如下:
QFontgetFont(bool*ok,QWidget*parent=0)
调用getFont()函数将创建一个模态的字体对话框,如图1-7所示。
用户选择OK,参数*ok将为true,函数返回用户选择的字体,否则为false,此时函数返回默认字体。
图1-7标准字体对话框
实例3各类位置信息
知识点:
1各种与位置相关函数的区别
1各种与位置相关函数的使用场合
Qt提供了很多关于获取窗体位置及显示区域大小的函数,本实例利用一个简单的对话框显示窗体的各种位置信息,包括窗体的所在点位置、长、宽信息等。
本实例的目的是分析各个有关位置信息的函数之间的区别,如x()、y()、pos()、rect()、size()、geometry()等,以及在不同的情况下应使用哪个函数来获取位置信息。
实现的效果图如图1-8所示。
图1-8各类位置信息
在实例中,分别调用了x()、y()、frameGeometry()、pos()、geometry()、width()、height()、rect()、size()几个函数,这几个函数均是QWidget提供的。
当改变对话框的大小,或移动对话框时,调用各个函数所获得的信息显示也相应地发生变化,从变化中可得知各函数之间的区别。
由于本实例的目的是为了分析各函数之间的区别并获得结论,而程序本身的实现较为简单,因此只简单介绍实现过程。
头文件geometry.h:
classGeometry:
publicQDialog
{
Q_OBJECT
public:
Geometry();
/*声明所需的控件主要为QLabel类*/
……
voidupdateLabel();
protected:
voidmoveEvent(QMoveEvent*);
voidresizeEvent(QResizeEvent*);
};
实现文件geometry.cpp:
Geometry:
:
Geometry()
{
setWindowTitle("Geometry");
/*创建程序所需的各控件*/
……
/*布局*/
……
updateLabel();
}
程序初始化时调用updateLabel()函数,以获得各位置函数的信息并显示。
具体代码如下:
voidGeometry:
:
updateLabel()
{
QStringtemp;
//获得x()函数的结果并显示
QStringstr_x;
xLabel->setText(str_x.setNum(x()));
//获得y()函数的结果并显示
QStringstr_y;
yLabel->setText(str_y.setNum(y()));
//获得frameGeometry()函数的结果并显示
QStringframeGeo;
frameGeo=temp.setNum(frameGeometry().x())+","+
temp.setNum(frameGeometry().y())+","+
temp.setNum(frameGeometry().width())+","+
temp.setNum(frameGeometry().height());
frameGeoLabel->setText(frameGeo);
//获得pos()函数的结果并显示
QStringposition;
position=temp.setNum(pos().x())+","+temp.setNum(pos().y());
posLabel->setText(position);
//获得geometry()函数的结果并显示
QStringgeo;
geo=temp.setNum(geometry().x())+","+
temp.setNum(geometry().y())+","+
temp.setNum(geometry().width())+","+
temp.setNum(geometry().height());
geoLabel->setText(geo);
//获得width()、height()函数的结果并显示
QStringw;
widthLabel->setText(w.setNum(width()));
QStringh;
heightLabel->setText(h.setNum(height()));
//获得rect()函数的结果并显示
QStringr;
r=temp.setNum(rect().x())+","+temp.setNum(rect().y())+","+
temp.setNum(rect().width())+","+temp.setNum(rect().height());
rectLabel->setText(r);
//获得size()函数的结果并显示
QStrings;
s=temp.setNum(size().width())+","+temp.setNum(size().height());
sizeLabel->setText(s);
}
updateLabel()函数负责调用各个位置函数获得结果并显示。
重定义QWidget的moveEvent()和resizeEvent()函数,分别响应对话框的移动事件和大小调整事件,使得窗体在被移动或窗体大小发生改变时,能同步更新各函数结果的显示。
具体代码如下:
voidGeometry:
:
moveEvent(QMoveEvent*)
{
updateLabel();
}
voidGeometry:
:
resizeEvent(QResizeEvent*)
{
updateLabel();
}
通过这个例子可以获得如图1-9所示的结论。
图1-9各位置函数获得结果的区别示意图
x()、y()和pos()函数都是获得整个窗体左上角的坐标位置。
而frameGeometry()与geometry()相对应,frameGeometry()是获得整个窗体的左上顶点和长、宽值,而geometry()函数获得的是窗体内中央区域的左上顶点坐标以及长、宽值。
直接调用width()和height()函数获得的是中央区域的长和宽的值。
还有两个函数rect()、size(),调用它们获得的结果也都是对于窗体的中央区域而言的,size()获得的是窗体中央区域的长、宽值,rect()与geometry()一样返回一个QRect对象。
其中,两个函数获得的长、宽值是一样的,都是窗体中央区域的长、宽值,只是左上顶点的坐标值不一样,geometry()获得的左上顶点坐标是相对于父窗体而言的坐标,而rect()获得的左上顶点坐标始终为(0,0)。
因此,在实际应用