Qt实训项目----(2)
1.在主窗体工具栏中添加放大、缩小工具;
2.点击工具后,在绘图区中由默认图标变换为相应的放大、缩小图标;
3.以缩小或放大图标所在绘图区位置为中心,实现绘图区图片的放大和缩小,要求:图片不能无限缩小。
任务1就不用说了,在上个章节里面已经添加了,放置的方法和上个项目放置工具的方法一样,都是拖入工具栏就行,这里就不再过多的描述了。
任务2:在网上下载相应的放大和缩小图片的相应资源
放大:
缩小:
在这里我们一定要记住,只要是有图片资源的,那就必须先实例化一个图片,不然无法加载。但是也别忘了在最上方添加头文件(我开始由于刚开始转行开始重学C++所以只要是基类我就给他添加一遍,这个方法绝对没有错误,但是后面如果东西多了可能会造成点问题!!!!)
好了,不多说了,上代码前一定要搞懂,图标变换是在哪一个函数周期内,就在功能开始的时候声明就行,最后恢复状态就好。
void MainWindow::on_actionZoomin_triggered()
{
/* 这确实是加载图标的方式,为什么我们要解析呢,你要多
读任务要求,任务要求我们在绘图区域内,如果我们这样
设置就是在这个功能的过程之中。
QCursor cursor_Zoomin;
QPixmap pixmap_Zoomin(":/new/img/zoomin.png");
cursor_Zoomin=QCursor(pixmap_Zoomin,-1,-1);
setCursor(cursor_Zoomin);
*/
_drawState=5;
}
void MainWindow::on_actionZoomout_triggered()
{
/*
QCursor cursor_Zoomout;
QPixmap pixmap_Zoomout(":/new/img/zoomout.png");
cursor_Zoomout=QCursor(pixmap_Zoomout,-1,-1);
setCursor(cursor_Zoomout);
*/
_drawState=6;
}
这就是我们设置的槽函数,在看重绘事件和点击事件中的函数,我只截图其中的部分了,就不做处理了;
点击事件mousePressEvent:
else if(_drawState==5) //放大事件
{
_lpress=event->pos(); //左键点击的位置
_point.append(_lpress); //把所有左键点击的点添加到容器中
central_point=_point.at(_point.size()-1); //放大缩小的中心点
_factor *=1.1;
_dx=central_point.x()*(1-_factor);
_dy=(central_point.y()-25)*(1-_factor);
update();
}
else if(_drawState==6) //缩小事件
{
_lpress=event->pos();
_point.append(_lpress);
central_point=_point.at(_point.size()-1);
qDebug()<<"central_point:"<<central_point;
//下面的计算我就不多说了,这是你数学基础的问题...
_factor =_factor*0.9;
_dx=central_point.x()*(1-_factor);
_dy=(central_point.y()-30)*(1-_factor);
if(_factor<=0.2) //保证最小放大倍数
{
_factor=0.2;
}
update();
}
这就是基本的实现函数,里面的容器还有全局变量需要自己去声明,我就不多说了。
下面看重绘事件paintEvent:
void MainWindow::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event);
QPainter p(this);
QPen pen(QColor(255,0,0));
// QBrush brush(QColor(0,255,0,125)); //不需要画刷
p.setPen(pen);
// p.setBrush(brush); //不需要画刷
p.setRenderHint(QPainter::Antialiasing);
//把图片绘制到绘图区域
QPixmap pix;
pix.load(":/new/img/earth.jpg");
p.drawPixmap(0+_dx,rect.height()+_dy,
ui->centralWidget->width()*_factor,
ui->centralWidget->height()*_factor,pix)
}
这就是重绘事件,我也不多说了,其中的运算式,是需要我们计算出来的,是我们能看见的与放大缩小后图片的差距。
好了最重要的一步到来了,就是我们要如何设置在绘图区域内就是在我们的工具栏之下图标进行变换呢。这就需要我们捕捉鼠标的移动监听。那么有人就会问setMouseTracking(true);
为什么就不行呢?这里就多说一下,因为我们的工程基类是mainwindow,而setMouseTracking(true);设置监听的如果能实现,那么是在widget基类的窗体工程可以实现的,但是在mainwindow基类下就不行了,所以我们就需要多设置一步,ui->centralWidget->setMouseTracking(true);
因为我们的绘图区域就是widget基类的,我们设置了它接收监听事件就可以了,毕竟工具栏maintoolbat状态栏statusbar还有menubar是不接受鼠标监听的。如此我们就需要在构造函数里面添加
ui->centralWidget->setMouseTracking(true);
setMouseTracking(true);
这样就可以了,当然你不在构造函数里面添加,在鼠标移动事件我们判断的时候添加应该可以(我没试过,所以不好给你们确切的答案,可以自己去尝试一下)。
我们这就去看鼠标图标的变换的代码。
鼠标移动事件mouseMoveEvent:
void MainWindow::mouseMoveEvent(QMouseEvent *event)
{
qDebug()<<event;
QCursor cursor_Zoomin,cursor_Zoomout;
QPixmap pix1(":/new/img/zoomin.png"),
pix2(":/new/img/zoomout.png");
cursor_Zoomin=QCursor(pix1,-1,-1);
cursor_Zoomout=QCursor(pix2,-1,-1);
// 为什么25不行 ,26可以 !!!!
// QRect eventRegion(0,25,
// this->centralWidget()->geometry().width(),
// this->centralWidget()->geometry().height());
QRect eventRegion(0,rect.height()+1,
this->centralWidget()->geometry().width(),
this->centralWidget()->geometry().height());
if(_drawState==5)
{
if(eventRegion.contains(event->pos()))
{
setCursor(cursor_Zoomin);
}
else
{
setCursor(Qt::ArrowCursor);
}
}
else if(_drawState==6)
{
if(eventRegion.contains(event->pos()))
{
setCursor(cursor_Zoomout);
}
else
{
setCursor(Qt::ArrowCursor);
}
}
}
这里我也不知道为什么在工具栏高度的基础上+1才可以,但是不+1就不行。我查过没答案,所以就这样了。如果有知道的,可以在下面评论告诉我一下。谢谢了!!!
任务3其实在任务2的说明里面都已经包含了,自己可以分辨出来的。
如果有说明错误,希望大家可以指出来我在改正的同时也会感谢给我指出错误的人。也希望刚开始接触Qt的对你们有所帮助。很简单的功能。
切记:东西都是一点点的积累起来的,路也是一步步走的。基础扎实了干什么都好说,如果太过的好高骛远,你什么都不会学到的。