QT-QLabel导入并显示图片

  • Post author:
  • Post category:其他




效果

在这里插入图片描述



主要功能及逻辑介绍

  • 界面上导入俩类八张图片,其控件皆为QLabel,导入的图片可以缩放,拖动,还原。导入的方式分为双击选择文件导入,和直接拖拽导入等。
  • 总的布局结构为:一个水平布局中插入俩个组,每个组中插入一个网格布局,网格布局中设置各种控件
  • 要实现QLabel的缩放与拖拽等功能,需要重写QLabel,重写paintEventd,mouseMoveEvent等函数。重写后想要鼠标悬停显示字体,还需重写event,设置对应得ToolTip。
  • 要得到双击弹窗选择路径,需要重写事件过滤器eventFilter
  • 拖拽进入QLabel可以选择使用事件过滤器进行处理,也可以选择重写dropEvent与eventFilter函数来实现,注意要先设置好允许拖拽



.h代码(代码需要修正)

#include <QComboBox>
#include <QFileDialog>
#include <QGroupBox>
#include <QPainter>
#include <QToolTip>

#define LABLE_WIDTH 150
#define LABLE_HEIGHT 150
class MyWidget;
class MyLable;
class IamgeSourceWidget : public QWidget
{
    friend class MyWidget;

public:

    IamgeSourceWidget(QWidget *parnt = nullptr);
    void inIt();
    /// @brief 选择资源图片文件
    /// @param plabel
    /// @param isPNG 是否为PNG
    void switchFileImage(QLabel *plabel, bool isPNG = false);
    /// @brief 设置label参数
    /// @param pLabel
    void setLabelParam(QLabel *pLabel);
    /// @brief 加载已有图片
    /// @param var
    void setInitLabelImage(const QVariant &var, QLabel *label);

protected:
    /// @brief label事件过滤器
    /// @param obj
    /// @param event
    /// @return
    virtual bool eventFilter(QObject *obj, QEvent *event) override;

private:
    //***PNG控件组***//
    MyLable *pngNormalLabel;
    MyLable *pngDisableLabel;
    MyLable *pngWarningLabel;
    MyLable *pngErrorLabel;
    QGroupBox *pngGroupBox;
    //***SVG控件组***//
    MyLable *svgNormalLabel;
    MyLable *svgDisableLabel;
    MyLable *svgWarningLabel;
    MyLable *svgErrorLabel;
    QGroupBox *svgGroupBox;

    QList<QString> picNames; // PNG名称
    QList<QString> svgNames; // SVG名称

    MyWidget *myWidget; // 二级弹窗界面
 }

class MyWidget : public QWidget
{
public:
    MyWidget(IamgeSourceWidget *image, QLabel *label, QWidget *parnt = 0);

public slots:
    void onSoureButton();
    void onDrawButton();

private:
    QLineEdit *edit;
    QPushButton *soureButton;
    QPushButton *drawButton;
    QLabel *mLabel;
    IamgeSourceWidget *mImage;
};

class MyLable : public QLabel
{
public:
    MyLable(QString str, QWidget *parnt = nullptr);

protected:
    void paintEvent(QPaintEvent *) override;
    void mouseMoveEvent(QMouseEvent *ev) override;
    void mousePressEvent(QMouseEvent *ev) override;
    void mouseReleaseEvent(QMouseEvent *ev) override;
    void wheelEvent(QWheelEvent *event) override;
    void resizeEvent(QResizeEvent *event) override;
    void changeWheelValue(QPoint event, int value);
    bool event(QEvent *e) override;

private:
    double m_scaleValue;  // 图片缩放倍数
    QPointF m_drawPoint;  // 绘图起点
    QPointF m_mousePoint; // 鼠标当前位置点
    QRect m_rectPixmap;   // 被绘图片的矩形范围
    bool m_isMousePress;  // 鼠标是否按下

    const double SCALE_MAX_VALUE; // 最大放大到原来的10倍
    const double SCALE_MIN_VALUE; // 最小缩小到原来的0.5倍
    QString strs;
};



.cpp代码(代码需要修正)

#include "WizardIamgeSourceWidget.h"

IamgeSourceWidget::IamgeSourceWidget( QWidget *parnt) : QWidget(parnt)
{
    picNames << tr("正常状态图片") << tr("禁用状态图片") << tr("警告状态图片") << tr("错误状态图片");
    svgNames << tr("0°图片") << tr("90°图片") << tr("180°图片") << tr("270°图片");
    inIt();
}

