QT中随着鼠标放大缩小图形

算法原理:鼠标放在图形区域的某一块位置,得到鼠标的点坐标,将图形以该点为中心缩放图形。

1、先指定一块图形显示区域。

    QRect updateArea = QRect(388, 31, 812, 729);

2、得到鼠标坐标位置,以及设置鼠标上滑放大,下滑缩小函数。

protected:
    void wheelEvent(QWheelEvent* event) override {

        this->initX = event->scenePosition().x();
		this->initY = event->scenePosition().y();
        if (this->initX >= 400 && this->initX <= 1200 && this->initY >= 40 && this->initY <= 760)
        {
            int numDegrees = event->angleDelta().y() / 8;
            int numSteps = numDegrees / 15;

            // 根据滚轮滚动方向调用放大或缩小的函数
            if (numSteps > 0) {
                zoomOut();
            }
            else {
                zoomIn();
            }

            event->accept();
        }
    }
private:
    void zoomIn();

    void zoomOut();
void BRPA::zoomIn() {
    // 缩小到 80%
    //scale *= 0.8;
    this->scale = 0.8;
    this->needToUpdateArea = true;
    update(updateArea); // 重新绘制界面
}

void BRPA::zoomOut() {
    // 放大到 120%
    //scale *= 1.2;
    this->scale = 1.2;
    this->needToUpdateArea = true;
    update(updateArea); // 重新绘制界面
}

3、我的图形和线段的数据结构

struct Point2
{
    float x = 0;
    float y = 0;
};
struct Segment2
{
	Point2 source;
    Point2 target;
};
struct Polygon2
{
    std::vector<Point2> poly;
};
struct PointData
{
    std::vector<Polygon2> support;
    std::vector<Segment2> fill;
    std::vector<Polygon2> polys;
};

4、重写绘制图形函数

void paintEvent(QPaintEvent* event) override;(.h 函数声明)
void BRPA::paintEvent(QPaintEvent* event){
    Q_UNUSED(event);
    if (this->needToUpdateArea)
    {
        QPainter painter(this);
        painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
        painter.fillRect(this->updateArea, Qt::white);
        painter.setPen(QPen(Qt::red, 1));
//this->drawData 为     PointData drawData;
        for (auto it = this->drawData.fill.begin(); it != this->drawData.fill.end(); it++)
        {
            //std::cout << it->source.x << " " << it->source.y << " " << it->target.x << " " << it->target.y << std::endl;
//this->initX  this->initY   为鼠标点的位置
            it->source.x = (it->source.x  - this->initX) * this->scale + this->initX;
			it->source.y = (it->source.y  - this->initY) * this->scale + this->initY;
			it->target.x = (it->target.x  - this->initX) * this->scale + this->initX;
			it->target.y = (it->target.y  - this->initY) * this->scale + this->initY;
            //std::cout<<it->source.x<<" "<<it->source.y<<" "<<it->target.x<<" "<<it->target.y<<std::endl;
            //painter.drawLine(QPointF((it->source.x - this->initX)*this->scale + this->initX, (it->source.y - this->initY) * this->scale + this->initY), QPointF((it->target.x - this->initX) * this->scale + this->initX, (it->target.y - this->initY) * this->scale + this->initY));
            painter.drawLine(QPointF(it->source.x, it->source.y), QPointF(it->target.x , it->target.y ));
        }
        painter.setPen(QPen(Qt::black));
        for (auto polyIt = this->drawData.polys.begin(); polyIt != this->drawData.polys.end(); polyIt++)
        {
            polyIt->poly.front().x = (polyIt->poly.front().x - this->initX) * this->scale + this->initX;
			polyIt->poly.front().y = (polyIt->poly.front().y - this->initY) * this->scale + this->initY;
            for (auto vert = polyIt->poly.begin(); vert != (--polyIt->poly.end());  vert++)
            {
				(vert+1)->x = ((vert+1)->x - this->initX) * this->scale + this->initX;
				(vert+1)->y = ((vert+1)->y - this->initY) * this->scale + this->initY;
                painter.drawLine(QPointF(vert->x, vert->y), QPointF((vert+1)->x, (vert+1)->y));
            }
            //painter.drawLine(QPointF(polyIt->poly.back().x, polyIt->poly.back().y), QPointF(polyIt->poly.front().x, polyIt->poly.front().y));
        }
        painter.setPen(QPen(Qt::green));
        for (auto supIt = this->drawData.support.begin(); supIt != this->drawData.support.end(); supIt++)
        {
			supIt->poly.front().x = (supIt->poly.front().x - this->initX) * this->scale + this->initX;
			supIt->poly.front().y = (supIt->poly.front().y - this->initY) * this->scale + this->initY;
            for (auto supVer = supIt->poly.begin(); supVer != (--supIt->poly.end()); supVer++)
            {
                (supVer+1)->x = ((supVer+1)->x - this->initX) * this->scale + this->initX;
				(supVer+1)->y = ((supVer+1)->y - this->initY) * this->scale + this->initY;
				painter.drawLine(QPointF(supVer->x, supVer->y), QPointF((supVer+1)->x, (supVer+1)->y));
            }
        }
        this->needToUpdateArea = false;
    }
}

其中QPainter有直接绘制poly的drawPolygon等函数,但最终都殊途同归。

如有误,请指出,谢谢!

  • 9
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值