Qt怎么实现图片浏览器


这篇文章主要介绍了Qt怎么实现图片浏览器的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Qt怎么实现图片浏览器文章都会有所收获,下面我们一起来看看吧。

图片浏览器逻辑

实现图片浏览器用到了前面几乎所有的知识,包括窗口部件、布局、事件、对象模型与容器类、图形视图、模型/视图编程以及多线程等。大致流程为:首先定义一个图片类,该类包含图片的路径、文件名、文件id以及获取这些变量的函数。然后定义了一个图片数组类,主要包含添加图像以及获取所有图像以及新加入图像的函数。最后通过将图片名字加入到界面左侧QDockWidget部件中的QTreeView中,通过线程将图片的预览加入界面下侧的窗口部件中。最后通过双击可查看完整图片,以及通过滚轮和鼠标等事件来对图片进行一些操作。

效果图

具体实现

utils.h

#ifndefUTILS_H#defineUTILS_H#include<QString>#include<string>//stringtoQStringinlineQStringstr2qstr(conststd::string&str){returnQString::fromLocal8Bit(str.data());}//QStringtostringinlinestd::stringqstr2str(constQString&qstr){QByteArraycdata=qstr.toLocal8Bit();returnstd::string(cdata);}#endif//UTILS_H

image.h

#ifndefIMAGE_H#defineIMAGE_H#include<string>#include<vector>usingstd::vector;usingstd::string;classImage{public:Image()=default;~Image()=default;Image(conststring&_path,constunsigned&_id):path_(_path),id_(_id){//从路径中获取图像名称autopos=path_.find_last_of('\\')+1;if(pos==0){pos=path_.find_last_of('/')+1;}name_=path_.substr(pos,path_.length()-pos);pos=name_.find_last_of('.');name_=name_.substr(0,pos);}//设置相机所属的idvoidset_cam_id(constunsigned&_id){cam_id_=_id;}//获取路径conststring&get_path(){returnpath_;}//获取文件名conststring&get_name(){returnname_;}constunsigned&get_id(){returnid_;}//获取相机idconstunsigned&get_cam_id(){returncam_id_;}private:stringpath_;stringname_;unsignedid_;unsignedcam_id_;};#endif//IMAGE_H

image_group.h

#ifndefIMAGE_GROUP_H#defineIMAGE_GROUP_H#include"image.h"classimage_group{public:image_group();~image_group();public:booladdImages(constvector<string>&img_paths);constvector<Image>&GetAllImages();constvector<Image>&GetNewAddingImages();private://所有图片数组vector<Image>all_images_;//新加入的图片数组vector<Image>new_images_;};#endif//IMAGE_GROUP_H

image_group.cpp

#include"image_group.h"image_group::image_group(){}image_group::~image_group(){}boolimage_group::addImages(constvector<std::string>&img_paths){new_images_.clear();for(auto&path:img_paths){all_images_.emplace_back(path,all_images_.size());new_images_.emplace_back(path,all_images_.size());}returntrue;}constvector<Image>&image_group::GetAllImages(){returnall_images_;}constvector<Image>&image_group::GetNewAddingImages(){returnnew_images_;}

qimgviewwidget.h

#ifndefQIMGVIEWWIDGET_H#defineQIMGVIEWWIDGET_H#include<QWidget>#include<QImage>//用于显示2D图像的窗口部件classQImgViewWidget:publicQWidget{Q_OBJECTpublic:explicitQImgViewWidget(QWidget*parent=nullptr);~QImgViewWidget()=default;//从文件路径加载图片voidSetImage(constQString&img_path);voidResetTransform();private://用来展示的image信息QImageimg_display_;//原始pixmap信息QPixmappix_ori_;//用来展示的pixmap信息QPixmappix_display_;//图片路径QStringimg_path_;//鼠标滚轮控制的缩放比例floatzoom_scale_;//由鼠标移动控制的移动QPointmove_step_;boolmove_start_;boolis_moving_;QPointmouse_point_;protected:voidpaintEvent(QPaintEvent*event)override;voidwheelEvent(QWheelEvent*event)override;voidmousePressEvent(QMouseEvent*event)override;voidmouseReleaseEvent(QMouseEvent*event)override;voidmouseMoveEvent(QMouseEvent*event)override;voidresizeEvent(QResizeEvent*event)override;};#endif//QIMGVIEWWIDGET_H

qimgviewwidget.cpp