void IamgeSourceWidget::inIt()
{
    this->isElec = isElec;
    pngGroupBox = new QGroupBox(tr("PNG图片"));
    QGridLayout *pnglayout = new QGridLayout(this);
    pngNormalLabel = new QLabel(picNames.at(0), this);
    setInitLabelImage(picA.value(Kcc::BlockDefinition::A_NORMAL_PIC), pngNormalLabel);
    setLabelParam(pngNormalLabel);
    pngDisableLabel = new MyLable(picNames.at(1));
    setInitLabelImage(picA.value(Kcc::BlockDefinition::A_NORMAL_PIC), pngDisableLabel);
    setLabelParam(pngDisableLabel);
    pngWarningLabel = new MyLable(picNames.at(2));
    setInitLabelImage(picA.value(Kcc::BlockDefinition::A_WARNING_PIC), pngWarningLabel);
    setLabelParam(pngWarningLabel);
    pngErrorLabel = new MyLable(picNames.at(3));
    setInitLabelImage(picA.value(Kcc::BlockDefinition::A_ERROR_PIC), pngErrorLabel);
    setLabelParam(pngErrorLabel);
    pnglayout->addWidget(pngNormalLabel, 0, 0, 1, 1);
    pnglayout->addWidget(pngDisableLabel, 0, 1, 1, 1);
    pnglayout->addWidget(pngWarningLabel, 1, 0, 1, 1);
    pnglayout->addWidget(pngErrorLabel, 1, 1, 1, 1);
    pngGroupBox->setLayout(pnglayout);

    svgGroupBox = new QGroupBox(tr("SVG图片"));
    QGridLayout *svglayout = new QGridLayout(this);
    svgNormalLabel = new MyLable(svgNames.at(0));
    setInitLabelImage(picB.value(Kcc::BlockDefinition::B_NORMAL_PIC), svgNormalLabel);
    setLabelParam(svgNormalLabel);
    svgDisableLabel = new MyLable(svgNames.at(1));
    setInitLabelImage(picB.value(Kcc::BlockDefinition::B_DISABLE_PIC), svgDisableLabel);
    setLabelParam(svgDisableLabel);
    svgWarningLabel = new MyLable(svgNames.at(2));
    setInitLabelImage(picB.value(Kcc::BlockDefinition::B_WARNING_PIC), svgWarningLabel);
    setLabelParam(svgWarningLabel);
    svgErrorLabel = new MyLable(svgNames.at(3));
    setInitLabelImage(picB.value(Kcc::BlockDefinition::B_ERROR_PIC), svgErrorLabel);
    setLabelParam(svgErrorLabel);
    svglayout->addWidget(svgNormalLabel, 0, 0, 1, 1);
    svglayout->addWidget(svgDisableLabel, 0, 1, 1, 1);
    svglayout->addWidget(svgWarningLabel, 1, 0, 1, 1);
    svglayout->addWidget(svgErrorLabel, 1, 1, 1, 1);
    svgGroupBox->setLayout(svglayout);

    QVBoxLayout *vlayout = new QVBoxLayout;
    QHBoxLayout *hlayout = new QHBoxLayout;
    QLabel *messable = new QLabel(tr("提示:双击选择图片,图片可以拖动,还原或缩放进行预览"));
    hlayout->addWidget(pngGroupBox);
    hlayout->addWidget(svgGroupBox);
    vlayout->addLayout(hlayout);
    vlayout->addWidget(messable);
    setLayout(vlayout);
    setAcceptDrops(true);
}

void IamgeSourceWidget::setInitLabelImage(const QVariant &var, QLabel *label)
{
    QImage image = qvariant_cast<QImage>(var);
    if (!var.isNull()) {
        label->setPixmap(QPixmap::fromImage(image));
        label->show();
    }
}

bool IamgeSourceWidget::eventFilter(QObject *obj, QEvent *event)
{
    QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
    if (obj == pngNormalLabel) {
        if (event->type() == QEvent::MouseButtonDblClick) {
            if (mouseEvent->button() == Qt::LeftButton) {
                switchFileImage(pngNormalLabel, true);
            }
        }

        // if ((event->type() == QEvent::DragEnter)) {
        //     QDragEnterEvent *dee = dynamic_cast<QDragEnterEvent *>(event);
        //     dee->acceptProposedAction();
        //     return true;
        // } else if (event->type() == QEvent::Drop) {
        //     // [[3]]: 当放操作发生后, 取得拖放的数据
        //     QDropEvent *de = dynamic_cast<QDropEvent *>(event);
        //     QList<QUrl> urls = de->mimeData()->urls();
        //     if (urls.isEmpty()) {
        //         return true;
        //     }
        //     QString path = urls.first().toLocalFile();
        //     // [[4]]: 在label上显示拖放的图片
        //     QImage image(path); // QImage对I/O优化过, QPixmap对显示优化
        //     if (!image.isNull()) {
        //         image = image.scaled(pngNormalLabel->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
        //         pngNormalLabel->setPixmap(QPixmap::fromImage(image));
        //     }
        //     return true;
        // }

    } else if (obj == pngDisableLabel && event->type() == QEvent::MouseButtonDblClick) {
        if (mouseEvent->button() == Qt::LeftButton) {
            switchFileImage(pngDisableLabel, true);
        }
    } else if (obj == pngWarningLabel && event->type() == QEvent::MouseButtonDblClick) {
        if (mouseEvent->button() == Qt::LeftButton) {
            switchFileImage(pngWarningLabel, true);
        }
    } else if (obj == pngErrorLabel && event->type() == QEvent::MouseButtonDblClick) {
        if (mouseEvent->button() == Qt::LeftButton) {
            switchFileImage(pngErrorLabel, true);
        }
    } else if (obj == svgNormalLabel && event->type() == QEvent::MouseButtonDblClick) {
        if (mouseEvent->button() == Qt::LeftButton) {
            if (isElec) {
                switchFileImage(svgNormalLabel);
            } 
        }
    } else if (obj == svgDisableLabel && event->type() == QEvent::MouseButtonDblClick) {
        if (mouseEvent->button() == Qt::LeftButton) {
            if (isElec) {
                switchFileImage(svgDisableLabel);
            }
        }
    } else if (obj == svgWarningLabel && event->type() == QEvent::MouseButtonDblClick) {
        if (mouseEvent->button() == Qt::LeftButton) {
            if (isElec) {
                switchFileImage(svgWarningLabel);
            }
        }
    } else if (obj == svgErrorLabel && event->type() == QEvent::MouseButtonDblClick) {
        if (mouseEvent->button() == Qt::LeftButton) {
            if (isElec) {
                switchFileImage(svgErrorLabel);
            }
        }
    }
    return false;
}

void IamgeSourceWidget::dragEnterEvent(QDragEnterEvent *event)
{
    if (event->mimeData()->hasUrls()) {
        QList<QUrl> urls = event->mimeData()->urls();
        if (urls.first().toLocalFile().endsWith(".png")) {
            event->acceptProposedAction();
        }
    }
}

void IamgeSourceWidget::dropEvent(QDropEvent *event)
{
    // 获取该位置下的子控件对象
    if (event->isAccepted()) {
        if (childAt(event->pos()) == pngNormalLabel) {
            foreach (const QUrl &url, event->mimeData()->urls()) {
                QString fileName = url.toLocalFile();
                if (fileName.endsWith(".png")) {
                    QPixmap pixmap(fileName);
                    pngNormalLabel->setPixmap(pixmap);
                    event->acceptProposedAction();
                    break;
                }
            }
        }
    }
}

void IamgeSourceWidget::setLabelParam(QLabel *pLabel)
{
    pLabel->setAcceptDrops(true);
    pLabel->setToolTip(pLabel->text());
    pLabel->installEventFilter(this);
    pLabel->setFixedSize(LABLE_WIDTH, LABLE_HEIGHT);
    pLabel->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
    pLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    pLabel->setFrameStyle(QFrame::Panel | QFrame::Plain);
}

void IamgeSourceWidget::switchFileImage(QLabel *plabel, bool isPNG)
{
    QString static filePath;
    if (!isPNG) {
        filePath = QFileDialog::getOpenFileName(&QWidget(), plabel->text(), filePath, "SVG(*.svg)");
        if (!filePath.isEmpty()) {	
            QFile file(filePath);
            file.open(QFile::ReadOnly);
            QByteArray svgData = file.readAll();
            QSvgRenderer renderer(svgData);	//绘制SVG图片防止失真
            QPixmap pixmap(LABLE_WIDTH - 2, LABLE_HEIGHT - 2);
            pixmap.fill(Qt::transparent);
            QPainter painter(&pixmap);
            renderer.render(&painter);
            plabel->setPixmap(pixmap);
            plabel->show();
        }
    } else {
        filePath = QFileDialog::getOpenFileName(&QWidget(), plabel->text(), filePath, "PNG(*.png)");
        if (!filePath.isEmpty()) {
            QImage image;
            QFile file(filePath);
            file.open(QFile::ReadOnly);
            image.loadFromData(file.readAll());
            plabel->setPixmap(QPixmap::fromImage(image));
            plabel->show();
        }
    }
}

