Qt常用类(10)Qchart绘制灰度直方图、Qt实现屏幕截图

在这里插入图片描述

1.Qt实现屏幕截图

1.1实现步骤

1.搭建界面,包含延时选项,新建截图(按钮),保存截图(按钮),退出(按钮) label显示图片。
在这里插入图片描述
2.单击新建截图,若未选择延时,则提示“beng”的声音;选择延时,则在延时spinbox数值后获取截图,并显示在界面上,随界面大小改变。
3.将获取的截图复制到系统剪切板上。
4.单击保存截图,若未获取截图提示模态对话框;若已获取则跳转到“我的图片”位置保存图片,默认png格式。

1.2效果

在这里插入图片描述

1.3代码分析

main文件

#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();
    return a.exec();
}

.h文件

#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QPixmap>
#include <QClipboard>
#include <QDesktopWidget>
#include <QTimer>
#include <QFileDialog>
#include <QDesktopServices>
#include <QClipboard>
#include <QMessageBox>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
    Q_OBJECT
public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
private slots:
    void on_quitBtn_clicked();
    void on_shotBtn_clicked();
    void on_saveBtn_clicked();
protected:
    void resizeEvent(QResizeEvent *event);
private:
    Ui::Widget *ui;
    QTimer *myTimer;
    QPixmap pix;
};
#endif // WIDGET_H

.cpp文件

#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
}
Widget::~Widget()
{
    delete ui;
}
void Widget::on_quitBtn_clicked()
{
    this->close();
}
void Widget::on_shotBtn_clicked()
{
    if(ui->isDelayed->isChecked()){
        //获取当前屏幕
        this->myTimer = new QTimer;
        this->myTimer->start(ui->spinBox->text().toInt()*1000);
        this->hide(); //隐藏
        connect(myTimer,&QTimer::timeout,[=](){
            //获取截图  grabWindow其他参数可获取自定义大小,这里默认全屏
            pix = QPixmap::grabWindow(QApplication::desktop()->winId());//要添加<QDesktopWidget>头文件
            ui->imgLabel->setPixmap(pix.scaled(ui->imgLabel->size()));
            //将截图放入剪切板
            QClipboard *myBoard = QApplication::clipboard();
            myBoard->setPixmap(pix);
            //关闭定时器
            myTimer->stop();
            //显示软件
            this->show();
        });
    }
    else{
        qApp->beep();//调用系统提示音 beng的声音
    }
}
void Widget::on_saveBtn_clicked()
{
    if(pix.isNull()){
        QMessageBox::information(this,"Info","请先获取截图");
        return;
    }
    QString filename = QFileDialog::getSaveFileName(this,"Save File",
                                                    QStandardPaths::writableLocation(QStandardPaths::PicturesLocation),
                                                    tr("Images (*.png *.xpm *.jpg)"));
    pix.save(filename);
}
void Widget::resizeEvent(QResizeEvent *event)
{
    //窗体大小改变时,动态改变QLabel中pix的大小
    ui->imgLabel->setPixmap(pix.scaled(ui->imgLabel->size()));
}

分析
1.使用qApp->beep()发出beng的声音
2.QPixmap::grabWindow(QApplication::desktop()->winId());//要添加头文件 获取截图
*3.QClipboard myBoard = QApplication::clipboard();
myBoard->setPixmap(pix);//将截图放入剪切板
4.QStandardPaths::writableLocation(QStandardPaths::PicturesLocation)//获取系统目录->我的图片

2.QChart绘制灰度直方图

一个小场景是,点击按钮将显示一张图片,灰度直方图将立即更新该图片的灰度统计结果。主要借助此场景说明直方图的创建步骤。实际应用中,可以在采集图片流时适时发出更新灰度统计信号,即可实时显示当前画面的统计信息,用于指示调节曝光时间。

2.1实现步骤

1.qt的组件中安装qt chart模块

在这里插入图片描述

2.Qt ,pro文件中添加chart模块

QT += core gui charts

3.添加模块相关的头文件

#include <QChart>
#include <QChartView>
#include <QtCharts/QChart>
#include <QtCharts/QBarSeries>
#include <QtCharts/QBarSet>
#include <QtCharts/QCategoryAxis>
#include <QtCharts/QValueAxis>

4.初始化画图程序

在界面初始化的时候,画一个直方图的框架,留下数据更新接口,程序运行时,通过信号槽的方式,在槽函数中添加更新直方图数据的代码。现介绍初始化部分。可以将QChart类比为一个画布,它提供了绘制图表所需的各种属性和方法。可以在QChart对象上添加不同类型的图表元素,如曲线、柱状图、饼图等。QChart负责管理和绘制这些图表元素,并提供一些功能,如坐标轴、图例、背景等。而QChartView类则可以看作是一个显示器,它将QChart对象的内容显示在窗口中。QChartView提供了一个图表视图,可以在其中显示QChart对象,并支持用户交互操作,例如缩放、平移、选择等。QChartView还可以设置一些显示属性,如背景颜色、边框样式等。可以将QChart理解为图表的数据和样式的容器,而QChartView则是将这些数据和样式以图形的形式展示出来的视图。通过将QChart对象与QChartView对象结合使用,我们可以在窗口中创建、显示和操作各种类型的图表。QBarSeries包含多个QBarSet对象,每个QBarSet对象代表一个柱子的数据集。QCategoryAxis用于在水平方向上显示类别,例如产品名称。QValueAxis用于在垂直方向上显示值,例如销售量。代码如下:

void MainWindow::initHistogram()
{
    grayChart= new QChart();//创建视图
    grayChart->setTitle("Histogram");
    QChartView* graphicsView = new QChartView(grayChart,ui->widget);//创建表格与视图绑定
    graphicsView->setRenderHint(QPainter::Antialiasing);//抗锯齿
    QVBoxLayout* layout_bottom_ = new QVBoxLayout(ui->widget);
    layout_bottom_->setMargin(0);
    layout_bottom_->setSpacing(0);
    layout_bottom_->addWidget(graphicsView);
    QBarSet * set = new QBarSet("灰度值",this);//柱子
    set->setBrush(QBrush(Qt::gray));
    set->setPen(QPen(Qt::gray));
    //包含关系是:Qchart(QChartView显示)>>QBarSeries>>QBarSet
    series = new QBarSeries(grayChart);//柱子族中只有一根柱子(一种柱子)
    series->append(set);
    series->setBarWidth(1);// 设置柱子宽度
    grayChart->addSeries(series);// 向直方图中添加数据系列
    grayChart->legend()->setVisible(false); // 显示图例
    // 初始化坐标轴画笔和标签字体
    QPen pen(Qt::black);
    pen.setWidth(2);
    QFont font;
    font.setBold(true);
    font.setPointSize(9);
    // 设置横坐标
    m_axisX = new QCategoryAxis();//水平方向上显示柱子族
    m_axisX->setRange(0, 255);
    // 设置x轴刻度标签
    for (int i = 0; i <= 255; i+=20) {
        m_axisX->append(QString::number(i), i);
    }
     m_axisX->append("0",0);
    m_axisX->append("255",255);
    m_axisX->setGridLineVisible(false);
    m_axisX->setLabelsPosition(QCategoryAxis::AxisLabelsPositionOnValue);
    grayChart->addAxis(m_axisX, Qt::AlignBottom);// 添加坐标轴
    series->attachAxis(m_axisX);// 将坐标轴与数据系列绑定
    m_axisX->setLinePen(pen);// 设置坐标轴及其网格线
    m_axisX->setGridLinePen(pen);
    m_axisX->setLabelsFont(font);

    // 设置纵坐标
    m_axisY = new QValueAxis();//水平方向上显示柱子族的对应数值
    m_axisY->setLabelFormat("%d");// 设置坐标轴刻度
    m_axisY->setTickCount(2);// 设置纵向刻度数目
    m_axisY->setGridLineVisible(false);
    grayChart->addAxis(m_axisY, Qt::AlignLeft); // 添加坐标轴
    series->attachAxis(m_axisY);// 将坐标轴与数据系列绑定
    m_axisY->setLinePen(pen); // 设置坐标轴及其网格线

    m_axisY->setGridLinePen(pen);
    m_axisY->setLabelsFont(font);
    grayChart->setBackgroundBrush(QColor(255, 255, 255));
    grayChart->setMargins(QMargins(0, 0, 0, 0)); // 设置边距,以增加边框的宽度
}

5.响应程序

在框架搭好的基础上,写一个槽函数用于更新直方图数据。需要注意,更新数据的时候需要从series中把原来的柱子clear掉,在添加新的柱子,如果试图清楚柱子的内容在更新柱子会出错。下面的程序是接收来自相应信号的QImage对象,然后通过遍历像素统计灰度分布,最后添加柱子对象barset更新直方图。

void MainWindow::doProcessUpdateHistogram(const QImage &img)
{
    series->clear();
    QBarSet *barSet = new QBarSet("灰度值",this);
    QVector<int> newData(256, 0);
    barSet->setBrush(QBrush(Qt::gray));
    barSet->setPen(QPen(Qt::gray));
    series->append(barSet);
    QImage image = img.convertToFormat(QImage::Format_Grayscale8);
    // 遍历每个像素 统计其灰度值
    uchar * imgData = image.bits();
    for (int x = 0; x < image.height()*image.width(); x++) {
            newData[imgData[x]] = newData[imgData[x]]+1;
    }
    int y_range = 0;
    for (int i = 0; i < 256; ++i) {
         barSet->append(static_cast<qreal>(newData[i]));
         if(newData[i] > y_range){
             y_range = newData[i] ;
         }
    }
    m_axisX->setRange(0, 255);
    m_axisY->setRange(0, y_range);//设置纵坐标范围
    grayChart->update();
}

2.2效果

在这里插入图片描述

3.传送门

END

🎏文章原创,首发于CSDN论坛。
🎏欢迎点赞❤❤收藏⭐⭐打赏💴💴!
🎏欢迎评论区或私信指出错误❌,提出宝贵意见或疑问❓。


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FPGA小油条

原创不易,请多支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值