#include"qimgviewwidget.h"#include<QPainter>#include<QWheelEvent>QImgViewWidget::QImgViewWidget(QWidget*parent):QWidget(parent){zoom_scale_=1.0f;move_start_=false;is_moving_=false;}voidQImgViewWidget::SetImage(constQString&img_path){ResetTransform();QSizeview_size=size();//通过QImage加载图像img_path_=img_path;img_display_.load(img_path_);pix_ori_=QPixmap::fromImage(img_display_);pix_display_=pix_ori_.scaled(zoom_scale_*size(),Qt::KeepAspectRatio);}voidQImgViewWidget::ResetTransform(){//重新设置缩放比例和移动位置zoom_scale_=1.0f;move_step_=QPoint(0,0);}voidQImgViewWidget::paintEvent(QPaintEvent*event){QPainterpainter(this);painter.drawPixmap(move_step_.x()+(width()-pix_display_.width())/2,move_step_.y()+(height()-pix_display_.height())/2,pix_display_);}voidQImgViewWidget::wheelEvent(QWheelEvent*event){//随滚轮缩放if(event->delta()>0){zoom_scale_*=1.1;}else{zoom_scale_*=0.9;}pix_display_=pix_ori_.scaled(zoom_scale_*size(),Qt::KeepAspectRatio);update();}voidQImgViewWidget::mousePressEvent(QMouseEvent*event){if(event->button()==Qt::LeftButton){if(!move_start_){move_start_=true;is_moving_=false;mouse_point_=event->globalPos();}}}voidQImgViewWidget::mouseReleaseEvent(QMouseEvent*event){if(event->button()==Qt::LeftButton){if(move_start_){move_start_=false;is_moving_=false;}}}voidQImgViewWidget::mouseMoveEvent(QMouseEvent*event){if(move_start_){constQPointmos_pt=event->globalPos();move_step_+=mos_pt-mouse_point_;is_moving_=true;mouse_point_=mos_pt;repaint();}}voidQImgViewWidget::resizeEvent(QResizeEvent*event){pix_display_=pix_ori_.scaled(zoom_scale_*size(),Qt::KeepAspectRatio);update();}

mainwindow.h

#ifndefMAINWINDOW_H#defineMAINWINDOW_H#include<QMainWindow>#include"image_group.h"#include<QThread>namespaceUi{classMainWindow;}classMainWindow:publicQMainWindow{Q_OBJECTpublic:MainWindow(QWidget*parent=Q_NULLPTR);//~MainWindow();image_group*get_image_group(){return&image_group_;}Ui::MainWindow*get_ui(){returnui;}voidInitTreeView();voidInitPrewView();voidInitDockView();voidInitTabView();voidInitLayout();voidupdateTreeView();voidupdatePreView();privateslots:voidOnActionAddImages();voidOnActiondoubleClickedTreeImage(constQModelIndex&index);protected:voidpaintEvent(QPaintEvent*event)override;voidresizeEvent(QResizeEvent*event)override;private:Ui::MainWindow*ui;image_groupimage_group_;};classQUpdatePreviewThread:publicQThread{Q_OBJECTpublic:QUpdatePreviewThread(MainWindow*mainwindow);signals:voidSingalAddPreview(constQPixmap&pixmap,constint&img_id);privateslots:voidSlotAddPreview(constQPixmap&pixmap,constint&img_id);protected:voidrun()override;private:MainWindow*mainwindow_;};#endif//MAINWINDOW_H

mainwindow.cpp

