09计科A23430110陈南博实训二.docx

上传人:b****6 文档编号:5607643 上传时间:2022-12-29 格式:DOCX 页数:22 大小:276.93KB
下载 相关 举报
09计科A23430110陈南博实训二.docx_第1页
第1页 / 共22页
09计科A23430110陈南博实训二.docx_第2页
第2页 / 共22页
09计科A23430110陈南博实训二.docx_第3页
第3页 / 共22页
09计科A23430110陈南博实训二.docx_第4页
第4页 / 共22页
09计科A23430110陈南博实训二.docx_第5页
第5页 / 共22页
点击查看更多>>
下载资源
资源描述

09计科A23430110陈南博实训二.docx

《09计科A23430110陈南博实训二.docx》由会员分享,可在线阅读,更多相关《09计科A23430110陈南博实训二.docx(22页珍藏版)》请在冰豆网上搜索。

09计科A23430110陈南博实训二.docx

09计科A23430110陈南博实训二

上海第二工业大学计算机科学与技术系

学生实训报告

课程名称

嵌入式操作系统课程设计

实训类别

验证型

实训项目名称

创建对话框

班级

09计科A2

姓名

陈南博

学号

20113430110

实训时间

2012年10月24日

实训地点

15号楼507

指导教师

崔莉莉

组号

同组学生信息(请填写在下方)

班级

姓名

学号

一、实训内容、结果与分析

1.完成书本第二部分“创建对话框”中的2.1例题find、2.3例题gotocell、2.4例题sort,其中报告提交find或sort其中一个的代码解释,给出利用Qtdesigner设计gotocell的主要过程和步骤。

三个程序运行结果

2.1Find:

2.3Gotocell:

2.4Sort:

Find的代码及解释:

先看finddialog.h

#ifndefFINDDIALOG_H“防止对这个文件的多重包含”

#defineFINDDIALOG_H书上是这么解释我看了几遍是没看懂什么意思

后来问了老师明白了,是用于自己定义的头文件——防止重复定义

#include声明QDialog类

classQCheckBox;简单申明QCheckBox类的存在

classQLabel;简单申明QLabel类的存在

classQLineEdit;简单申明QLineEdit类的存在

classQPushButton;简单申明QPushButton类的存在

classFindDialog:

publicQDialog定义Finddialog作为QDialog的一子类

{

Q_OBJECT对已定义了信号和槽的类,在类定义开始出的Q_OBJECT宏定义是必须的

public:

FindDialog(QWidget*parent=0,constchar*name=0);parent是父类窗口部件,name是这个窗口部件的名称

signals:

信号

voidfindNext(constQString&str,boolcaseSensitive);findNext信号定义

voidfindPrev(constQString&str,boolcaseSensitive);findPrev信号定义

privateslots:

voidfindClicked();定义findclicked槽

voidenableFindButton(constQString&text);定义enableFindButton槽

private:

声明一些私有成员

QLabel*label;声明label成员

QLineEdit*lineEdit;

QCheckBox*caseCheckBox;这几个不再累述

QCheckBox*backwardCheckBox;

QPushButton*findButton;

QPushButton*closeButton;

};

#endif与第一第二行相对应

 

接下来看finddialog.cpp:

#include头文件的声明

#include

#include

#include“<>”优先查找系统库,系统头文件

#include

#include"finddialog.h"“”””优先查找相对路径的声明头文件

FindDialog:

:

FindDialog(QWidget*parent,constchar*name)

:

QDialog(parent,name)parent和name传递给基类的构造函数

