实训四.docx
《实训四.docx》由会员分享,可在线阅读,更多相关《实训四.docx(26页珍藏版)》请在冰豆网上搜索。
![实训四.docx](https://file1.bdocx.com/fileroot1/2022-11/30/eaac2d39-56c4-4978-9696-3b97cc055f3e/eaac2d39-56c4-4978-9696-3b97cc055f3e1.gif)
实训四
上海第二工业大学计算机科学与技术系
学生实训报告
课程名称
嵌入式操作系统课程设计
实训类别
验证型
实训项目名称
布局管理、事件处理和图像
班级
10计科A1
姓名
学号
实训时间
2013年11月1日
实训地点
15号楼507
指导教师
组号
同组学生信息(请填写在下方)
班级
姓名
学号
一、实训目的
1、了解并掌握QT提供的多种布局管理部件,包括QT布局管理器、分裂器、栈部件、工作空间部件和多文档区部件等;
2、分析Qt的常用事件,包括鼠标事件、键盘事件以及事件过滤器的使用方法;
3、掌握QPainter、QCanvas与OpenGL进行绘图的基本方法,并注意这三类方式使用的异同点。
二、设备和仪器
装有Linux和Windows操作系统的PC机一台
三、实训内容
1、完成书本第六部分“布局管理”中的两个例题QScrollView的IconEditor和多文档界面的Editor;
QScrollView的IconEditor运行结果:
主要代码注释如下:
ImageEditor.cpp
ImageEditor:
:
ImageEditor(QWidget*parent,constchar*name)
:
QScrollView(parent,name,WStaticContents|WNoAutoErase)
{
curColor=black;
zoom=8;
curImage.create(16,16,32);//若没有加载图片,则将画布的大小设置为16*16大小的
curImage.fill(qRgba(0,0,0,0));//颜色为白色
curImage.setAlphaBuffer(true);
resizeContents();//此函数用于管理初始窗口部件获取自己的大小
}
voidImageEditor:
:
resizeContents()
{
QSizesize=zoom*curImage.size();
if(zoom>=3)
size+=QSize(1,1);//若zoom大于等于3,size则放大一格
QScrollView:
:
resizeContents(size.width(),size.height());//QScrollView是否显示滚动条由窗口的大小决定
}
voidImageEditor:
:
setImage(constQImage&newImage)//获取所要显示的图片
{
if(newImage!
=curImage)
{
curImage=newImage.convertDepth(32);
curImage.detach();
resizeContents();//重新获得大小
updateContents();//重新绘制图片
}
}
voidImageEditor:
:
contentsMousePressEvent(QMouseEvent*event)//鼠标点击事件
{
if(event->button()==LeftButton)//左击事件
setImagePixel(event->pos(),true);
else
if(event->button()==RightButton)//右击事件
setImagePixel(event->pos(),false);
}
voidImageEditor:
:
cotentMouseMoveEvent(QMouseEvent*event)//鼠标按住拖动事件
{
if(event->state()&LeftButton)//左击事件
setImagePixel(event->pos(),true);
else
if(event->state()&RightButton)//右击事件
setImagePixel(event->pos(),false);
}
intmain(intargc,char*argv[])
{
QApplicationapp(argc,argv);
ImageEditor*imageEditor=newImageEditor;
imageEditor->setImage(QImage:
:
QImage("mouse.png",0));//加载资源图片mouse.png
app.setMainWidget(imageEditor);
imageEditor->show();//显示窗口
returnapp.exec();
}
多文档界面的Editor运行结果:
MainWindow:
:
MainWindow(QWidget*parent,constchar*name)
:
QMainWindow(parent,name)
{
workspace=newQWorkspace(this);//创建一个窗口部件
setCentralWidget(workspace);//使其成为中央窗口部件
connect(workspace,SIGNAL(windowActivated(QWidget*)),
this,SLOT(updateMenus()));
connect(workspace,SIGNAL(windowActivated(QWidget*)),//槽用于保持菜单栏和状态栏总是用于反应,当前激活子菜单的窗口状态。
this,SLOT(updateModIndicator()));
createActions();
createMenus();
createToolBars();
createStatusBar();
setCaption(tr("Editor"));
setIcon(QPixmap:
:
fromMimeSource("icon.png"));
}
voidMainWindow:
:
updateMenus()//只要一个窗口被激活或最后一个被关闭,updatemenu就会被调用
{
boolhasEditor=(activeEditor()!
=0);
saveAct->setEnabled(hasEditor);
saveAsAct->setEnabled(hasEditor);
pasteAct->setEnabled(hasEditor);
deleteAct->setEnabled(hasEditor);
copyAvailable(activeEditor()
&&activeEditor()->hasSelectedText());
closeAct->setEnabled(hasEditor);
closeAllAct->setEnabled(hasEditor);
tileAct->setEnabled(hasEditor);
cascadeAct->setEnabled(hasEditor);
nextAct->setEnabled(hasEditor);
previousAct->setEnabled(hasEditor);
windowsMenu->clear();//若不存在激活的窗口,清空windows菜单
createWindowsMenu();
}
2.编写程序ch_501,实现程序界面如下:
下方文本框可以输入内容(保存类型为AllFiles(*.*)),所有菜单及工具按钮均可实现功能。
File菜单如下:
Help菜单如下:
About菜单为:
AboutQt菜单为
实验过程:
1.运行结果:
2、完成书本第七部分“事件处理”中的例题Ticker;
#include
#include"ticker.h"
Ticker:
:
Ticker(QWidget*parent,constchar*name)
:
QWidget(parent,name)
{
offset=0;//设置被绘制文本X坐标
myTimerId=0;//定时器标示器
}
voidTicker:
:
setText(constQString&newText)
{
myText=newText;
update();//强制重新绘制
updateGeometry();//提示ticker窗口布局的变化
}
QSizeTicker:
:
sizeHint()const
{
returnfontMetrics().size(0,text());
}
voidTicker:
:
paintEvent(QPaintEvent*)
{
QPainterpainter(this);
inttextWidth=fontMetrics().width(text());//确定文版需要多少水平空间
if(textWidth<1)
return;
intx=-offset;
while(xpainter.drawText(x,0,textWidth,height(),
AlignLeft|AlignVCenter,text());
x+=textWidth;
}
}
voidTicker:
:
showEvent(QShowEvent*)
{
myTimerId=startTimer(30);//设置一个30秒的定时器
}
voidTicker:
:
timerEvent(QTimerEvent*event)//时间间隔调用
{
if(event->timerId()==myTimerId){
++offset;
if(offset>=fontMetrics().width(text()))
offset=0;
scroll(-1,0);//左移一个像素
}else{
QWidget:
:
timerEvent(event);
}
}
voidTicker:
:
hideEvent(QHideEvent*)
{
killTimer(myTimerId);//当文本消失时,释放对应的定时器
}
3、请按下列程序源代码,编写ch_601,并在程序后进行注释:
ch_601.cpp的源程序为:
#include
#include
#include
#include
#include
#include"ch_601.h"
ch_601:
:
ch_601(QWidget*parent,constchar*name):
QWidget(parent,name)
{
for(inta=0;a{
colors[a]=QColor(rand()&255,rand()&255);//设置随机颜色
}
rectangles=0;//矩形计数为0
startTimer(0);//开始计数为0
QTimer*counter=newQTimer(this);
connect(counter,SIGNAL(timeout()),this,SLOT(updateCaption()));//计数器的信号为timeout时,更新caption
counter->start(1000);
}
voidch_601:
:
updateCaption()
{
QStrings;
s.sprintf(QObject:
:
tr("QTimer实例"),rectangles);//设置caption为“QTimer实例”和举行数
rectangles=0;
setCaption(s);
}
voidch_601:
:
paintEvent(QPaintEvent*)
{
QPainterpaint(this);
intw=width();//宽w
inth=height();//高h
if(w<=0||h<=0)//若w<=0或h<=0
return;//返回
paint.setPen(NoPen);//若没有画笔则设置画笔
paint.setBrush(colors[rand()%numColors]);//画刷颜色随机
QPointp1(rand()%w,rand()%h);//设置矩形的位置
QPointp2(rand()%w,rand()%h);
QRectr(p1,p2);
paint.drawRect(r);//画矩形
}
voidch_601:
:
timerEvent(QTimerEvent*)
{
for(inti=0;i<100;i++)
{
repaint(false);//在一个绘画窗口发送之前,之前的窗口不会被擦除
rectangles++;//矩形累加
}
}
Main.cpp的源程序为:
#include
#include
#include"ch_601.h"
intmain(intargc,char**argv)
{
QApplicationa(argc,argv);
ch_601always(0,0);
QTextCodec:
:
setCodecForTr(QTextCodec:
:
codecForName("gb18030"));//设置标题字体
always.resize(400,250);//初始化窗体
a.setMainWidget(&always);
always.setCaption(QObject:
:
tr("时钟的测试例题"));
always.show();
returna.exec();
}
ch_601.h的源程序为:
#ifndefCH_601_H
#defineCH_601_H
#include
constintnumColors=120;
classCh_601:
publicQWidget
{
Q_OBJECT
public:
Ch_601(QWidget*parent=0,constchar*name=0);
protected:
voidpaintEvent(QPaintEvent*);
voidtimerEvent(QTimerEvent*);
privateslots:
voidupdateCaption();
private:
intrectangles;
QColorcolors[numColors];
};
#endif
Ch_601运行结果:
4、请按下列程序源代码(其中主程序自编),编写ch_602,并在程序后进行注释:
#include"progressbar.h"
#include
#include
#include
#include
#include
ProgressBar:
:
ProgressBar(QWidget*parent,constchar*name)
:
QButtonGroup(0,Horizontal,QObject:
:
tr("进度条测试"),parent,name),timer()
{
setMargin(10);//设置边距
QGridLayout*toplayout=newQGridLayout(layout(),2,2,5);//设置空间组
setRadioButtonExclusive(TRUE);//按键单一选择
slow=newQRadioButton(QObject:
:
tr("低速"),this);//设置低速,中速,高速三个选项
normal=newQRadioButton(QObject:
:
tr("中速"),this);
fast=newQRadioButton(QObject:
:
tr("高速"),this);
QVBoxLayout*vb1=newQVBoxLayout;//新建一个box
toplayout->addLayout(vb1,0,0);//嵌套布局
vb1->addWidget(slow);//添加slow,normal,fast到布局
vb1->addWidget(normal);
vb1->addWidget(fast);
start=newQPushButton(QObject:
:
tr("开始"),this);//新建开始按钮
reset=newQPushButton(QObject:
:
tr("重启"),this);//新建重启按钮
QVBoxLayout*vb2=newQVBoxLayout;
toplayout->addLayout(vb2,0,1);
vb2->addWidget(start);
vb2->addWidget(reset);
progress=newQProgressBar(100,this);//添加进度条
toplayout->addMultiCellWidget(progress,1,1,0,1);//1列插入progressbar占2行2列
connect(start,SIGNAL(clicked()),this,SLOT(slotStart()));//点击开始触发开始槽
connect(reset,SIGNAL(timeout()),this,SLOT(slotTimeout()));//点击重置触发timeout槽
normal->setChecked(TRUE);//默认选中设置为中速
start->setFixedWidth(80);//设置最大最小宽度为80
setMinimumWidth(300);//设置最小宽度300
}
voidProgressBar:
:
slotStart()
{
if(progress->progress()==-1)
{
if(slow->isChecked())
progress->setTotalSteps(10000);//slow进度条满需10000小时
elseif(normal->isChecked())
progress->setTotalSteps(1000);//normal进度条满需1000小时
else
progress->setTotalSteps(50);//fast进度条满需50小时
slow->setEnabled(FALSE);//slow不能选中
normal->setEnabled(FALSE);//normal不能选中
fast->setEnabled(FALSE);/fast不能选中
}
if(!
timer.isActive())//若时钟未被激活
{
timer.start
(1);//时钟设置为1
start->setText(QObject:
:
tr("暂停"));
}
else
{
timer.stop();//时间停止
start->setText(QObject:
:
tr("继续"));
}
}
voidProgressBar:
:
slotReset()//进度条重置
{
timer.stop();
start->setText(QObject:
:
tr("开始"));
start->setEnabled(TRUE);//start可以被选择
slow->setEnabled(TRUE);//slow可以被选择
normal->setEnabled(TRUE);//normal可以被选择
fast->setEnabled(TRUE);//fast可以被选择
progress->reset();//进度条重置
}
voidProgressBar:
:
slotTimeout()
{
intp=progress->progress();//声明p,用于保存进度条
#if1
if(p==progress->totalSteps())//若进度条满
{
start->setText(QObject:
:
tr("开始"));
start->setEnabled(FALSE);
return;
}
#endif
progress->setProgress(++p);
}
processbar.h的源程序为:
#ifndefPROGRESSBAR_H
#definePROGRESSBAR_H
#include
#include
classQRadioButton;
classQPushButton;
classQProgressBar;
classProgressBar:
publicQButtonGroup
{
Q_OBJECT
public:
ProgressBar(QWidget*parent=0,constchar*name=0);
protected:
QRadioButton*slow,*normal,*fast;
QPushButton*start,*pause,*reset;
QProgressBar*progress;
QTimertimer;
protectedslots:
voidslotStart();
voidslotReset();
voidslotTimeout();
};
#endif
Main.cpp源程序为:
#include
#include"progressbar.h"
intmain(intargc,char**argv)
{
QApplicationa(argc,argv);
ProgressBa