Qt项目实战2:图片查看器QImageViewer
2016-12-07 18:22
405 查看
在博文Qt学习笔记2:QMainWindow和QWidget的区别中介绍了使用空的Qt项目创建带有菜单栏、工具栏的界面。
这里,使用一个简单的图片查看器项目,来熟悉一下Qt的图片显示和基本操作。
该项目实现的主要功能:
实现图片的打开、关闭、居中显示;
实现图片上一张/下一张切换;
实现图片的放大、缩小操作
实现图片的左旋、右旋操作
需要用的Qt类:
QFileDialog QImage QPixmap QFileInfo
使用空的Qt项目创建带有菜单栏和工具栏的界面的操作参考博文Qt学习笔记1:创建一个QT的空项目
工具栏图标依次是:打开图片、关闭图片、上一张、下一张、左旋、右旋、放大、缩小
此项目算是一个小demo,主要是熟悉图片处理的相关的操作,基础类和操作熟悉之后可以加入复杂的功能。
(1)使用QFileDislog函数选择一个图片文件,获取到文件的路径名;
(2)使用QImage类加载文件,生成image对象;
(3)使用QLabel类的setPixmap函数将图片显示在界面上。
参考代码如下:
图片关闭时,只需将label清空即可:
图片打开、关闭的函数,作为QAction的槽函数触发即可:
提示:在图片打开时可以将界面名改为文件名+标题,关闭时去掉文件名,方便用户使用。
但是会出现各种问题,例如:label在resize时部分尺寸超出页面的大小显示不全、图片不能居中显示等。
需要做以下操作来解决上述问题:
使用QLabel类的setPixmap函数将图片显示在界面上;
创建一个QScrollArea部件,将label加载到scrollarea中;
设置scrollarea部件为中心对齐,无边框;
设置页面布局方式为格点布局,并将scrollarea部件增加到0,0点上。
参考代码:
当打开一张图片时,自动居中对齐;当图片大小超过中心窗口尺寸时,scrollarea部件出现滑动条,显示配合放大、缩小功能,显示效果更好。
效果如下图所示:
当需要对打开的文件上、下切换时,只需对当前链表的下表进行轮询并获取图片显示即可。
在菜单栏和工具栏增加上一张/下一张按钮,实现QAction行为触发。
实现步骤:
(1)使用QFileInfoList链表保存下已经打开的文件所在路径下所有的图片文件的信息;
(2)记录下当前文件的下表,上一张/下一张时间触发时,对下标进行增减;
(3)获取到文件路径和文件名;
(4)重新构造image对象,加载图片文件并显示。
参考代码:
实现步骤:
(1)通过当前图片文件名静态加载image;
(2)将成员变量旋转角度,以90度间隔增、减;
(3)通过QImage类的transformed行为修改加载的图片角度;
(4)显示修改后的图片,并重置图片尺寸等;
参考代码:
这里增加一个功能:支持图片旋转之后进行放大、缩小操作。只需对放大、缩小后新的image对象再进行旋转操作即可。
实现步骤:
(1)通过当前图片文件名静态加载image;
(2)修改成员变量图片尺寸,设置放大倍数为1.2,缩小倍数为0.8,保存新的尺寸;
(3)通过QImage类的transformed行为修改加载的图片角度;
(5)显示修改后的图片,并重置图片尺寸等;
参考代码:
需要注意的地方:
图片关闭、上一张、下一张操作是在图片打开成功之后才能操作,所以误点按钮导致程序崩溃,需要加使能操作。
此处图片对象的创建没有使用new操作,理由是需要手动delete比较麻烦;直接使用局部变量,编译器会自动释放资源。
此处使用空的Qt模板创建,不使用系统的ui文件,需要手动初始化菜单栏、工具栏和中心窗口等。
源码下载链接:https://github.com/gitorup/QImageViewer
这里,使用一个简单的图片查看器项目,来熟悉一下Qt的图片显示和基本操作。
该项目实现的主要功能:
实现图片的打开、关闭、居中显示;
实现图片上一张/下一张切换;
实现图片的放大、缩小操作
实现图片的左旋、右旋操作
需要用的Qt类:
QFileDialog QImage QPixmap QFileInfo
使用空的Qt项目创建带有菜单栏和工具栏的界面的操作参考博文Qt学习笔记1:创建一个QT的空项目
页面布局
根据自己的实际需求添加菜单栏和工具栏,参考如下图:工具栏图标依次是:打开图片、关闭图片、上一张、下一张、左旋、右旋、放大、缩小
此项目算是一个小demo,主要是熟悉图片处理的相关的操作,基础类和操作熟悉之后可以加入复杂的功能。
实现图片的打开、关闭
文件打开和显示的步骤:(1)使用QFileDislog函数选择一个图片文件,获取到文件的路径名;
(2)使用QImage类加载文件,生成image对象;
(3)使用QLabel类的setPixmap函数将图片显示在界面上。
参考代码如下:
void QImageViewer::openActionTriggered(void) { filename = QFileDialog::getOpenFileName(this, tr("Select image:"), "D:\\Documents\\Pictures", tr("Images (*.png *.bmp *.jpg *.gif)")); if (filename.isEmpty()) { return ; } QImage image; if (!image.load(filename)) { QMessageBox::information(this, tr("Error"), tr("Open file error")); return ; } QPixmap pixmap = QPixmap::fromImage(image); imageSize = pixmap.size(); imageLabel->setPixmap(pixmap); imageLabel->resize(imageSize); //qDebug() << "filname: " << filename; setWindowTitle(QFileInfo(filename).fileName() + tr(" - imageViewer")); }
图片关闭时,只需将label清空即可:
void QImageViewer::closeActionTriggered(void) { imageLabel->clear(); imageLabel->resize(QSize(200, 100)); setWindowTitle(tr("imageViewer")); }
图片打开、关闭的函数,作为QAction的槽函数触发即可:
connect(openAction, SIGNAL(triggered(bool)), this, SLOT(openActionTriggered())); connect(closeAction, SIGNAL(triggered(bool)), this, SLOT(closeActionTriggered()));
提示:在图片打开时可以将界面名改为文件名+标题,关闭时去掉文件名,方便用户使用。
实现图片居中显示、页面自动调整
通过上述操作,已经可以创建一个label,并将图片显示在label中。但是会出现各种问题,例如:label在resize时部分尺寸超出页面的大小显示不全、图片不能居中显示等。
需要做以下操作来解决上述问题:
使用QLabel类的setPixmap函数将图片显示在界面上;
创建一个QScrollArea部件,将label加载到scrollarea中;
设置scrollarea部件为中心对齐,无边框;
设置页面布局方式为格点布局,并将scrollarea部件增加到0,0点上。
参考代码:
void QImageShow::setImageShowWidget(void) { /* label show image */ imageLabel = new QLabel(); QScrollArea *imageScrollArea = new QScrollArea(); imageScrollArea->setAlignment(Qt::AlignCenter); imageScrollArea->setFrameShape(QFrame::NoFrame); imageScrollArea->setWidget(imageLabel); QGridLayout *mainLayout = new QGridLayout(); mainLayout->addWidget(imageScrollArea, 0, 0); centralWidget->setLayout(mainLayout); }
当打开一张图片时,自动居中对齐;当图片大小超过中心窗口尺寸时,scrollarea部件出现滑动条,显示配合放大、缩小功能,显示效果更好。
效果如下图所示:
实现上一张/下一张切换
在打开文件同时,获取到当前目录的文件列表,保存到文件信息链表中。当需要对打开的文件上、下切换时,只需对当前链表的下表进行轮询并获取图片显示即可。
void QImageViewer::getImgInfoList(QFileInfoList &imgInfoList) { imgInfoList.clear(); QDir dir = QFileInfo(filename).absolutePath(); QFileInfoList infoList = dir.entryInfoList(QDir::Files); //qDebug() << "GET:" << infoList.count() << dir; QFileInfo info; for (int i = 0; i < infoList.count(); i++) { info = infoList.at(i); //qDebug() << i << info.absolutePath(); QString suffix = info.suffix(); if (suffix == "jpg" || suffix == "bmp" || suffix == "png") { imgInfoList.append(info); //qDebug() << "getImgInfoList:" << i << info.absolutePath() << info.suffix(); } } QFileInfo curImageInfo = QFileInfo(filename); for (int j = 0; j < imgInfoList.count(); j++) { info = imgInfoList.at(j); if (info.fileName() == curImageInfo.fileName()) { index = j; //qDebug() << "curImage index:" << index; } } }
在菜单栏和工具栏增加上一张/下一张按钮,实现QAction行为触发。
实现步骤:
(1)使用QFileInfoList链表保存下已经打开的文件所在路径下所有的图片文件的信息;
(2)记录下当前文件的下表,上一张/下一张时间触发时,对下标进行增减;
(3)获取到文件路径和文件名;
(4)重新构造image对象,加载图片文件并显示。
参考代码:
void QImageViewer::lastActionTriggered(void) { //getImgInfoList(imgInfoList); index = index - 1; int count = imgInfoList.count(); //qDebug() << "left count: " << count << "index: " << index; if (index < 0) { index = count - 1; } filename.clear(); filename.append(path); filename += "/"; filename += imgInfoList.at(index).fileName(); //qDebug() << "filname: " << filename; QImage image; if (!image.load(filename)) { QMessageBox::information(this, tr("Error"), tr("Open file error")); return ; } QPixmap pixmap = QPixmap::fromImage(image); imageSize = pixmap.size(); imageLabel->setPixmap(pixmap); imageLabel->resize(imageSize); setWindowTitle(QFileInfo(filename).fileName() + tr(" - imageViewer")); } void QImageViewer::nextActionTriggered(void) { //getImgInfoList(imgInfoList); index = index + 1; int count = imgInfoList.count(); //qDebug() << "right count: " << count << "index: " << index; if (index == count) { index = 0; } filename.clear(); filename.append(path); filename += "/"; filename += imgInfoList.at(index).fileName(); //qDebug() << "filname: " << filename; QImage image; if (!image.load(filename)) { QMessageBox::information(this, tr("Error"), tr("Open file error")); return ; } QPixmap pixmap = QPixmap::fromImage(image); imageSize = pixmap.size(); imageLabel->setPixmap(pixmap); imageLabel->resize(imageSize); setWindowTitle(QFileInfo(filename).fileName() + tr(" - imageViewer")); }
图片的左旋、右旋操作
图片的旋转使用QImage类的transformed行为来实现,使用成员变量保存下当前图片的旋转角度,每次触发旋转操作,将旋转角度以90度间隔增减。实现步骤:
(1)通过当前图片文件名静态加载image;
(2)将成员变量旋转角度,以90度间隔增、减;
(3)通过QImage类的transformed行为修改加载的图片角度;
(4)显示修改后的图片,并重置图片尺寸等;
参考代码:
void QImageViewer::toLeftActionTriggered(void) { QImage imgRotate; QMatrix matrix; QPixmap pixmap; QImage image; imageAngle += 3; imageAngle = imageAngle % 4; qDebug() << "angle:%d" << imageAngle; matrix.rotate(imageAngle * 90); image.load(filename); imgRotate = image.transformed(matrix); pixmap = QPixmap::fromImage(imgRotate); imageSize = pixmap.size(); imageLabel->resize(imgRotate.size()); imageLabel->setPixmap(pixmap); } void QImageViewer::toRightActionTriggered(void) { QImage imgRotate; QMatrix matrix; QPixmap pixmap; QImage image; imageAngle += 1; imageAngle = imageAngle % 4; //qDebug() << "angle:%d" << imageAngle; matrix.rotate(imageAngle * 90); image.load(filename); imgRotate = image.transformed(matrix); pixmap = QPixmap::fromImage(imgRotate); imageSize = pixmap.size(); imageLabel->resize(imgRotate.size()); imageLabel->setPixmap(pixmap); }
图片的放大、缩小操作
图片的放大、缩小操作通过QImage类的scaled行为实现。可以重置image的尺寸,返回新的image对象。这里增加一个功能:支持图片旋转之后进行放大、缩小操作。只需对放大、缩小后新的image对象再进行旋转操作即可。
实现步骤:
(1)通过当前图片文件名静态加载image;
(2)修改成员变量图片尺寸,设置放大倍数为1.2,缩小倍数为0.8,保存新的尺寸;
(3)通过QImage类的transformed行为修改加载的图片角度;
(5)显示修改后的图片,并重置图片尺寸等;
参考代码:
void QImageViewer::toEnlargeActionTriggered(void) { QImage imgScaled; QPixmap pixmap; QImage image; QImage imgRotate; QMatrix matrix; image.load(filename); matrix.rotate(imageAngle * 90); imgRotate = image.transformed(matrix); imgScaled = imgRotate.scaled(imageSize.width() * 1.2, imageSize.height() * 1.2, Qt::KeepAspectRatio); pixmap = QPixmap::fromImage(imgScaled); imageSize = pixmap.size(); //qDebug() << "width:%d, height:%d" << imageSize.width() << imageSize.height(); imageLabel->setPixmap(pixmap); imageLabel->resize(imageSize); } void QImageViewer::toLessenActionTriggered(void) { QImage imgScaled; QPixmap pixmap; QImage image; QImage imgRotate; QMatrix matrix; image.load(filename); matrix.rotate(imageAngle * 90); imgRotate = image.transformed(matrix); imgScaled = imgRotate.scaled(imageSize.width() * 0.8, imageSize.height() * 0.8, Qt::KeepAspectRatio); pixmap = QPixmap::fromImage(imgScaled); imageSize = pixmap.size(); //qDebug() << "width:%d, height:%d" << imageSize.width() << imageSize.height(); imageLabel->setPixmap(pixmap); imageLabel->resize(imageSize); }
需要注意的地方:
图片关闭、上一张、下一张操作是在图片打开成功之后才能操作,所以误点按钮导致程序崩溃,需要加使能操作。
此处图片对象的创建没有使用new操作,理由是需要手动delete比较麻烦;直接使用局部变量,编译器会自动释放资源。
此处使用空的Qt模板创建,不使用系统的ui文件,需要手动初始化菜单栏、工具栏和中心窗口等。
源码下载链接:https://github.com/gitorup/QImageViewer
相关文章推荐
- Android 实战 - 个人App乐逗项目 之 查看图片,查看GIF封装
- Qt学习之---项目实战
- 项目实战之中小网站图片压缩技术
- 09(maven+SSH)网上商城项目实战之使用jersey实现应用服务器和图片服务器分离
- 【springmvc+mybatis项目实战】杰信商贸-9.生产厂家删除+查看
- 【springmvc+mybatis项目实战】杰信商贸-14.购销合同添加+修改+删除+查看
- 攻防实战:教你轻松查看QQ空间加密后的好友图片
- Qt/C++ 项目实战模仿酷狗之实现 换肤(二)
- Android 实战 - 个人App乐逗项目(查看网页链接封装,播放视频封装)
- Swift开发iOS项目实战视频教程(二)---图片与动画
- android项目 之 记事本(13) ----- 查看图片及播放录音
- 【springmvc+mybatis项目实战】杰信商贸-14.购销合同添加+修改+删除+查看
- 【springmvc+mybatis项目实战】杰信商贸-9.生产厂家删除+查看
- 09(maven+SSH)网上商城项目实战之使用jersey实现应用服务器和图片服务器分离
- iOS项目开发实战——使用CALayer实现图片的淡入淡出效果
- Android项目实战--手机卫士04--自定义图片
- iOS开发项目实战——Swift实现图片轮播与浏览
- 项目实战No9 不等高cell高度 相册图片
- AJ学IOS 之微博项目实战(10)微博cell中图片的显示以及各种填充模式简介
- Qt/C++项目实战模仿酷狗之播放列表实现(一)