大多数情况下,我们会采用label控件显示图像预览或者图像处理后的结果。有些时候,会将预览或者与预览相关的图像数据保存下来,以便对图像处理效果进行进一步分析和处理。保存预览的方法有很多,比如保存按钮、菜单、快捷键等。在此采用右键菜单的方式,进行预览保存。
简单的概括就是,为label控件添加鼠标响应,在点击/释放鼠标右键后,弹出菜单,通过点击菜单选项,保存预览。
- 将frameShape属性设置为box,可在预览四周显示一个黑色边框。在未导入图像时,可直观的确定预览显示范围。
- 勾选scaledContents属性,可将图像完整的显示在label控件内。
由于实例中使用右键菜单的方式保存预览,因此需要对label控件做一些处理,实现鼠标右键功能。故定义了一个myLabel类用于响应鼠标操作,其具体内容如下所示。
#ifndef _MYLABEL_H
#define _MYLABEL_H
#include <QLabel>
#include <QPoint>
class myLabel : public QLabel
{
Q_OBJECT
protected:
void mouseReleaseEvent(QMouseEvent *event);
public:
myLabel(QWidget *parent = Q_NULLPTR);
~myLabel();
private:
signals:
void signalReleaseMouseRightButton(QPoint point); // 释放鼠标右键信号
};
#endif
对于鼠标右键信号而言,点击右键或者释放右键均以发射信号。在此采用释放鼠标右键的方式发射鼠标释放信号,并记录鼠标的globalPos坐标,用于显示右键菜单。值得注意的是,globalPos坐标可将右键菜单显示在点击的位置。
void myLabel::mouseReleaseEvent(QMouseEvent *event)
{
if (event->button() == Qt::RightButton) // 释放右键
{
emit signalReleaseMouseRightButton(event->globalPos()); // 右键释放信号
}
QLabel::mouseReleaseEvent(event);
}
完成myLabel类的定义后,可在Designer中,将鼠标移动到label控件内,点击右键->提升窗口的部件,编辑好提升内容,便能将label控件提升为myLabel。注意:提升的类名称一定要和自定义的类名一致,否则会导致编译报错。
完成上述界面设计后,就正式进入导图显示,右键菜单保存的关键部分。通过QtLabelTest实现导图,右键菜单保存预览的功能,以下为QtLabelTest的实现方式。
/*
描述: QtLableTest.h
*/
#pragma once
#include <QtWidgets/QMainWindow>
#include "ui_QtLabelTest.h"
#include <QDir>
#include <QString>
#include <QFileDialog>
#include <opencv2/opencv.hpp>
using namespace cv;
class QtLabelTest : public QMainWindow
{
Q_OBJECT
public:
QtLabelTest(QWidget *parent = Q_NULLPTR);
private:
Ui::QtLabelTestClass ui;
private slots:
void Load_Image_clicked(); // 导图按钮响应
void slotReleaseMouseRightButton(QPoint point); // 鼠标右键释放响应
void slotSavePreview(); // 保存预览
};
/*
描述: QtLableTest.cpp
*/
#include "QtLabelTest.h"
QtLabelTest::QtLabelTest(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
// 连接鼠标右键信号及响应
QObject::connect(ui.label, SIGNAL(signalReleaseMouseRightButton(QPoint)),
this, SLOT(slotReleaseMouseRightButton(QPoint)));
}
void QtLabelTest::Load_Image_clicked()
{
// 导入图片
QString curPath = QDir::currentPath();
QString dlgTitle = "Pick Image";
QString filefilter = "jpg(*.jpg)";
QString imageName = QFileDialog::getOpenFileName(this, dlgTitle, curPath, filefilter);
if (imageName.isEmpty())
return;
// cv::Mat -> QPixmap
Mat img = imread(imageName.toStdString());
cvtColor(img, img, COLOR_BGR2RGB);
QImage qimg = QImage((const unsigned char*)(img.data),
img.cols, img.rows,
img.cols*img.channels(),
QImage::Format_RGB888);
QPixmap pix = QPixmap::fromImage(qimg);
// 显示图片
ui.label->setPixmap(pix);
}
void QtLabelTest::slotReleaseMouseRightButton(QPoint point)
{
// 创建菜单
QMenu *menu = new QMenu();
QAction *saveAction = new QAction("Save Current");
connect(saveAction, SIGNAL(triggered()), this, SLOT(slotSavePreview()));
menu->addAction(saveAction);
menu->exec(point); // 显示菜单
}
void QtLabelTest::slotSavePreview()
{
QPixmap p = ui.label->grab(ui.label->rect()); // 截取预览
QImage img = p.toImage();
img.save("save.png");
}
由于菜单是由一系列action组件组成。因此在释放鼠标右键的响应函数内,添加了菜单,并为菜单添加了action控件。通过连接action组件的triggered信号和保存预览的槽函数,完成保存预览的功能。当程序运行时,就可以右键弹出菜单,再点击菜单中的“Save Current”选项,即可完成保存预览的功能。关于预览保存,在此通过类似截屏的处理完成。
说明:
上述功能,采用VS2013+Qt5.8环境编译,且验证通过。使用者可根据各自的需求,修改相应的部分。
个人声明:
以上内容,纯属个人观点,不喜勿喷。未经本人同意,不得私自转载。博客中出现的代码仅供学习参考,不得有其他用途。若文中存在纰漏,或读者有更好的建议,欢迎留言探讨。也可邮箱联系:yxyx_0212@163.com