{

setCaption(tr("Find"));设置窗口标题

label=newQLabel(tr("Find&what:

"),this);新建基于QLabel的label

lineEdit=newQLineEdit(this);新建基于QLineEdit的lineEdit

label->setBuddy(lineEdit);建立关系label与lineedit

caseCheckBox=newQCheckBox(tr("Match&case"),this);新建基于QCheckBox的caseCheckBox

backwardCheckBox=newQCheckBox(tr("Search&backward"),this);新建基于QCheckBox的backwardCheckBox

findButton=newQPushButton(tr("&Find"),this);“&”用于加速键

findButton->setDefault(true);findButton设置为”缺省”

findButton->setEnabled(false);findButton设置为”不可选”

closeButton=newQPushButton(tr("Close"),this);新建基于QPushButton的closeButton

connect(lineEdit,SIGNAL(textChanged(constQString&)),

this,SLOT(enableFindButton(constQString&)));信号lineedit发生调用就调用槽enableFindButton

connect(findButton,SIGNAL(clicked()),

this,SLOT(findClicked()));信号findButton发生clicked()就调用槽findClicked()

connect(closeButton,SIGNAL(clicked()),

this,SLOT(close()));信号closeButton发生clicked()就调用槽close()

QHBoxLayout*topLeftLayout=newQHBoxLayout;新建一个名为topLeftLayout的QHBoxLayou框架

topLeftLayout->addWidget(label);把label放入框架topLeftLayout

topLeftLayout->addWidget(lineEdit);把lineEdit放入框架topLeftLayout

QVBoxLayout*leftLayout=newQVBoxLayout;新建一个名为leftLayout的QHBoxLayou框架

leftLayout->addLayout(topLeftLayout);把topLeftLayout放入框架leftLayout

leftLayout->addWidget(caseCheckBox);把caseCheckBox放入框架leftLayout

leftLayout->addWidget(backwardCheckBox);把backwardCheckBox放入框架leftLayout

QVBoxLayout*rightLayout=newQVBoxLayout;新建一个名为rightLayout的QHBoxLayou框架

rightLayout->addWidget(findButton);把findButton放入框架rightLayout

rightLayout->addWidget(closeButton);把closeButton放入框架rightLayout

rightLayout->addStretch

(1);设置一个弹簧放入框架rightLayout

QHBoxLayout*mainLayout=newQHBoxLayout(this);新建一个名为mainLayout的QHBoxLayou框架

mainLayout->setMargin(11);设置mainLayout边缘

mainLayout->setSpacing(6);设置mainLayout空隙

mainLayout->addLayout(leftLayout);把leftLayout放入框架mainLayout

mainLayout->addLayout(rightLayout);把rightLayout放入框架mainLayout

}

voidFindDialog:

:

findClicked()findclicked槽用于find按键的clicked事件

{

QStringtext=lineEdit->text();linedit的值赋予text()

boolcaseSensitive=caseCheckBox->isOn();打开caseCheckBox

if(backwardCheckBox->isOn())如果backwardCheckBox打开

emitfindPrev(text,caseSensitive);发射findprev信号

else

emitfindNext(text,caseSensitive);否则发射findNext信号

}

voidFindDialog:

:

enableFindButton(constQString&text)enableFindButton槽定义

{

findButton->setEnabled(!

text.isEmpty());lineEdit不为空,find按钮生效

}

Main.cpp:

#include头文件

#include"finddialog.h"头

intmain(intargc,char*argv[])声明

{

QApplicationapp(argc,argv);

FindDialog*dialog=newFindDialog;新建

app.setMainWidget(dialog);

dialog->show();dialog可见

returnapp.exec();运行exe

}

 

设计gocell主要过程:

QT创建一个dialog

1添加一个文本标签,设置name属性为label,text为&CellLocation:

2添加行编辑器,name-lineedit

3添加间隔期,orientation-horizontal

4添加第一个按钮,name-okbutton,enable-false,default-ture,text-OK

5添加第二个按钮,name-cancelButton,text-Cancel

6窗体本身,name-GoToCellDialog,caption-GotoCell

使用Tools|SetBuddy设置label和edit的伙伴关系

摆放部件

1单击打Celllocation标签下的shift,单击layout|layouthorizontally

2单击间隔器与2个button,使用layout|layouthorizontally

3单击背景取消任何选择,使用layout|layouthorizontally

4单击使用layout|adjustsize

单击tool|taborder设置tab时的空间选中顺序

设置信号与槽

单击edit|connections设计如下

enableOKbutton需要

新建如下

在工程下新建一个main.cpp文件:

#include

#include"gotocelldialog.h"

intmain(intargc,char*argv[])

{

QApplicationapp(argc,argv);

GoToCellDialog*dialog=newGoToCellDialog;

app.setMainWidget(dialog);

dialog->show();

returnapp.exec();

}

生成之后有问题,OK失效行编辑器接受任何文本,而不是接受有效的单元格定位。

结果:

2.理解2.2节“信号与槽”相关内容,查阅资料,写出大约一页A4纸的小论文(字号为五号,行间距为单倍),要求有自己对“信号与槽”的概念理解。

红色是干要部分,黑色是扩充补充,因为原文的逻辑性和语言比较慎密,感觉如果剪切顺序可能并没有原文表达的好,我会扩充一些,我是认真去查看过资料的,并不是随便网上随便拉一篇应付的。

信号和槽是QT自行定义的一种通信机制,它独立于标准的C/C++语言,因此要正确的处理信号和槽,必须借助一个称为moc(MetaObjectCompiler)的QT工具,该工具是一个C++预处理程序,它为高层次的事件处理自动生成所需要的附加代码。

窗口小部件(widget)都有一个回调函数用于响应它们能触发的每个动作,这个回调函数通常是一个指向某个函数的指针。

但是,在QT中信号和槽取代了这些凌乱的函数指针,使得我们编写这些通信程序更为简洁明了。

信号和槽能携带任意数量和任意类型的参数,他们是类型完全安全的,不会像回调函数那样产生coredumps。

所有从QObject或其子类(例如Qwidget)派生的类都能够包含信号和槽。

当对象改变其状态时,信号就由该对象发射(emit)出去,这就是对象所要做的全部事情,它不知道另一端是谁在接收这个信号。

这就是真正的信息封装,它确保对象被当作一个真正的软件组件来使用。

槽用于接收信号,但它们是普通的对象成员函数。

一个槽并不知道是否有任何信号与自己相连接。

而且,对象并不了解具体的通信机制。

可以将很多信号与单个的槽进行连接,也可以将单个的信号与很多的槽进行连接,甚至于将一个信号与另外一个信号相连接也是可能的,这时无论第一个信号什么时候发射系统都将立刻发射第二个信号。

信号

当某个信号对其客户或所有者发生的内部状态发生改变,信号被一个对象发射。

只有定义过这个信号的类及其派生类能够发射这个信号。

当一个信号被发射时,与其相关联的槽将被立刻执行,就象一个正常的函数调用一样。

只有当所有的槽返回以后发射函数(emit)才返回。

如果存在多个槽与某个信号相关联,那么,当这个信号被发射时,这些槽将会一个接一个地执行,但是它们执行的顺序将会是随机的、不确定的,我们不能人为地指定哪个先执行、哪个后执行。

信号的声明是在头文件中进行的,QT的signals关键字指出进入了信号声明区,随后即可声明自己的信号。

例如,下面定义了三个信号:

signals:

voidmySignal();

voidmySignal(intx);

voidmySignalParam(intx,inty);

在上面的定义中,signals是QT的关键字,而非C/C++的。

接下来的一行voidmySignal()定义了信号mySignal,这个信号没有携带参数;接下来的一行voidmySignal(intx)定义了重名信号mySignal,但是它携带一个整形参数,这有点类似于C++中的虚函数。

从形式上讲信号的声明与普通的C++函数是一样的,但是信号却没有函数体定义,另外,信号的返回类型都是void,不要指望能从信号返回什么有用信息。

信号由moc自动产生,它们不应该在.cpp文件中实现。

当一个槽为一个信号来执行的时候,这个返回值就会忽略,但是把槽作为一个函数来调用的时候,返回值对我们的作用和我们调用一个普通的C++函数一样。

槽是普通的C++成员函数,可以被正常调用,它们唯一的特殊性就是很多信号可以与其相关联。

当与其关联的信号被发射时,这个槽就会被调用。

槽可以有参数,但槽的参数不能有缺省值。

既然槽是普通的成员函数,因此与其它的函数一样,它们也有存取权限。

槽的存取权限决定了谁能够与其相关联。

同普通的C++成员函数一样,槽函数也分为三种类型,即publicslots、privateslots和protectedslots。

publicslots:

在这个区内声明的槽意味着任何对象都可将信号与之相连接。

这对于组件编程非常有用,你可以创建彼此互不了解的对象,将它们的信号与槽进行连接以便信息能够正确的传递。

protectedslots:

在这个区内声明的槽意味着当前类及其子类可以将信号与之相连接。

这适用于那些槽,它们是类实现的一部分,但是其界面接口却面向外部。

privateslots:

在这个区内声明的槽意味着只有类自己可以将信号与之相连接。

这适用于联系非常紧密的类。

槽也能够声明为虚函数,这也是非常有用的。

槽的声明也是在头文件中进行的。

信号与槽的关联

最简单的信号与槽的关联:

控件事件——send信号——单目标槽接受——目标控件做出相应

单信号与多槽的关联:

控件事件——send信号——多个目标槽接受——多个目标控件做出相应

信号与信号关联:

控件事件——send信号——目标接受——目标send信号

通过调用QObject对象的connect函数来将某个对象的信号与另外一个对象的槽函数相关联,这样当发射者发射信号时,接收者的槽函数将被调用。

该函数的定义如下:

boolQObject:

:

connect(constQObject*sender,constchar*signal,

constQObject*receiver,constchar*member)[static]

这个函数的作用就是将发射者sender对象中的信号signal与接收者receiver中的member槽函数联系起来。

当指定信号signal时必须使用QT的宏SIGNAL(),当指定槽函数时必须使用宏SLOT()。

如果发射者与接收者属于同一个对象的话,那么在connect调用中接收者参数可以省略。

一个信号甚至能够与另一个信号相关联,

connect(aButton,SIGNAL(clicked()),SIGNAL(aSignal()));

当信号与槽没有必要继续保持关联时,我们可以使用disconnect函数来断开连接。

其定义如下:

boolQObject:

:

disconnect(constQObject*sender,constchar*signal,

constObject*receiver,constchar*member)[static]

这个函数断开发射者中的信号与接收者中的槽函数之间的关联。

有三种情况必须使用disconnect()函数:

断开与某个对象相关联的任何对象。

这似乎有点不可理解,事实上,当我们在某个对象中定义了一个或者多个信号,这些信号与另外若干个对象中的槽相关联,如果我们要切断这些关联的话,就可以利用这个方法,非常之简洁。

disconnect(myObject,0,0,0)或者myObject->disconnect()

断开与某个特定信号的任何关联。

disconnect(myObject,SIGNAL(mySignal()),0,0)或者myObject->disconnect(SIGNAL(mySignal()))

断开两个对象之间的关联。

disconnect(myObject,0,myReceiver,0)或者myObject->disconnect(myReceiver)

在disconnect函数中0可以用作一个通配符,分别表示任何信号、任何接收对象、接收对象中的任何槽函数。

但是发射者sender不能为0,其它三个参数的值可以等于0。

我昨晚实验后有个疑问,每个例题编译完之后都会产生moc_****,那么moc作用又是什么?

元对象编译器moc(metaobjectcompiler)对C++文件中的类声明进行分析并产生用于初始化元对象的C++代码,元对象包含全部信号和槽的名字以及指向这些函数的指针。

moc读C++源文件,如果发现有Q_OBJECT宏声明的类,它就会生成另外一个C++源文件,这个新生成的文件中包含有该类的元对象代码。

例如,假设我们有一个头文件mysignal.h,在这个文件中包含有信号或槽的声明,那么在编译之前moc工具就会根据该文件自动生成一个名为mysignal.moc.h的C++源文件并将其提交给编译器;类似地,对应于mysignal.cpp文件moc工具将自动生成一个名为mysignal.moc.cpp文件提交给编译器。

元对象代码是signal/slot机制所必须的。

用moc产生的C++源文件必须与类实现一起进行编译和连接,或者用#include语句将其包含到类的源文件中。

moc并不扩展#include或者#define宏定义,它只是简单的跳过所遇到的任何预处理指令。

应注意的问题

信号与槽机制是比较灵活的,但有些局限性我们必须了解,这样在实际的使用过程中做到有的放矢,避免产生一些错误。

下面就介绍一下这方面的情况。

1.使用槽与型号会,降低运行效率.信号与槽的效率是非常高的,但是同真正的回调函数比较起来,由于增加了灵活性,因此在速度上还是有所损失,当然这种损失相对来说是比较小的,通过在一台i586-133的机器上测试是10微秒(运行Linux),可见这种机制所提供的简洁性、灵活性还是值得的。

但如果我们要追求高效率的话,比如在实时系统中就要尽可能的少用这种机制。

2.信号与槽机制与普通函数的调用一样,如果使用不当的话,在程序执行时也有可能产生死循环。

因此,在定义槽函数时一定要注意避免间接形成无限循环,即在槽中再次发射所接收到的同样信号。

例如,在前面给出的例子中如果在mySlot()槽函数中加上语句emitmySignal()即可形成死循环。

3.如果一个信号与多个槽相联系的话,那么,当这个信号被发射时,与之相关的槽被激活的顺序将是随机的。

4.宏定义不能用在signal和slot的参数中。

既然moc工具不扩展#define,因此,在signals和slots中携带参数的宏就不能正确地工作,如果不带参数是可以的。

5.构造函数不能用在signals或者slots声明区域内。

的确,将一个构造函数放在signals或者slots区内有点不可理解,无论如何,不能将它们放在privateslots、protectedslots或者publicslots区

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > PPT模板 > 商务科技

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1