⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 imageview.cc

📁 c++的guiQt做的开发
💻 CC
📖 第 1 页 / 共 2 页
字号:
/** @file ImageView - class for viewing images*/#include "imageview.h"#include "settings.h"#include "iconcache.h"#include "util.h"#include "image.h"#include <QKeyEvent>#include <QMouseEvent>#include <QPaintEvent>#include <QPainter>#include <QPoint>#include <QRectF>#include <QRubberBand>#include <QScrollBar>#include <QString>#include <QToolTip>#include <QWheelEvent>#include <iostream>#include <assert.h>#include <math.h>namespace gui {using namespace std;/** Icon cache instance - one for all classes */IconCache *ic=NULL;/** Internal subwidget, which is positioned inside the QScrollArea */class ImageViewPrivate : public QWidget {private: /** parent imageview */ ImageView* p; /** Selection rectangle */ QRubberBand* rb; /** Selection origin */ QPoint origin; /** True if rubber band is being moved */ bool moveRb;public: /**  Default constructor  @param _p parent ImageView  @param parent parent widget */ ImageViewPrivate(ImageView* _p,QWidget *parent=NULL) : QWidget(parent) {  setPalette(QPalette(QColor(0xff,0xff,0xff),QColor(0,0,0)));  setAttribute(Qt::WA_NoSystemBackground);  setAttribute(Qt::WA_OpaquePaintEvent);  p=_p;  rb=NULL;  moveRb=false;  setMouseTracking(true); } /**  Return size hint from parent item */ virtual QSize sizeHint() const {  return p->sizeHint(); } /**  Handler called for repainting the widget  @param e event data */ virtual void paintEvent(QPaintEvent *e)  {  int x=width();  int y=height();  QPainter pa(this);  p->repaint(x,y,pa,e->rect());  e->accept(); }  /**  Handler called when mouse is moved over the widget  @param e event data */ virtual void mouseMoveEvent(QMouseEvent *e) {  if (rb && (e->buttons() & Qt::LeftButton)) {   QRect r=QRect(origin, e->pos()).normalized();   rb->setGeometry(r & p->data_rect);   p->selRect(rb->geometry());  }  p->mouseCoordEvent(e);  e->ignore(); } /**  Handler called when mouse button is pressed  @param e event data */ virtual void mousePressEvent(QMouseEvent *e) {  if (e->button() == Qt::LeftButton) { //LMB was just pressed   moveRb=true;   origin=e->pos();   if (!rb) rb=new QRubberBand(QRubberBand::Rectangle, this);   rb->setGeometry(QRect(origin, QSize()));   rb->show();   e->accept();  } else e->ignore(); } /**  Handler called when mouse button is released  @param e event data */ virtual void mouseReleaseEvent(QMouseEvent *e) {  if (e->buttons() & Qt::LeftButton) { // Left button is still pressed   e->ignore();   return;  }  if (moveRb) {   moveRb=false;   p->selRect(rb->geometry());   p->rectCheck();  } else e->ignore(); } /**  Cancel selection rectangle */ void cancelRect() {  if (!rb) return;  rb->setGeometry(QRect(origin, QSize()));    p->selRect(rb->geometry()); } /**  Move the rubberband after updating the zoom level  @param newGeom New rubberband geometry */ void moveRubberBand(const QRect &newGeom) {  if (!rb) return;  rb->setGeometry(newGeom); }};/** constructor of ImageView @param parent parent widget containing this control*/ImageView::ImageView(QWidget *parent/*=0*/):QScrollArea(parent) { image=NULL; zoom=100; if (!ic) ic=new IconCache(); setFocusPolicy(Qt::WheelFocus); setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding); d=new ImageViewPrivate(this); setWidget(d); setWidgetResizable(true); setBackgroundRole(QPalette::Dark); setMouseTracking(true); mouse_x=mouse_y=-1; mouse_ex=mouse_ey=0; data_rect=QRect(0,0,1,1); setMode(view);}/** Called when selection is finished (on releasing the mouse button) and on start*/void ImageView::rectCheck() { if (selection.isValid()) {  // "Snap rect to grid"  setDataRect();  d->moveRubberBand(selectionFromImageCoords(selection)); } if (!selectionText.isNull()) {  emit selectionInfo(selectionText); } else {  emit selectionInfo(""); } emit selectionChanged();}/** Return true, if there is image shown in imageview, otherwise false*/bool ImageView::haveImage() const { return (image!=NULL);}/**\copydoc ImageViewPrivate::cancelRect()*/void ImageView::cancelRect() { d->cancelRect(); rectCheck(); emit selectionInfo("");}/** Return true, if there is available selection*/bool ImageView::haveSelection() const { return (selection.isValid());}/** Return image shown in the widget (or NULL if nothing is shown) If the image is modified, update() should be called to redraw the new image*/Image* ImageView::getImage() { return image;}/** Update selection rectangle position @param r selection rectangle*/void ImageView::selRect(const QRect &r) { if (r.width()<=0 || r.height()<=0) {  selection=QRect();  selText(QString::null); } else {  selection=selectionToImageCoords(r);  int x1=selection.left();  int x2=selection.right();  int y1=selection.top();  int y2=selection.bottom();  int w=selection.width();  int h=selection.height();    selText(QString::number(x1)+","+QString::number(y1)+" - "+QString::number(x2)+","+QString::number(y2)         +" ("+QString::number(w)+"x"+QString::number(h)+") "); }}/** Return selection rectangle in string form. Values (x and y position of corners) are separated by spaces @param coord What to return (0=all coordinates, 1-4=single appropriate coordinate)*/QString ImageView::getRect(int coord/*=0*/) { if (!selection.isValid()) return "";//Invalid rectangle int x1=selection.left(); int x2=selection.right(); int y1=selection.top(); int y2=selection.bottom(); switch (coord) {  case 1: {   return QString::number(x1);  }  case 2: {   return QString::number(y1);  }  case 3: {   return QString::number(x2);  }  case 4: {   return QString::number(y2);  } } return QString::number(x1)+" "+QString::number(y1)+" "+QString::number(x2)+" "+QString::number(y2);}/** Return selection rectangle converted to image coordinate system @param selectionRect rectangle to convert*/QRect ImageView::selectionToImageCoords(const QRect &selectionRect) { double dw=data_rect.width(); double dh=data_rect.height(); int x=(int)floor((selectionRect.left()-data_rect.left())*image->x()/dw); int y=(int)floor((selectionRect.top()-data_rect.top())*image->y()/dh); int xr=(int)floor((selectionRect.right()-data_rect.left())*image->x()/dw); int yr=(int)floor((selectionRect.bottom()-data_rect.top())*image->y()/dh); return QRect(QPoint(x,y),QPoint(xr,yr));}/** Return selection rectangle converted from image coordinate system to window coordinate syste, @param selectionRect rectangle to convert*/QRect ImageView::selectionFromImageCoords(const QRect &selectionRect) { int x= (selectionRect.left()  )*data_rect.width()/image->x()+data_rect.left(); int y= (selectionRect.top()   )*data_rect.height()/image->y()+data_rect.top(); int xr=(selectionRect.right()+1)*data_rect.width()/image->x()+data_rect.left()-1; int yr=(selectionRect.bottom()+1)*data_rect.height()/image->y()+data_rect.top()-1; return QRect(QPoint(x,y),QPoint(xr,yr));}/** Send text about selection rectangle to statusbar @param txt selection-rectangle-text*/void ImageView::selText(const QString &txt) { selectionText=txt;}/** Return size hint for the widget*/QSize ImageView::sizeHint() const { if (image) {  //Size of image  return QSize(image->x(),image->y()); } else {  //Some default  return QSize(600,400); }}/** Return minimum size neede to display the widget*/QSize ImageView::minSize() const { if (image && !isSet("scale")) {  //Size of image  int x=image->x();  int y=image->y();  x=x*zoom/100;  y=y*zoom/100;  return QSize(x,y); } else {  //No minimum  return QSize(0,0); }}/** Set mode of operation for the widget (simple viewing, color picking, etc ... @param m new mode for the data view*/void ImageView::setMode(ImageViewMode m) { mode=m; if (!image) {  d->setCursor(Qt::ArrowCursor);  return; } switch(mode) {  case crosshair: {   QPixmap* pick=ic->getIcon("target.png");   d->setCursor(QCursor(*pick));   break;  }  case view: {   d->setCursor(Qt::ArrowCursor);   break;  }  default: {   d->setCursor(Qt::ArrowCursor);  } }}/** Open image with given name in viewer @param name name of image*/void ImageView::loadImage(const QString &name) { if (image) delete image; image=new Image(name); flushImage();}/** Open image with data from clipboard @return true if the image was loaded, false if clipboard does not contain compatible image*/bool ImageView::loadImagePaste() { Image *im=Image::loadFromPaste(); if (im) {  if (image) delete image;  image=im;  flushImage();  return true; } return false;}/** Create image from given pixmap @param px pixmap to use as source of image*/void ImageView::loadImage(QPixmap px) { if (image) delete image; image=new Image(px); flushImage();}/** Use after new image is loaded to flush/redraw various data */void ImageView::flushImage() { update(); cancelRect(); emit zoomChanged(zoom); emit info("");}/** Handler called when widget is resized @param e Event data*/void ImageView::resizeEvent(QResizeEvent *e) { applyZoom(); //Call parent method QScrollArea::resizeEvent(e);}/** Save image in viewer under given name @param name name of image*/void ImageView::saveImage(const QString &name) { if (image) image->saveImage(name);}/** Load state of specified optional feature from settings (default value is false) @param name Feature name */bool ImageView::isSet(const QString &name) const { return globalSettings->readBool("view/"+name,false);}/** Set specified display feature to be on or off @param name Name of the feature @param state New state: true=on, false=off*/void ImageView::setFeature(const QString &name,bool state) { globalSettings->write("view/"+name,state); update();}/** Change internal widget's minimum size. Schedule this and internal widget to repaint.*/void ImageView::update() { d->setMinimumSize(minSize()); d->update(); QScrollArea::update();}/** Use when settings "view in fullscreen" was changed*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -