QT 学习笔记(十一)

简介: QT 学习笔记(十一)

文章目录

一、绘图设备

1. QPixmap

1.1 QPixmap 简介

1.2 QPixmap 演示

2. QBitmap

2.1 QBitmap 简介

2.2 QBitmap 演示见 QPixmap 和 QBitmap 的区别。

3. QImage

3.1 QImage 简介

3.2 QImage 演示

4. QPicture

4.1 QPicture 简介

4.2 QPicture 演示

二、QPixmap 和 QBitmap 的区别

1. widget.h

2. widget.cpp

3. 实现结果

三、QPixmap 与 QImage 的区别和相互转换

1. QImage 与 QPixmap 的区别

2. QImage 与 QPixmap 的相互转换

四、不规则窗口



由于每次代码都是在原有程序上修改,因此除了新建项目,不然一般会在学完后统一展示代码。

提示:具体项目创建流程和注意事项见QT 学习笔记(一)

提示:具体项目准备工作和细节讲解见QT 学习笔记(二)



一、绘图设备



绘图设备是指继承 QPainterDevice 的子类。 QT 一共提供了四个这样的类,分别是 QPixmap、QBitmap、QImage 和 QPicture。

QPixmap 专门为图像在屏幕上的显示做了优化,和平台相关,不能对图片进行修改。

QBitmap 是 QPixmap 的一个子类,它的色深限定为 1,可以使用 QPixmap 的 isQBitmap() 函数来确定这个 QPixmap 是不是一个 QBitmap。

QImage 专门为图像的像素级访问做了优化。,和平台无关,可以对图片进行修改, 在线程中绘图。

QPicture 可以记录和重现 QPainter 的各条命令,保存绘图的状态(二进制文件)。


1. QPixmap

  • 生成一个新的项目,具体步骤过程见提示。

1.1 QPixmap 简介


(1) QPixmap 继承了 QPaintDevice 。因此,可以使用 QPainter 直接在上面绘制图形。

(2) QPixmap 可以接受一个字符串作为一个文件的路径来显示这个文件,比如想在程序之中打开 png、jpeg 之类的文件,就可以使用 QPixmap。

(3) 使用 QPainter 的 drawPixmap() 函数可以把这个文件绘制到一个 QLabel、QPushButton 或者其他的设备上面。

(4) QPixmap 是针对屏幕进行特殊优化的。因此,它与实际的底层显示设备息息相关。注意,这里说的显示设备并不是硬件,而是操作系统提供的原生的绘图引擎。所以,在不同的操作系统平台下,QPixmap 的显示可能会有所差别。


1.2 QPixmap 演示

  • 我们现在指定绘图设备 QPixmap,不是窗口。因此,我们可以直接在构造函数里面编写代码。

e2120d3b327f4cb4908ccbb14a11745d.png


  • 运行后,在 QT 的运行结果上并没有现象。但是,在我们的文件当中,会生成一个 QPixmap.png 的图片文件。打开后,我们发现图片的背景颜色是黑色。
  • 在应用的时候,我们往往按照需求对背景色进行填充。在这里以背景色为白色举例。

b4f71dfc1efb4ef89ecce7b7f84d7952.png


  • 实现代码如下:
//绘图设备大小400*300
    QPixmap pixmap(400,300);
    QPainter p(&pixmap);
    //填充背景色
    //p.fillRect(0,0,400,300,QBrush(Qt::white));//画家填充
    pixmap.fill(Qt::white);//绘图设备填充
    p.drawPixmap(0,0,80,80,QPixmap("../tuoian/5.jpg"));
    //保存图片
    pixmap.save("../pixmap.png");



2. QBitmap

2.1 QBitmap 简介


(1) QBitmap 继承于 QPixmap,因此具有 QPixmap 的所有特性,提供单色图像。

(2) QBitmap 的色深始终为1,色深这个概念来自计算机图形学,是指用于表现颜色的二进制的位数。计算机里面的数据都是使用二进制表示的。为了表示一种颜色,我们也会使用二进制。比如我们要表示 8 种颜色,需要用 3 个二进制位,这时我们就说色深是 3。因此,所谓色深为 1,也就是使用 1 个二进制位表示颜色。1 个位只有两种状态:0 和 1,因此它所表示的颜色就有两种,黑和白。因此,QBitmap 实际上是只有黑白两色的图像数据。