#include"utils.h"#include"mainwindow.h"#include"ui_mainwindow.h"#include<QStandardItemModel>#include<QFileDialog>#include<QMessageBox>#include<QResizeEvent>#include<QListWidgetItem>#include<QImageReader>MainWindow::MainWindow(QWidget*parent):QMainWindow(parent),ui(newUi::MainWindow){ui->setupUi(this);setWindowState(Qt::WindowMaximized);//初始化UiInitDockView();InitTreeView();InitTabView();InitPrewView();InitLayout();connect(ui->action_addimages,&QAction::triggered,this,&MainWindow::OnActionAddImages);connect(ui->tree_images,&QTreeView::doubleClicked,this,&MainWindow::OnActiondoubleClickedTreeImage);connect(ui->list_previews,&QTreeView::doubleClicked,this,&MainWindow::OnActiondoubleClickedTreeImage);}voidMainWindow::InitTreeView(){//初始化treeviewautotree_imgs=ui->tree_images;auto*model=newQStandardItemModel(tree_imgs);tree_imgs->setModel(model);model->setHorizontalHeaderLabels(QStringList()<<QStringLiteral("images"));tree_imgs->setEditTriggers(QAbstractItemView::NoEditTriggers);}voidMainWindow::InitPrewView(){//初始化previewviewautolist_preview=ui->list_previews;list_preview->setIconSize(QSize(100,100));list_preview->setResizeMode(QListView::Adjust);list_preview->setViewMode(QListView::IconMode);list_preview->setMovement(QListView::Static);list_preview->setSpacing(10);}voidMainWindow::InitDockView(){//初始化dockViewautodp_workspace=(QDockWidget*)ui->dock_workspace;dp_workspace->setWindowTitle("Wokspace");addDockWidget(Qt::LeftDockWidgetArea,dp_workspace);}voidMainWindow::InitTabView(){//2d/3d部件的样式表//autotab_view=ui->tab_mainview;//tab_view->setStyleSheet("QTabWidget:pane{border:1px;}\//QTabBar::tab{width:50px;height:28px;background-color:rgb(36,36,36);color:rgb(200,200,200);margin-right:2px;margin-bottom:-2px;}\//QTabBar::tab:selected{border:1px;border-bottom-color:none;background-color:rgb(50,50,50)}\//QTabBar::tab:!selected{border-bottom:3px;}\//");//tab_view->setCurrentIndex(0);//autowid_model=ui->widget_model;//wid_model->setStyleSheet("background-color:rgb(80,80,80);");//autowid_image=ui->widght_imgview;//wid_image->setStyleSheet("background-color:rgb(80,80,80);");////照片/控制台部件样式表//autotab_info=ui->tab_info;//tab_info->setStyleSheet("QTabWidget:pane{border:1px;}\//QTabBar::tab{width:60px;height:28px;background-color:rgb(36,36,36);color:rgb(200,200,200);margin-right:2px;margin-bottom:-2px;}\//QTabBar::tab:selected{border:1px;border-bottom-color:none;background-color:rgb(50,50,50)}\//QTabBar::tab:!selected{border-bottom:3px;}\//");//autowid_priviews=ui->widget_previews;//wid_priviews->setStyleSheet("background-color:rgb(80,80,80);");//autowid_console=ui->widget_console;//wid_console->setStyleSheet("background-color:rgb(80,80,80);");}voidMainWindow::InitLayout(){}voidMainWindow::updateTreeView(){//相关操作后更新treeview。例如,加载图像constautoall_images=image_group_.GetAllImages();constautonew_images=image_group_.GetNewAddingImages();if(new_images.empty())return;constautonum_allimages=all_images.size();constautonum_images=new_images.size();auto*tree=ui->tree_images;auto*model=static_cast<QStandardItemModel*>(tree->model());QStringstr_title=QString("AllImages(%1Images)").arg(num_allimages);if(model->item(0,0)==nullptr){model->setItem(0,0,newQStandardItem(str_title));}else{autoitem=model->item(0,0);item->setText(str_title);}//为tree添加图片的名字for(autoimage:new_images){model->item(0,0)->setChild(image.get_id(),0,newQStandardItem(str2qstr(image.get_name())));}tree->setExpanded(model->index(0,0),true);autoworkspace=static_cast<QDockWidget*>(ui->dock_workspace);autows_size=workspace->frameSize();tree->setFixedWidth(ws_size.width());}voidMainWindow::updatePreView(){autotab_info=ui->tab_info;tab_info->setCurrentIndex(0);//通过线程来创建previewsQUpdatePreviewThread*thread=newQUpdatePreviewThread(this);thread->start();}voidMainWindow::OnActionAddImages(){QStringListfile_paths=QFileDialog::getOpenFileNames(this,tr("ImagePath"),"Data\\",tr("ImageFiles(*png*jpg*tif);"));//添加图片vector<string>str_paths;for(autopath:file_paths){str_paths.push_back(qstr2str(path));}image_group_.addImages(str_paths);//更新treeviewupdateTreeView();//更新previewviewupdatePreView();}voidMainWindow::OnActiondoubleClickedTreeImage(constQModelIndex&index){QMessageBoxmsg_box;auto*tree=ui->tree_images;auto*model=static_cast<QStandardItemModel*>(tree->model());unsignedimg_id=index.row();constautoall_images=image_group_.GetAllImages();if(img_id>=all_images.size()){msg_box.setText("dataerror");msg_box.exec();return;}//获得双击的图片路径autoimage=all_images[img_id];autoimgpath=str2qstr(image.get_path());//repaintautoimg_view=ui->widght_imgview;img_view->SetImage(imgpath);img_view->repaint();}voidMainWindow::paintEvent(QPaintEvent*event){}voidMainWindow::resizeEvent(QResizeEvent*event){//自动调整所有小部件的大小constQSizesize=event->size();constQRectframe_geometry=ui->central_widget->geometry();constQSizeframe_size=ui->central_widget->size();constQSizemenu_size=ui->menuBar->size();QSizelayout_h2(menu_size.width()*0.12,frame_size.height()),layout_h2(menu_size.width()*0.76,frame_size.height()),layout_h4(menu_size.width()*0.12,frame_size.height());QSizelayout_v1(menu_size.width(),frame_size.height()*0.8),layout_v2(menu_size.width(),frame_size.height()*0.2);//workspaceui->dock_workspace->setMinimumWidth(layout_h2.width());ui->dock_workspace->setMaximumHeight(frame_size.height());//mainview(modelandimage)ui->tab_mainview->setFixedSize(layout_h2.width()-10,layout_v1.height());QSizetab_bar_sz=ui->tab_mainview->tabBar()->size();ui->widget_model->setFixedSize(layout_h2.width()-10,layout_v1.height()-tab_bar_sz.height());ui->widght_imgview->setFixedSize(layout_h2.width()-10,layout_v1.height()-tab_bar_sz.height());ui->widget_gl_model->setFixedSize(layout_h2.width()-10,layout_v1.height()-tab_bar_sz.height());//infoview(photosandconsole)QRectview_rt=ui->tab_mainview->frameGeometry();ui->tab_info->setGeometry(view_rt.x(),view_rt.y()+view_rt.height()+5,layout_h2.width()-10,layout_v2.height());autotab_sz=ui->tab_info->size();tab_bar_sz=ui->tab_info->tabBar()->size();ui->list_previews->setGeometry(0,0,tab_sz.width(),tab_sz.height()-tab_bar_sz.height());setMinimumSize(500,500);}QUpdatePreviewThread::QUpdatePreviewThread(MainWindow*mainwindow){mainwindow_=mainwindow;connect(this,SIGNAL(SingalAddPreview(constQPixmap&,constint&)),this,SLOT(SlotAddPreview(constQPixmap&,constint&)));}voidQUpdatePreviewThread::SlotAddPreview(constQPixmap&pixmap,constint&img_id){autoui=mainwindow_->get_ui();constautoall_images=mainwindow_->get_image_group()->GetAllImages();if(img_id>=all_images.size())return;autolist_preview=ui->list_previews;constQSizeicon_sz=list_preview->iconSize();autoimage=all_images[img_id];QListWidgetItem*list_item=newQListWidgetItem(QIcon(pixmap),str2qstr(image.get_name()));list_item->setSizeHint(QSize(icon_sz.width(),icon_sz.height()+10));list_preview->insertItem(img_id,list_item);list_preview->repaint();}voidQUpdatePreviewThread::run(){if(mainwindow_==nullptr||mainwindow_->get_image_group()==nullptr){return;}autoui=mainwindow_->get_ui();constautonew_images=mainwindow_->get_image_group()->GetNewAddingImages();if(new_images.empty()){return;}constautonum_images=new_images.size();QImageReaderreader;for(autok=0;k<num_images;k++){autoimage=new_images[k];reader.setFileName(str2qstr(image.get_path()));reader.setAutoTransform(true);constQSizeimg_size=reader.size();constQSizeicon_sz=ui->list_previews->iconSize();constQSizesize_scale=img_size.scaled(icon_sz,Qt::KeepAspectRatio);reader.setScaledSize(size_scale);autopixmap=QPixmap::fromImageReader(&reader);emitSingalAddPreview(pixmap,image.get_id());}}

main.cpp

#include"mainwindow.h"#include<QApplication>intmain(intargc,char*argv[]){QApplicationa(argc,argv);MainWindoww;w.show();returna.exec();}

关于“Qt怎么实现图片浏览器”这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对“Qt怎么实现图片浏览器”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注主机评测网行业资讯频道。


上一篇:Java根据某个key加锁怎么实现

下一篇:在Laravel10项目中如何使用ChatGPT


Copyright © 2002-2019 测速网 https://www.inhv.cn/ 皖ICP备2023010105号 城市 地区 街道
温馨提示:部分文章图片数据来源与网络,仅供参考!版权归原作者所有,如有侵权请联系删除!
热门搜索