MyLable::MyLable(QString str, QWidget *parent)
    : QLabel(parent),
      m_scaleValue(1.0),
      m_mousePoint(0, 0),
      m_drawPoint(0, 0),
      m_rectPixmap(0, 0, 0, 0),
      m_isMousePress(0),
      SCALE_MAX_VALUE(10.0),
      SCALE_MIN_VALUE(0.5)
{
    strs = str;
}

void MyLable::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    QPen pen;
    pen.setWidth(1);
    pen.setColor(Qt::black);
    painter.setPen(pen);
    const QPixmap *pixmap = this->pixmap();
    painter.drawRect(1, 1, LABLE_WIDTH - 2, LABLE_HEIGHT - 2);
    if (!pixmap) {
        painter.drawText(LABLE_WIDTH / 4, LABLE_HEIGHT / 2, strs);
        return;
    }
    double width = this->width() * m_scaleValue;
    double height = this->height() * m_scaleValue;
    QPixmap scalePixmap =
            this->pixmap()->scaled(width, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); // 饱满缩放
    m_rectPixmap = QRect(m_drawPoint.x(), m_drawPoint.y(), width, height);                          // 图片区域
    painter.drawPixmap(m_rectPixmap, scalePixmap);
}

void MyLable::mouseMoveEvent(QMouseEvent *event)
{
    if (m_isMousePress) {
        int x = event->pos().x() - m_mousePoint.x();
        int y = event->pos().y() - m_mousePoint.y();
        m_mousePoint = event->pos();
        m_drawPoint = QPointF(m_drawPoint.x() + x, m_drawPoint.y() + y);
        update();
    }
}

void MyLable::mousePressEvent(QMouseEvent *event)
{
    if (event->type() == QEvent::MouseButtonDblClick) {
        if (event->button() == Qt::LeftButton) {
            return;
        }
    }
    if (event->button() == Qt::LeftButton) {
        m_isMousePress = true;
        m_mousePoint = event->pos();
    }
}

void MyLable::mouseReleaseEvent(QMouseEvent *event)
{
    if (event->button() == Qt::RightButton) {
        m_drawPoint = QPointF(0, 0);
        m_scaleValue = 1.0;
        update();
    }
    if (event->button() == Qt::LeftButton)
        m_isMousePress = false;
}

void MyLable::wheelEvent(QWheelEvent *event)
{
    changeWheelValue(event->pos(), event->delta());
    event->accept();
}

void MyLable::resizeEvent(QResizeEvent *event)
{
    m_drawPoint = QPointF(0, 0);
    m_scaleValue = 1.0;
    update();
}

void MyLable::changeWheelValue(QPoint event, int numSteps)
{
    double oldScale = m_scaleValue;
    if (numSteps > 0) {
        m_scaleValue *= 1.1;
    } else {
        m_scaleValue *= 0.9;
    }
    if (m_scaleValue > (SCALE_MAX_VALUE)) {
        m_scaleValue = SCALE_MAX_VALUE;
    }
    if (m_scaleValue < (SCALE_MIN_VALUE)) {
        m_scaleValue = SCALE_MIN_VALUE;
    }

    if (m_rectPixmap.contains(event)) {
        double x = m_drawPoint.x()
                - (event.x() - m_drawPoint.x()) / m_rectPixmap.width() * (this->width() * (m_scaleValue - oldScale));
        double y = m_drawPoint.y()
                - (event.y() - m_drawPoint.y()) / m_rectPixmap.height() * (this->height() * (m_scaleValue - oldScale));
        m_drawPoint = QPointF(x, y);
    } else {
        double x = m_drawPoint.x() - (this->width() * (m_scaleValue - oldScale)) / 2;
        double y = m_drawPoint.y() - (this->height() * (m_scaleValue - oldScale)) / 2;
        m_drawPoint = QPointF(x, y);
    }
    update();
}

bool MyLable::event(QEvent *e)
{
    if (e->type() == QEvent::ToolTip) {
        QToolTip::showText(mapToGlobal(QPoint(0, 0)), strs);
        return true;
    }
    return QLabel::event(e);
}



版权声明:本文为weixin_49065061原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。