(3) 由于 QBitmap 色深小,因此只占用很少的存储空间,所以适合做光标文件和笔刷。

2.2 QBitmap 演示见 QPixmap 和 QBitmap 的区别。

3. QImage

  • 生成一个新的项目,具体步骤过程见提示。

3.1 QImage 简介


(1) QImage 是使用独立于硬件的绘制系统,实际上是自己绘制自己,因此提供了像素级别的操作,并且能够在不同系统之上提供一个一致的显示形式。

(2) 我们声明了一个 QImage 对象,大小是 300 x 300,颜色模式是 RGB32,即使用 32 位数值表示一个颜色的 RGB 值,也就是说每种颜色使用 8 位。然后我们对每个像素进行颜色赋值,从而构成了这个图像。我们可以把 QImage 想象成一个 RGB 颜色的二维数组,记录了每一像素的颜色。


3.2 QImage 演示

  • 我们现在指定绘图设备 QImage ,不是窗口。因此,我们可以直接在构造函数里面编写代码


b4a56db594614fa899d6d124151d2e99.png

ARGB 应用背景是透明色,RGB 的背景是黑色。在这里我们选用 QImage::Format_ARGB32 背景是透明,现象如下图所示:

image.png


QImage 可以对像素点进行操作,现象如下图所示:

image.png


  • 实现代码如下:
    //创建一个绘图设备,QImage::Format_ARGB32 背景是透明
    QImage image(400,300,QImage::Format_ARGB32);
    QPainter p;
    p.begin(&image);
    //绘图
    p.drawImage(0,0,QImage("../tuoian/5.jpg"));
    //对绘图设备前50个像素点进行操作
    for(int i=0;i<50;i++)
    {
        for(int j=0;j<50;j++)
        {
            image.setPixel(QPoint(i, j), qRgb(0,255,0));
        }
    }
    p.end();
    //保存图片
    image.save("../image.png");



4. QPicture

  • 生成一个新的项目,具体步骤过程见提示。

4.1 QPicture 简介


(1) QPicture 是一个可以记录和重现 QPainter 命令的绘图设备。

(2) QPicture 将 QPainter 的命令序列化到一个 I/O 设备,保存为一个平台独立的文件格式。这种格式有时候会是“元文件(meta- files)”。QT 的这种格式是二进制的,不同于某些本地的元文件,QT 的 pictures 文件没有内容上的限制,只要是能够被 QPainter 绘制的元素,不论是字体还是 pixmap,或者是变换,都可以保存进一个 picture 中。

(3) QPicture 是平台无关的,因此它可以使用在多种设备之上,比如 svg、pdf、ps、打印机或者屏幕。这里所说的 QPaintDevice,实际上是说可以有 QPainter 绘制的对象。QPicture 使用系统的分辨率,并且可以调整 QPainter 来消除不同设备之间的显示差异。

(4) 如果要记录下 QPainter 的命令,首先要使用 QPainter::begin() 函数,将 QPicture 实例作为参数传递进去,以便告诉系统开始记录,记录完毕后使用 QPainter::end() 命令终止。


4.2 QPicture 演示


  • 我们现在指定绘图设备 QPicture ,不是窗口。因此,我们可以直接在构造函数里面编写代码。
  • QPicture 文件生成的图片是二进制文件,在文件路径下图片是无法打开的,实现代码和现象如下图所示:
    QPicture picture;
    QPainter p;
    p.begin(&picture);
    //绘图
    p.drawPixmap(0,0,80,80,QPixmap("../tuoian/5.jpg"));
    p.drawLine(50,50,150,50);
    p.end();
    //保存的是二进制文件
    picture.save("../picture.png");



b87b06e616e6400d8248cf86515f3ad9.png

如果我们想观察到生成的图片,需要在头文件 widget.h 当中的 protected 下进行 paintEvent 的声明,在源文件 widget.cpp 下进行实现,实现代码和现象如下图所示:

void Widget::paintEvent(QPaintEvent *)
{
    QPicture pic;
    pic.load("../picture.png");
    QPainter p(this);
    p.drawPicture(0,0,pic);
}

3c380eef94304be692a9513b87be6d43.png


二、QPixmap 和 QBitmap 的区别

  • 生成一个新的项目,具体步骤过程见提示。
  • QPixmap 主要是画彩色;QBitmap 只有黑白两种颜色。
  • 下面进行同一个图像文件在 QPixmap 和 QBitmap 下的不同表现,以便于我们可以更直观的观察到区别。



1. widget.h

#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
    Q_OBJECT
public:
    explicit Widget(QWidget *parent = nullptr);
    ~Widget();
protected:
    //重写绘图事件
    //如果给窗口绘图,一定要在paintEvent()中实现
    void paintEvent(QPaintEvent *);
private:
    Ui::Widget *ui;
};
#endif // WIDGET_H



2. widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include <QPainter>
#include <QBitmap>
Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
}
Widget::~Widget()
{
    delete ui;
}
void Widget::paintEvent(QPaintEvent *)
{
    QPainter p(this);
    //QPixmap 图片背景透明
    p.drawPixmap(0,0,QPixmap("../Image/butterfly.png"));
    //QBitmap 图片背景透明
    p.drawPixmap(200,0,QBitmap("../Image/butterfly.png"));
    //QPixmap 图片背景白色
    QPixmap pixmap;
    pixmap.load("../Image/butterfly1.png");
    p.drawPixmap(0,200,pixmap);
    //QBitmap 图片背景白色
    QBitmap bitmap;
    bitmap.load("../Image/butterfly1.png");
    p.drawPixmap(200,200,bitmap);
}


3. 实现结果


eb0cf93b133948ac91138197d1ab9259.png


这里我们采用两张 png 图片。butterfly1.png 是没有透明色的纯白背景,而 butterfly.png 是具有透明色的背景。我们分别使用 QPixmap 和 QBitmap 来加载它们。

可以很明显知道它们的区别:白色的背景在 QBitmap 中消失了,而透明色在 QBitmap 中转换成了黑色;其他颜色则是使用点的疏密程度来体现的。


三、QPixmap 与 QImage 的区别和相互转换

1. QImage 与 QPixmap 的区别


1) QPixmap 主要是用于绘图,针对屏幕显示而最佳化设计;QImage 主要是为图像 I/O、图片访问和像素修改而设计的。

(2) QPixmap 依赖于所在的平台的绘图引擎,故例如反锯齿等一些效果在不同的平台上可能会有不同的显示效果;QImage 使用 QT 自身的绘图引擎,可在不同平台上具有相同的显示效果。

(3) QImage 是独立于硬件的,也是一种 QPaintDevice,因此我们可以在另一个线程中对其进行绘制,而不需要在 GUI 线程中处理,使用这一方式可以很大幅度提高 UI 响应速度。

(4) QImage 可通过 setPixpel() 和 pixel() 等方法直接存取指定的像素。


2. QImage 与 QPixmap 的相互转换

  • (1) QImage 转换为 QPixmap
  • 使用 QPixmap 的静态成员函数 fromImage()。
QPixmap tempPixmap = QPixmap::fromImage(image);


  • (2) QPixmap 转换为 QImage :
  • 使用 QPixmap 类的成员函数 toImage()。
QImage tempImage = pixmap.toImage();



四、不规则窗口

  • 生成一个新的项目,具体步骤过程见提示。


  • 常见的窗体是各种方形的对话框,但有时候也需要非方形的窗体,如圆形,椭圆甚至是不规则形状的对话框。
  • 不规则窗口的实现步骤:



(1) 新建一个项目,比如项目名称叫做 ShapeWidget,给此项目添加一个类 ShapeWidget,基类选择 QWidget。

(2) 为了使该不规则窗体可以通过鼠标随意拖拽,在类中重定义鼠标事件:mousePressEvent()、mouseMoveEvent()、以及绘制函数 paintEvent()。

