QT-实现图片浏览器

摘录自:https://www.cnblogs.com/lifexy/p/9057046.html

painter.cpp

#include "painter.h"

painter::painter()
  :Paint(10 , 10 , 810 , 810)
  ,Alloffset(0 , 0)
  ,label(QString::fromLocal8Bit("100%") , this)
  ,BigButton(QString::fromLocal8Bit("放大") , this)
  ,LittleButton(QString::fromLocal8Bit("缩小") , this)
  ,LiftButton(QString::fromLocal8Bit("向左") , this)
  ,RightButton(QString::fromLocal8Bit("向右") , this)
  ,UpButton(QString::fromLocal8Bit("向上") , this)
  ,DownButton(QString::fromLocal8Bit("向下") , this)
  ,ResetButton(QString::fromLocal8Bit("还原") , this)
  ,OpenButton(QString::fromLocal8Bit("打开文件") , this)
{
    ratio = 1.0;
    action = painter::None;

    BigButton.setGeometry(822 , 10 ,60 ,25);    // x y w h
    connect(&BigButton , SIGNAL(clicked()) , this , SLOT(onBigClicked()));

    LittleButton.setGeometry(822 , 40 , 60 ,25);
    connect(&LittleButton , SIGNAL(clicked()) , this , SLOT(onLittleClicked()));

    LiftButton.setGeometry(822,70,60,25);
    connect(&LiftButton,SIGNAL(clicked()),this,SLOT(OnLiftClicked()));

    RightButton.setGeometry(822,100,60,25);
    connect(&RightButton,SIGNAL(clicked()),this,SLOT(OnRightClicked()));

    UpButton.setGeometry(822,130,60,25);
    connect(&UpButton,SIGNAL(clicked()),this,SLOT(onUpClicked()));

    DownButton.setGeometry(822,160,60,25);
    connect(&DownButton,SIGNAL(clicked()),this,SLOT(onDownClicked()));

    ResetButton.setGeometry(822,190,60,25);
    connect(&ResetButton,SIGNAL(clicked()),this,SLOT(onResetClicked()));

    OpenButton.setGeometry(822,220,60,25);
    connect(&OpenButton,SIGNAL(clicked()),this,SLOT(onOpenClicked()));

    label.move(840 , 260);
    resize(890 , 850);

    this->setWindowTitle(QString::fromLocal8Bit("图片浏览器"));
}

void painter::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);
    QPainter painter(this);
    painter.setRenderHints(QPainter::SmoothPixmapTransform | QPainter::Antialiasing | QPainter::TextAntialiasing);  //渲染
    //painter.drawRect(Paint.x() - 1 , Paint.y() - 1 , Paint.width() + 1 , Paint.height() + 1);
    painter.drawRect(Paint.x(), Paint.y(), Paint.width(), Paint.height());//画框

    if(image.isNull())
    {
        return;
    }

    int NowW = ratio * pixW;
    int NowH = ratio * pixH;

    if(action == painter::Shrink)
    {
        ratio -= (0.05 * ratio);
        if(ratio < 0.018)
        {
            ratio = 0.01;
        }

        /*显示比例*/
        QString str;
        str.sprintf("%.0f%",ratio*100);
        label.setText(str) ;
        qDebug()<<QString::fromLocal8Bit("缩小:")<<ratio;
    }

    else if(action == painter::Amplification)
    {
        ratio += 0.05 * ratio;
        if(ratio>4.5){
            ratio = 5.000;
        }

        /*显示比例*/
        QString str;
        str.sprintf("%.0f%",ratio*100);
        label.setText(str);
        qDebug()<<QString::fromLocal8Bit("放大:")<<ratio;
    }

    if(action == painter::Amplification || action == painter::Shrink || action == painter::Reset)
    {
        qDebug() << "111";
        NowW = ratio *pixW;
        NowH = ratio *pixH;

        crtPix= pix.scaled(NowW, NowH,Qt::KeepAspectRatio,Qt::SmoothTransformation); //重新装载

        action=painter::None;
    }

    if(action==painter::Move)                    //移动
    {
        int offsetx=Alloffset.x()+offset.x();
        Alloffset.setX(offsetx);

        int offsety=Alloffset.y()+offset.y();
        Alloffset.setY(offsety);
        action=painter::None;
    }

    if(abs(Alloffset.x())>=(Paint.width()/2 + NowW/2 -10))    //限制X偏移值
    {
        if(Alloffset.x()>0)
            Alloffset.setX(Paint.width()/2 + NowW/2 -10);
        else
         Alloffset.setX(-Paint.width()/2 + -NowW/2 +10);

    }
    if(abs(Alloffset.y())>=(Paint.height()/2 + NowH/2 -10))    //限制Y偏移值
    {
        if(Alloffset.y()>0)
            Alloffset.setY(Paint.height()/2 + NowH/2 -10);
        else
         Alloffset.setY(-Paint.height()/2 + -NowH/2 +10);

    }

    int x = Paint.width()/2 + Alloffset.x() -NowW/2;
    if(x<0)
        x=0;

    int y = Paint.height()/2 + Alloffset.y() -NowH/2;
    if(y<0)
        y=0;

    int  sx = NowW/2 - Paint.width()/2 - Alloffset.x();
    if(sx<0)
        sx=0;

    int  sy = NowH/2 - Paint.height()/2 - Alloffset.y();
    if(sy<0)
        sy=0;

    int w =(NowW - sx)>Paint.width()? Paint.width() : (NowW - sx);
    if(w>(Paint.width()-x))
        w = Paint.width()-x;

    int h =(NowH - sy)>Paint.height()? Paint.height() : (NowH - sy);
    if(h>(Paint.height()-y))
        h = Paint.height()-y;

    painter.drawTiledPixmap(x+Paint.x(),y+Paint.y(),w,h,crtPix,sx,sy);             //绘画图形
}

