项目场景:
最近有个项目,要实现FPGA原理图功能,其中涉及到以鼠标为中心缩放的问题,效果应该和CAD的缩放效果类似,顺便也做个记录。
废话不多说,直接上代码
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include"draw_figure.h"
#include<QScrollBar>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
bool eventFilter(QObject *object, QEvent *event);
public:
draw_figure drawFigure;
public slots:
void getWheelSlot(QWheelEvent *event);
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
}
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->scrollArea->setWidget(&drawFigure);
connect(&drawFigure,&draw_figure::mouseWheelZoom,this,&MainWindow::getWheelSlot);
ui->scrollArea->setWidgetResizable(true);
ui->scrollArea->viewport()->installEventFilter(this);//QSCrollArea 滚动区域是viewport()
}
MainWindow::~MainWindow()
{
delete ui;
}
bool MainWindow::eventFilter(QObject *target, QEvent *event)
{
if(target == ui->scrollArea->viewport())
{
if(event->type() == QEvent::Wheel)
{
event->ignore();
return true; //只针对scrollArea窗口禁用滚轮滚动功能,返回true表示过滤
}else {
return false;//返回false表示不过滤
}
}
else
{
return false;
}
}
void MainWindow::getWheelSlot(QWheelEvent *event)
{
QScrollBar *tmph = ui->scrollArea->horizontalScrollBar();
QScrollBar *tmpv = ui->scrollArea->verticalScrollBar();
QPoint pos = event->pos();
if(event->delta()>0)
{
drawFigure.scale *=1.05;
drawFigure.setFixedSize(drawFigure.width()*1.05,drawFigure.height()*1.05);
double value_x = event->x()*1.05 - event->x();
tmph->setValue( tmph->value()+ value_x);
double value_y = event->y()*1.05 - event->y();
tmpv->setValue(tmpv->value()+ value_y);
}else{
drawFigure.setFixedSize(drawFigure.width()/1.05,drawFigure.height()/1.05);
drawFigure.scale =drawFigure.scale/1.05;
double value_x = event->x()/1.05 - event->x();
double value_y = event->y()/1.05 - event->y();
tmph->setValue( tmph->value()+ value_x);
tmpv->setValue(tmpv->value()+ value_y);
}
}
draw_figure.h
#ifndef DRAW_FIGURE_H
#define DRAW_FIGURE_H
#include <QWidget>
#include<QWheelEvent>
#include<QPaintEvent>
#include<QPainter>
#include<QDebug>
#include<QMouseEvent>
#include<QScrollBar>
#include<QAbstractScrollArea>
class draw_figure : public QWidget
{
Q_OBJECT
public:
explicit draw_figure(QWidget *parent = nullptr);
double scale=1.0;
protected:
void paintEvent(QPaintEvent *event);
void wheelEvent(QWheelEvent *event);
void mouseMoveEvent(QMouseEvent *event);
void mousePressEvent(QMouseEvent *event);
signals:
void mouseWheelZoom(QWheelEvent *event);
public slots:
};
#endif // DRAW_FIGURE_H
draw_figure.cpp
#include "draw_figure.h"
draw_figure::draw_figure(QWidget *parent) : QWidget(parent)
{
setCursor(Qt::CrossCursor);
}
void draw_figure::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
painter.scale(scale,scale);
painter.drawRect(200,100,300,600);
}
void draw_figure::wheelEvent(QWheelEvent *event)
{
if (event->delta() > 0)
{
emit mouseWheelZoom(event);
}
else
{
emit mouseWheelZoom(event);
}
}
void draw_figure::mouseMoveEvent(QMouseEvent *event)
{
// qDebug()
}
void draw_figure::mousePressEvent(QMouseEvent *event)
{
// qDebug()<<event->pos();
}
敲黑板:别用resize(),应该用setFixedSize();
setFixedSize()是设置最大最小值,如果调用resize(X,Y),X,Y小于最大的时候,resize不生效。
手懒的同学,点这里: 最简单的方式实现QPainter以鼠标为中心缩放.