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

6 篇文章 0 订阅

这是最终的效果
在这里插入图片描述
两个类,两个头文件,两个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

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));
}

//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


//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;
}


  • 9
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值