bool painter::event(QEvent *event)
{
    static bool press = false;
    static QPoint PreDot;

    if(event->type() == QEvent::MouseButtonPress)
    {
        QMouseEvent *mouse = dynamic_cast<QMouseEvent*>(event);
        //判断苏表左键按下且实在绘图区域内
        if(mouse->button() == Qt::LeftButton && Paint.contains(mouse->pos()))
        {
            press = true;
            //QApplication::setOverrideCursor(Qt::OpenHandCursor);            // 设置鼠标样式
            this->setCursor(Qt::OpenHandCursor);

            PreDot = mouse->pos();
        }
        qDebug() << "event press";
    }

    else if(event->type() == QEvent::MouseButtonRelease)
    {
        QMouseEvent *mouse = dynamic_cast<QMouseEvent*>(event);

        //判断鼠标左键是否释放
        if(mouse->button() == Qt::LeftButton && press)
        {
            QApplication::setOverrideCursor(Qt::ArrowCursor);
            press = false;
        }
        qDebug() << "event relesae";
    }

    if(event->type() == QEvent::MouseMove)
    {
        //按下拖动才能实现
        if(press)
        {
            QMouseEvent *mouse = dynamic_cast<QMouseEvent*>(event);

            offset.setX(mouse->x() - PreDot.x());
            offset.setY(mouse->y() - PreDot.y());
            PreDot = mouse->pos();
            action = painter::Move;

            this->update();
        }

        qDebug() << "event move";
    }
    return QWidget::event(event);
}

void painter::wheelEvent(QWheelEvent* event)     //鼠标滑轮事件
{
    if(event->delta()>0) {      //上滑,缩小
        action=painter::Shrink;
        this->update();
    } else {                    //下滑,放大
        action=painter::Amplification;
        this->update();
    }
    event->accept();
}

void painter::onLittleClicked()
{
    action=painter::Amplification;
    this->update();
}

void painter::onOpenClicked()
{
    QString str = QFileDialog::getOpenFileName(this,
                                 "open",
                                 "E:",
                                 "img (*.png *.jpg)");

    if(!str.isNull())
    {
       image.load(str);
       pix = pix.fromImage(image);

       crtPix = pix;
       pixW = image.width();            //图片宽
       pixH = image.height();           //图片高
       qDebug()<<str<<pixW<<pixH;
       this->setWindowTitle(QStringLiteral("image read") + "(" + str + ")");
       onResetClicked();
    }
}

void  painter::onBigClicked()
{
    action=painter::Shrink;
    this->update();
}

void painter::onUpClicked()
{
    action=painter::Move;
    offset.setX(0);
    offset.setY(-20);

    this->update();
}

void painter::onDownClicked()
{
    action=painter::Move;
    offset.setX(0);
    offset.setY(20);
    this->update();
}

void painter::onResetClicked()
{
    action=painter::Reset;
    Alloffset.setX(0);
    Alloffset.setY(0);
    ratio = 1.000;
    label.setText("100%");
    this->update();
}

void painter::OnLiftClicked()
{
    action=painter::Move;
    offset.setX(-20);
    offset.setY(0);

    this->update();
}

void painter::OnRightClicked()
{
    action=painter::Move;
    offset.setX(20) ;
    offset.setY(0) ;

    this->update();
}

painter.h

#ifndef PAINTER_H
#define PAINTER_H

#include <QWidget>
#include <QtGui>
#include <QLabel>
#include <QPushButton>
#include <QComboBox>
#include <QApplication>
#include <QFileDialog>
#include <QImage>

class painter : public QWidget
{
    Q_OBJECT
private :
    QPixmap  pix;
    QPixmap  crtPix;
    int action;          //动作(放大,缩小,移动...)
    int pixW;            //图片宽
    int pixH;            //图片高

    QRect Paint;         //绘画区域

    QImage image;        //打开的图片


    float ratio;              //缩放比例
    QPoint offset;           //一次的图片偏移值
    QPoint Alloffset;          //总偏移
    QLabel label;

    QPushButton  BigButton;
    QPushButton  LittleButton;
    QPushButton  LiftButton;
    QPushButton  RightButton;
    QPushButton  UpButton;
    QPushButton  DownButton;
    QPushButton  ResetButton;
    QPushButton  OpenButton;

    void AddComboItem(QComboBox* cmbo);
    bool event(QEvent * event);
    void wheelEvent(QWheelEvent* e);     //鼠标滑轮事件
private slots:
    void onUpClicked();
    void onDownClicked();
    void onResetClicked();
    void OnLiftClicked();
    void OnRightClicked();
    void onLittleClicked();
    void onBigClicked();

    void onOpenClicked();

    void paintEvent(QPaintEvent *event);

public:
    explicit painter();

   enum  Type {
       None          = 0,
       Amplification ,
       Shrink,
       Lift,
       Right,
       Up,
       Down,
       Move,
       Reset
   };

signals:

};

#endif // PAINTER_H

主要通过鼠标事件与定义的事件相关联,并通过重写painterEvent实现相关操作。实现缩小放大,移动的逻辑跟我上篇相似。

 

posted @ 2021-07-13 11:15  xcn-xcn  阅读(280)  评论(0编辑  收藏  举报