(3) ShapeWidget 的构造函数部分是实现该不规则窗体的关键,具体代码如下:

 

    //新建一个Pixmap对象
    QPixmap pixmap;
    //加载图片
    pixmap.load("../tuoian/7.jpg");
   //固定窗口大小,将窗口大小设置为图片大小
    setFixedSize( pixmap.width(), pixmap.height() );
    //给窗口去掉边框,设置窗口的flags
    setWindowFlags(Qt::FramelessWindowHint | windowFlags() );
    //设置透明背景
    setAttribute(Qt::WA_TranslucentBackground);


  • 4) 重新实现鼠标事件和绘制函数,具体代码如下:
void ShareWidget::mousePressEvent(QMouseEvent *ev)
{
    if(ev->button() == Qt::LeftButton)
    {
        //求坐标插值
        //当前点击坐标-窗口左上角坐标
        m_dragPoint = ev->globalPos()-frameGeometry().topLeft();
    }
    else if(ev->button() == Qt::RightButton)
    {
        // 鼠标右键关闭窗口
        close();
    }
}
void ShareWidget::mouseMoveEvent(QMouseEvent *ev)
{
    if(ev->buttons() & Qt::LeftButton)
    {
        // 如果是鼠标左键拖动, 移动窗口
        move(ev->globalPos() - m_dragPoint);
    }
}
void ShareWidget::paintEvent(QPaintEvent *ev)
{
    Q_UNUSED(ev)
    QPainter painter(this);
    // 重新绘制图片
    painter.drawPixmap(0, 0, QPixmap(":/ButterFly"));
}












相关文章
|
6月前
【Qt 学习笔记】Qt窗口 | 标准对话框 | 消息对话框QMessageBox
【Qt 学习笔记】Qt窗口 | 标准对话框 | 消息对话框QMessageBox
1059 4
【Qt 学习笔记】Qt窗口 | 标准对话框 | 消息对话框QMessageBox
|
6月前
|
开发者
【Qt 学习笔记】Qt系统相关 | Qt事件 | 事件的介绍及基本概念
【Qt 学习笔记】Qt系统相关 | Qt事件 | 事件的介绍及基本概念
274 4
|
6月前
【Qt 学习笔记】Qt窗口 | 标准对话框 | 文件对话框QFileDialog
【Qt 学习笔记】Qt窗口 | 标准对话框 | 文件对话框QFileDialog
1088 4
|
6月前
|
数据安全/隐私保护
【Qt 学习笔记】Qt窗口 | 对话框 | 模态与非模态对话框的创建
【Qt 学习笔记】Qt窗口 | 对话框 | 模态与非模态对话框的创建
540 4
|
6月前
|
搜索推荐 C++
【Qt 学习笔记】Qt窗口 | 对话框 | 创建自定义对话框
【Qt 学习笔记】Qt窗口 | 对话框 | 创建自定义对话框
277 4
|
6月前
|
API UED
【Qt 学习笔记】Qt窗口 | 状态栏 | QStatusBar的使用及说明
【Qt 学习笔记】Qt窗口 | 状态栏 | QStatusBar的使用及说明
740 4
|
6月前
【Qt 学习笔记】Qt窗口 | 标准对话框 | 输入对话框QInputDialog
【Qt 学习笔记】Qt窗口 | 标准对话框 | 输入对话框QInputDialog
445 3
|
6月前
|
数据可视化
【Qt 学习笔记】Qt窗口 | 标准对话框 | 字体对话框QFontDialog
【Qt 学习笔记】Qt窗口 | 标准对话框 | 字体对话框QFontDialog
163 3
|
6月前
【Qt 学习笔记】Qt窗口 | 标准对话框 | 颜色对话框QColorDialog
【Qt 学习笔记】Qt窗口 | 标准对话框 | 颜色对话框QColorDialog
849 3
|
6月前
【Qt 学习笔记】Qt窗口 | 对话框 | Qt对话框的分类及介绍
【Qt 学习笔记】Qt窗口 | 对话框 | Qt对话框的分类及介绍
209 3