自定义控件 QOpenGLWidget并实现缩放(纯代码)

QScrollArea+QOpenGLWidget 实现缩放,用于显示QImage。

先自定义QOpenGLWidget ,然后自定义QWidget(上图)

glwidget.h

#ifndef GLWIDGET_H
#define GLWIDGET_H

#include <QOpenGLWidget>

class GLWidget : public QOpenGLWidget
{
    Q_OBJECT
public:
    explicit GLWidget(QWidget *parent = nullptr);

    void setImageData(const QImage& img);
protected:
    //重写事件
    void paintEvent(QPaintEvent* e) override;

private:
    QImage mImg;

};

#endif // GLWIDGET_H

glwidget.cpp

#include "glwidget.h"
#include <QPainter>

GLWidget::GLWidget(QWidget *parent)
    : QOpenGLWidget{parent}
{
}

void GLWidget::setImageData(const QImage& img)
{
    if (!img.isNull())
    {
        mImg = img;
        update();
    }
}

void GLWidget::paintEvent(QPaintEvent* e)
{
    QPainter p;
    p.begin(this);
    p.drawImage(rect(), mImg);
    p.end();
}

viewwidget.h

#ifndef VIEWWIDGET_H
#define VIEWWIDGET_H

#include <QWidget>
#include "glwidget.h"
#include <QScrollArea>

class ViewWidget : public QWidget
{
    Q_OBJECT
public:
    explicit ViewWidget(QWidget *parent = nullptr);

signals:

public:
    GLWidget *glWidget;
    QScrollArea *scrollArea;

    float scaleFactor;

private slots:
    void buttonClicked(int id);

};

#endif // VIEWWIDGET_H

viewwidget.cpp

#include "viewwidget.h"
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QPushButton>
#include <QButtonGroup>

#pragma execution_character_set("utf-8")

ViewWidget::ViewWidget(QWidget *parent)
    : QWidget{parent}
    ,glWidget{new GLWidget}
    ,scrollArea{new QScrollArea}
{
//! [1]
    //上下布局,上方为QOpenGLWidget,下方为3个按钮(放大、缩小、适应窗口)
    QVBoxLayout *centralLayout=new QVBoxLayout;
    setLayout(centralLayout);
    centralLayout->setSpacing(0);
    centralLayout->setMargin(0);

    centralLayout->addWidget(scrollArea);
    scrollArea->setBackgroundRole(QPalette::Dark);
    scrollArea->setWidgetResizable(true);
    scrollArea->setWidget(glWidget);

    //下方的3个按钮+1个弹簧,水平布局
    QHBoxLayout* toolboxLayout = new QHBoxLayout;
    centralLayout->addLayout(toolboxLayout);
    toolboxLayout->setSpacing(0);
    toolboxLayout->setMargin(0);

    QPushButton* buttonPlus = new QPushButton(QIcon("://icons/zoom_in.png"), QString(""), this);
    buttonPlus->setMaximumWidth(32);
    toolboxLayout->addWidget(buttonPlus);

    QPushButton* buttonMinus = new QPushButton(QIcon("://icons/zoom_out.png"), QString(""), this);
    buttonMinus->setMaximumWidth(32);
    toolboxLayout->addWidget(buttonMinus);

    QPushButton* buttonFit = new QPushButton(QIcon("://icons/zoom_fit.png"), QString(""), this);
    buttonFit->setMaximumWidth(32);
    toolboxLayout->addWidget(buttonFit);

    toolboxLayout->addStretch();

    //按钮组,方便多按钮调用一个函数
    QButtonGroup *toolbox=new QButtonGroup;
    toolbox->addButton(buttonPlus, 0);
    toolbox->addButton(buttonMinus, 1);
    toolbox->addButton(buttonFit, 2);
    connect(toolbox, SIGNAL(buttonClicked(int)), this, SLOT(buttonClicked(int)));
//! [1]

    //初始化缩放系数
    scaleFactor = 1.0;
}

void ViewWidget::buttonClicked(int id)
{
    switch (id)
    {
    case 0: //plus
        scaleFactor *= 1.25;
        glWidget->setFixedSize(scrollArea->width() * scaleFactor, scrollArea->height() * scaleFactor);
        break;
    case 1: //minus
        scaleFactor *= 0.8;
        glWidget->setFixedSize(scrollArea->width() * scaleFactor, scrollArea->height() * scaleFactor);
        break;
    case 2: //fit
        scaleFactor = 1.0;
        glWidget->setMinimumSize(0, 0);
        glWidget->setMaximumSize(QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX));
        glWidget->resized();
        break;
    default:
        break;
    }
}

 【参考】

QT学习笔记之QT代码编写控件不显示的问题 - sgggr - 博客园 (cnblogs.com)

 

【画圆、文字,以及随图缩放】

void GLWidget::paintEvent(QPaintEvent* e)
{
    QPainter p;
    p.begin(this);
    p.drawImage(rect(), m_qImg);

    float factorX = 1.0*rect().width() / m_qImg.width();
    float factorY = 1.0*rect().height() / m_qImg.height();
    p.setFont(QFont("Arial", 14));
    for (int i = 0; i < m_vCircle.length(); i++)
    {
        //画圆
        int x = factorX*m_vCircle[i].x(); //矩形左上角
        int y= factorY*m_vCircle[i].y();
        p.drawEllipse(x + 50 * factorX / 2, y + 50 * factorY / 2, 50 * factorX, 50 * factorX);
        //在圆附近显示文字
        QString txt = QString("清晰度:%1").arg(m_vSharpness[i]);
        p.drawText(QPointF(x + 50 * factorX / 2, y + 50 * factorY / 2), txt);
    }

    p.end();
}

 

posted @ 2023-03-10 17:24  夕西行  阅读(700)  评论(0编辑  收藏  举报