当前位置:   article > 正文

QT 实现放大镜跟随鼠标效果

QT 实现放大镜跟随鼠标效果

这是最终的效果
在这里插入图片描述
两个类,两个头文件,两个CPP文件:

Lens.h
#ifndef LENSE_H
#define LENSE_H
#include <QWidget>
class Lense : public QWidget
{
    Q_OBJECT
public:
    explicit Lense(QWidget *parent = nullptr);
    void setRadius(int r);
    void setZoomTarget(QWidget * target);
protected:
    virtual void paintEvent(QPaintEvent *event) override;
    virtual void mouseMoveEvent(QMouseEvent *event) ;
private:
    QWidget* mZoomTarget;
    int mRadius;
};
#endif // LENSE_H

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
Lens.cpp
#include "Lense.h"
#include <QPaintEvent>
#include <QPainter>
#include <QDebug>
#include <QPainterPath>
Lense::Lense(QWidget *parent) : QWidget(parent),mZoomTarget(nullptr),mRadius(64)
{
    resize(mRadius,mRadius);
    setMouseTracking(true);
}
void Lense::setRadius(int r){
    if(r > 0 && mRadius != r){
        mRadius = r;
        setFixedSize(r,r);
    }
}
void Lense::mouseMoveEvent(QMouseEvent *event) {
    if(!event) return;
    auto pos = mapToParent( event->pos() );
    pos.setX(pos.x() - width() / 2);
    pos.setY(pos.y() - height() / 2);
    move(pos);
    if(parent()){
        QWidget * w = dynamic_cast<QWidget*>(parent());
        w->update();
    }
    event->ignore();//让父窗口检测到鼠标移出指定范围
}
void Lense::setZoomTarget(QWidget * target){
    mZoomTarget = target;
}
void Lense::paintEvent(QPaintEvent *event) {
    if(!event) return;
    QPainter painter(this);
    const auto rect = QRectF(2,2,mRadius - 4,mRadius - 4);
    painter.setBrush(Qt::NoBrush);

    QPen pen(QColor("black"));
    pen.setWidth(4);
    painter.setPen(pen);
    painter.drawRoundedRect(rect,rect.width(),rect.width());

    QPainterPath pp;
    pp.moveTo(mRadius/2,mRadius/2);
    pp.arcTo(rect,0,360);
    painter.setClipPath(pp);

    if(!mZoomTarget) return;

    auto center = mapToGlobal(QPoint(mRadius/2,mRadius/2));
    center = mZoomTarget->mapFromGlobal(center);

    painter.drawPixmap(rect.toRect(),mZoomTarget->grab(
        QRect(center - QPoint(mRadius/3,mRadius/3),center + QPoint(mRadius/3,mRadius/3))).scaled(mRadius*1.33,mRadius *1.33));
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
//Widget.h
#ifndef ZOOMLENSE_H
#define ZOOMLENSE_H
#include <QLabel>
#include <QWidget>
#include <Lense.h>
class Widget : public QWidget
{
    Q_OBJECT
public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
protected:
    void resizeEvent(QResizeEvent *event) override;
    void mouseMoveEvent(QMouseEvent *event) override;
    bool eventFilter(QObject *watched, QEvent *event);
private:
    QLabel * mLabel;
    Lense * mLens;
};
#endif // ZOOMLENSE_H


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
//Widget.cpp
#include "Widget.h"
#include "ui_Widget.h"
#include <QDebug>
#include <QResizeEvent>
static const QString speech("I don't have a dream.\n\nNow, before you start throwing inspirational quotes and vision boards at me, let me assure you, it's not a case of ambition deficiency. No, it's a deliberate choice to embrace the uncharted territory of dreamless living.\n\nWhile the world is abuzz with tales of people chasing their dreams, I find solace in the fact that I'm not chasing anything. You know, they say, :Shoot for the moon. Even if you miss, you'll land among the stars. Well, I prefer to stay grounded, feet firmly planted on the Earth, avoiding potential interstellar mishaps and alien encounters.\n\nSure, dreams can be the wind beneath your wings, but I've always been more of a 'let's take a leisurely stroll' kind of person. No need to break a sweat when you can amble through life with a cup of coffee in hand, savoring the flavor of the ordinary.\n\nIn a world filled with visionaries, I am the anomaly – the dreamless wonder, navigating existence without a roadmap to success or a GPS for fulfillment. People often ask me:What's your passion? What's your purpose? Well, I'm passionate about perfectly toasting marshmallows and my purpose is to find the TV remote that seems to have mastered the art of disappearing.");
#include <QApplication>
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();
    return a.exec();
}
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::ZoomLense)
{
    ui->setupUi(this);
    setMouseTracking(true);
    setStyleSheet("background:white;font-size:12px;");

    mLabel = new QLabel(this);
    mLabel->move(20,20);
    mLabel->setWordWrap(true);
    mLabel->setText(speech);
    mLabel->setStyleSheet("border:1px solid black;padding:8px;");

    resize(600,360);

    mLens = new Lense(this);
    mLens->setRadius(80);
    mLens->setZoomTarget(mLabel);
    mLens->hide();

    mLabel->setMouseTracking(true);
    mLabel->installEventFilter(this);
}
bool Widget::eventFilter(QObject *watched, QEvent *event){
    if(watched == mLabel){
        if(event->type() == QEvent::MouseMove){
            if(mLens->isHidden()){
                QMouseEvent * e = dynamic_cast<QMouseEvent*>(event);
                auto pos = mLabel->mapToParent( e->pos() );
                pos.setX(pos.x() - mLens->width() /2);
                pos.setY(pos.y() - mLens->height()/2);
                mLens->move(pos);
                mLens->show();
            }
            event->accept();
            return true;
        }
    }
    return false;
}
void Widget::mouseMoveEvent(QMouseEvent *event) {
    if(!event) return;
    const auto pos = event->pos();
    auto rect = mLabel->rect();
    rect.moveTo(mLabel->pos());
    if(!rect.contains(pos)){
        if(mLens->isVisible()) mLens->hide();
    }
}
void Widget::resizeEvent(QResizeEvent *event) {
    if(!event) return;
    mLabel->setFixedWidth(event->size().width() - 40);
    mLabel->setFixedHeight(event->size().height()-40);
    QWidget::resizeEvent(event);
}
Widget::~Widget()
{
    delete ui;
}


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/187386
推荐阅读
相关标签
  

闽ICP备14008679号