谷多网站,灰色网站欣赏,注册有限公司需要多少钱,网站核验单 没有网站 怎么办目录
前言
消息事件机制 (Event System)
绘图 (Graphics Drawing)
绘图设备
Qt 提供的主要绘图设备
Qt 主要绘图设备的特点
各个绘图设备的详细介绍
文件处理 (File Handling)
总结 前言
QT 是一个非常强大的图形用户界面#xff08;GUI#xff09;开发框架 Drawing)
绘图设备
Qt 提供的主要绘图设备
Qt 主要绘图设备的特点
各个绘图设备的详细介绍
文件处理 (File Handling)
总结 前言
QT 是一个非常强大的图形用户界面GUI开发框架它的消息事件机制、绘图功能以及文件处理能力都是其重要组成部分。下面是关于这些部分的一些概述。 消息事件机制 (Event System)
Qt 采用 事件驱动 的机制即 应用程序的运行是由事件触发的。所有用户交互如鼠标、键盘或系统行为如窗口重绘、计时器触发都以 事件Event 的形式传递到 Qt 应用程序。
工作原理
Qt 通过 事件队列Event Queue 和 事件循环Event Loop 来处理事件
用户或系统产生事件如鼠标点击。事件被添加到 Qt 的事件队列QApplication::exec() 进入事件循环。Qt 事件分发机制 将事件发送给对应的 QObject 处理如 mousePressEvent()、keyPressEvent()。组件根据事件执行相应的逻辑。
QT 使用事件驱动的方式来管理应用程序的操作。每个 UI 元素如按钮、窗口、文本框等都会生成事件这些事件会被送到事件队列中并由应用程序的事件循环Event Loop逐一处理。基本上QT 的事件机制涉及以下几个方面
事件循环QT 应用程序的主线程通常会有一个事件循环负责处理来自用户的输入事件如鼠标点击、键盘输入等以及其他系统事件如定时器触发。事件处理UI 元素的类如 QWidget、QPushButton可以重写事件处理函数如 mouseEvent、keyEvent从而对不同类型的事件作出响应。事件传播事件可以通过父子组件链传播。例如点击事件先在子组件中处理如果没有处理才会传递到父组件。自定义事件你可以通过继承 QEvent 类和 QCoreApplication::postEvent 函数来创建并发送自定义事件。
常见的事件类型
在Qt中QWidget类定义了很多事件处理函数这些函数都是protected virtual的意味着我们可以在子类中重写它们来响应特定的事件。常见的事件包括
keyPressEvent()键盘按键按下事件。keyReleaseEvent()键盘按键松开事件。mouseDoubleClickEvent()鼠标双击事件。mouseMoveEvent()鼠标移动事件。mousePressEvent()鼠标按键按下事件。mouseReleaseEvent()鼠标按键松开事件。
事件处理的例子
下面是一个基于QLabel的事件处理示例它演示了如何响应鼠标事件鼠标按下、鼠标移动、鼠标释放 打开 Qt Creator。选择 File - New File or Project然后选择 Application - Qt Widgets Application。输入项目名称例如 MouseEventDemo并选择保存路径。点击 Next然后 Finish。右键点击项目名选择 Add New然后选择 C Class并命名为 EventLabel。将上述的头文件 (EventLabel.h) 和实现文件 (EventLabel.cpp) 复制到 EventLabel.h 和 EventLabel.cpp 中。在 main.cpp 中包含 EventLabel.h 并按照上述代码实现主程序。最后点击 Run 或者 ctrlR 来运行应用程序。 main.cpp
#include QApplication
#include mainwindow.hint main(int argc, char *argv[])
{QApplication app(argc, argv);// 创建自定义标签EventLabel *label new EventLabel;label-setWindowTitle(MouseEvent Demo);label-resize(300, 200);label-show();return app.exec();
}mainwindow.h
#ifndef EVENTLABEL_H
#define EVENTLABEL_H#include QLabel
#include QMouseEventclass EventLabel : public QLabel
{Q_OBJECTpublic:// 构造函数explicit EventLabel(QWidget *parent nullptr);protected:// 重写事件处理函数void mousePressEvent(QMouseEvent *event) override;void mouseMoveEvent(QMouseEvent *event) override;void mouseReleaseEvent(QMouseEvent *event) override;
};#endif // EVENTLABEL_Hmainwindow.cpp
#include mainwindow.h
#include QString// 构造函数
EventLabel::EventLabel(QWidget *parent) : QLabel(parent)
{setAlignment(Qt::AlignCenter); // 设置文本居中setText(h1Move the mouse here/h1); // 初始文本
}// 处理鼠标按下事件
void EventLabel::mousePressEvent(QMouseEvent *event)
{setText(QString(h1Press: (%1, %2)/h1).arg(event-x()).arg(event-y()));
}// 处理鼠标移动事件
void EventLabel::mouseMoveEvent(QMouseEvent *event)
{setText(QString(h1Move: (%1, %2)/h1).arg(event-x()).arg(event-y()));
}// 处理鼠标释放事件
void EventLabel::mouseReleaseEvent(QMouseEvent *event)
{setText(QString(h1Release: (%1, %2)/h1).arg(event-x()).arg(event-y()));
}运行效果
在 Qt Creator 中创建并运行这个项目后你会看到一个窗口显示有一个标签。当你点击鼠标、移动鼠标或者释放鼠标时标签上的文本会相应地更新显示鼠标的当前坐标。 这样你就能够在 Qt Creator 中创建并运行一个带有事件处理的简单应用程序了
mouseMoveEvent() 默认情况下只会在按下鼠标后触发因为 QWidget 的 mouseTracking 属性默认是 false。如果你希望鼠标在移动时无需点击就触发 mouseMoveEvent()可以在 EventLabel 的构造函数中启用鼠标追踪功能
修改 mainwindow.cpp 使鼠标追踪生效
// 构造函数
EventLabel::EventLabel(QWidget *parent) : QLabel(parent)
{setAlignment(Qt::AlignCenter); // 设置文本居中setText(h1Move the mouse here/h1); // 初始文本setMouseTracking(true); // 启用鼠标追踪
}解释
默认情况下 (mouseTracking false) 只有当鼠标按下并拖动时mouseMoveEvent() 才会被触发。 启用 mouseTracking true 只要鼠标移动到 QWidget 上就会触发 mouseMoveEvent()即使没有点击鼠标。
消息事件机制和信号和槽机制的关系
信号和槽机制异步回调
Qt 的 信号和槽Signal Slot 机制是一种 高级的消息通信机制用于对象之间解耦的事件处理。它是一种 基于发布-订阅模式的回调机制允许不同对象之间进行交互而不需要显式调用对方的方法。
工作原理
信号Signal对象 A 发送一个信号例如按钮被点击 clicked()。槽Slot对象 B 连接了 A 的信号并定义了相应的槽函数例如 onButtonClicked()。Qt 内部管理信号-槽连接当信号被触发时Qt 事件系统会自动调用对应的槽函数。
特性消息事件机制Event信号和槽机制Signal Slot触发方式事件循环调度直接调用传输机制事件队列直接/异步调用是否跨线程不能可以是否解耦否需要重写是对象不直接依赖适用场景低级事件鼠标、键盘、窗口重绘高级对象交互按钮点击、线程通信
事件机制 适用于 GUI 组件鼠标、键盘、窗口重绘需要重写 QEvent 处理函数。信号-槽机制 适用于对象间的通信更高级更解耦可以跨线程。二者可以结合使用在事件触发后发射信号供其他组件监听。 应用建议
简单交互鼠标、键盘 → 事件处理 mousePressEvent()按钮点击、跨对象交互 → connect(signal, slot)复杂任务、跨线程 → 信号-槽机制 绘图 (Graphics Drawing)
Qt 的绘图系统允许开发者使用相同的 API 在屏幕、打印设备等不同目标上绘制图形。其核心组成部分包括
QPainter画笔执行绘制操作。QPaintDevice绘图设备提供绘制的空间例如窗口、图片、打印机等。QPaintEngine绘图引擎连接 QPainter 和 QPaintDevice提供底层绘图支持通常无需手动使用。
QPainter绘图核心
QPainter 是 Qt 的 绘图核心类它提供了一组 API 用于 绘制线条、文本、图片、形状等。
基本用法
要在 QWidget 组件上绘制需要重写 paintEvent() 事件并在其中使用 QPainter
#include QApplication
#include QWidget
#include QPainterclass MyWidget : public QWidget {
protected:void paintEvent(QPaintEvent *) override {QPainter painter(this); // 绑定当前窗口painter.setPen(Qt::blue);painter.setFont(QFont(Arial, 20));painter.drawText(50, 50, Hello Qt!);painter.drawRect(20, 70, 100, 50); // 绘制矩形painter.drawEllipse(150, 70, 50, 50); // 绘制圆}
};int main(int argc, char *argv[]) {QApplication app(argc, argv);MyWidget w;w.resize(300, 200);w.show();return app.exec();
}要点
QPainter 需要绑定 this当前窗口。setPen() 设置画笔颜色setFont() 设置字体。使用 drawText()、drawRect()、drawEllipse() 等方法绘制不同图形。
QPaintDevice绘图目标
Qt 提供了多个 QPaintDeviceQPainter 需要在这些设备上绘制
QPaintDevice 子类描述QWidget用于窗口、按钮等组件QPixmap用于绘制离屏位图更高效QImage用于像素级操作如滤镜、图像处理QPicture用于存储绘图命令可回放QPrinter用于打印支持
在 QPixmap 上绘制
QPixmap pixmap(300, 200);
pixmap.fill(Qt::white);
QPainter painter(pixmap);
painter.setPen(Qt::red);
painter.drawLine(10, 10, 100, 100);
pixmap.save(output.png); // 保存为图片适用场景
QPixmap 适合 高效绘制用于 界面。QImage 适合 逐像素操作用于 图像处理。
QPaintEngine绘图引擎
QPaintEngine 负责将 QPainter 的绘图指令翻译成底层的 平台绘图调用如 OpenGL、Raster、Direct2D。 你通常不需要直接使用 QPaintEngine除非你要 自定义绘图设备。
绘图事件与交互
QPainter 主要在 paintEvent() 事件中使用而绘图交互通常涉及
鼠标事件mousePressEvent、mouseMoveEvent定时器事件QTimer 实现动画自定义控件绘制QCustomPlot 等
示例鼠标拖动绘制线条 打开 Qt Creator。选择 New Project然后选择 Qt Widgets Application。设置项目名称和路径点击 Next然后选择合适的构建套件。点击 Finish 完成创建。 mainwindow.h
#ifndef DRAWWIDGET_H
#define DRAWWIDGET_H#include QWidget
#include QPoint
#include QVectorclass DrawWidget : public QWidget
{Q_OBJECTpublic:explicit DrawWidget(QWidget *parent nullptr);~DrawWidget();protected:void paintEvent(QPaintEvent *event) override; // 重写绘图事件void mousePressEvent(QMouseEvent *event) override; // 鼠标按下事件void mouseMoveEvent(QMouseEvent *event) override; // 鼠标移动事件void mouseReleaseEvent(QMouseEvent *event) override; // 鼠标释放事件private:QVectorQPoint points; // 用来存储鼠标点击的点bool isDrawing false; // 标记是否正在绘制
};#endif // DRAWWIDGET_Hmainwindow.cpp
#include mainwindow.h
#include QPainter
#include QMouseEventDrawWidget::DrawWidget(QWidget *parent): QWidget(parent)
{setWindowTitle(Draw with Mouse);setFixedSize(400, 300); // 设置窗口大小
}DrawWidget::~DrawWidget()
{
}void DrawWidget::paintEvent(QPaintEvent *event)
{QPainter painter(this);painter.setPen(Qt::black); // 设置画笔颜色为黑色// 绘制已存储的所有点for (int i 1; i points.size(); i) {painter.drawLine(points[i - 1], points[i]); // 绘制线条}
}void DrawWidget::mousePressEvent(QMouseEvent *event)
{// 当鼠标按下时开始绘制isDrawing true;points.clear(); // 清除之前的点points.append(event-pos()); // 记录鼠标按下的位置update(); // 更新窗口触发重绘
}void DrawWidget::mouseMoveEvent(QMouseEvent *event)
{if (isDrawing) {points.append(event-pos()); // 记录鼠标拖动时的位置update(); // 更新窗口触发重绘}
}void DrawWidget::mouseReleaseEvent(QMouseEvent *event)
{if (isDrawing) {points.append(event-pos()); // 记录鼠标释放的位置isDrawing false; // 结束绘制update(); // 更新窗口触发重绘}
}主文件main.cpp
#include QApplication
#include mainwindow.hint main(int argc, char *argv[])
{QApplication a(argc, argv);// 创建窗口并显示DrawWidget w;w.show();return a.exec();
}运行项目
在 Qt Creator 中构建并运行项目。鼠标点击并拖动窗口你将看到鼠标拖动的路径逐渐绘制出来。 mousePressEvent当鼠标按下时记录当前位置并清空之前的点开始绘制。mouseMoveEvent鼠标拖动时不断记录新的点并更新绘制区域。mouseReleaseEvent鼠标释放时结束当前绘制过程并记录最后一个点。
在窗口中实现动态绘制线条的效果
mainwindow.h
#ifndef DRAWWIDGET_H
#define DRAWWIDGET_H#include QWidget
#include QVector
#include QPointclass DrawWidget : public QWidget
{Q_OBJECTpublic:explicit DrawWidget(QWidget *parent nullptr);~DrawWidget();protected:void paintEvent(QPaintEvent *event) override; // 绘图事件void mousePressEvent(QMouseEvent *event) override; // 鼠标按下事件void mouseMoveEvent(QMouseEvent *event) override; // 鼠标移动事件void mouseReleaseEvent(QMouseEvent *event) override; // 鼠标释放事件private:QVectorQVectorQPoint lines; // 存储所有绘制的线条QVectorQPoint currentLine; // 当前绘制的线条
};#endif // DRAWWIDGET_Hmainwindow.cpp
#include mainwindow.h
#include QPainter
#include QMouseEventDrawWidget::DrawWidget(QWidget *parent): QWidget(parent)
{setWindowTitle(动态鼠标绘制);setFixedSize(600, 400); // 设置窗口大小
}DrawWidget::~DrawWidget()
{
}void DrawWidget::paintEvent(QPaintEvent *event)
{QPainter painter(this);painter.setPen(QPen(Qt::black, 2)); // 设置黑色画笔线宽 2// 绘制所有历史线条for (const auto line : lines) {for (int i 1; i line.size(); i) {painter.drawLine(line[i - 1], line[i]);}}// 绘制当前线条for (int i 1; i currentLine.size(); i) {painter.drawLine(currentLine[i - 1], currentLine[i]);}
}void DrawWidget::mousePressEvent(QMouseEvent *event)
{if (event-button() Qt::LeftButton) {currentLine.clear(); // 清空当前线条currentLine.append(event-pos()); // 记录鼠标按下的点update(); // 触发重绘}
}void DrawWidget::mouseMoveEvent(QMouseEvent *event)
{if (!currentLine.isEmpty()) {currentLine.append(event-pos()); // 记录鼠标移动轨迹update(); // 触发重绘实现动态绘制}
}void DrawWidget::mouseReleaseEvent(QMouseEvent *event)
{if (event-button() Qt::LeftButton !currentLine.isEmpty()) {lines.append(currentLine); // 将当前线条加入历史线条currentLine.clear();update(); // 触发重绘}
}main.cpp
#include QApplication
#include mainwindow.hint main(int argc, char *argv[])
{QApplication a(argc, argv);DrawWidget w;w.show();return a.exec();
}✅ 实时绘制鼠标移动时线条立即更新无需等待鼠标释放。 ✅ 多段绘制支持多次绘制每次释放鼠标都会存入历史线条。 ✅ 动态更新每次 mouseMoveEvent() 都会触发 update()保证实时绘制效果。
小结
QPainter 是 Qt 的核心绘图 API必须在 paintEvent() 或 QPaintDevice 绑定后使用。QPaintDevice 提供绘图目标如 窗口QWidget、位图QPixmap、图片QImage。QPaintEngine 负责底层绘图通常无需直接操作。事件机制如 mouseMoveEvent()可用于绘图交互。 绘图设备
在 Qt 中绘图设备QPaintDevice 是用于支持 QPainter 进行绘制的对象。它提供了一个二维的绘图表面可以是窗口、图片、缓冲区等。所有可以绘制的对象都继承自 QPaintDevice例如 QWidget、QPixmap、QImage 等。
QPaintDevice 本身是一个基类不能直接使用而是通过其子类来提供不同的绘图方式和特性。
Qt 提供的主要绘图设备
Qt 提供了四种常见的绘图设备分别是
QPixmap - 适用于屏幕显示的优化图像。QBitmap - QPixmap 的子类仅支持单色位图1 位深度。QImage - 适用于像素级访问的图像数据。QPicture - 记录和重放 QPainter 命令的设备。
Qt 主要绘图设备的特点
绘图设备特点适用场景QPixmap适用于屏幕显示底层优化存储格式与设备相关UI 组件绘制、按钮、标签、绘制缓冲QBitmap单色位图 (1-bit)是 QPixmap 的子类绘制蒙版、遮罩、位操作QImage支持像素级访问可独立于设备存储图像处理、滤波、像素操作QPicture记录 QPainter 命令适用于重放绘图操作矢量绘图、回放绘制
各个绘图设备的详细介绍
① QPixmap屏幕优化的图像
QPixmap 是一种高效的图像存储方式它主要用于 屏幕显示在底层进行了特定优化能在不同操作系统上实现最快的绘制效果。QPixmap 不能 直接访问像素数据因此 不适合像素级操作如果需要操作像素可以使用 QImage。
示例加载并显示一张图片 创建 Qt Widgets 应用程序 在 Qt Creator 中新建一个 Qt Widgets Application 项目并选择 QMainWindow 作为主窗口类型。 修改 mainwindow.h 在 mainwindow.h 文件中添加 QLabel 作为图片显示组件。 修改 mainwindow.cpp 在 mainwindow.cpp 文件中加载并显示图片。 运行程序窗口中会显示 image.png 这张图片。 mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include QMainWindow
#include QLabelclass MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent nullptr);~MainWindow();private:QLabel *imageLabel; // 用于显示图片的 QLabel
};#endif // MAINWINDOW_Hmainwindow.cpp
#include mainwindow.h
#include QPixmapMainWindow::MainWindow(QWidget *parent): QMainWindow(parent)
{// 创建 QLabel 用于显示图片imageLabel new QLabel(this);// 加载图片QPixmap pixmap(image.png); // 确保 image.png 在可访问的路径if (pixmap.isNull()) {imageLabel-setText(图片加载失败);} else {imageLabel-setPixmap(pixmap);imageLabel-setScaledContents(true); // 让图片适应 QLabel 大小}// 设置 QLabel 作为主窗口的中心组件setCentralWidget(imageLabel);resize(600, 400); // 设置窗口大小
}MainWindow::~MainWindow()
{
}main.cpp
#include mainwindow.h
#include QApplicationint main(int argc, char *argv[])
{QApplication app(argc, argv);MainWindow window;window.show();return app.exec();
}如果路径不对 绘制图片
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include QMainWindow
#include QPixmapclass MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent nullptr);~MainWindow();protected:void paintEvent(QPaintEvent *event) override; // 监听绘制事件private:QPixmap pixmap;
};#endif // MAINWINDOW_Hmainwindow.cpp
#include mainwindow.h
#include QPainterMainWindow::MainWindow(QWidget *parent): QMainWindow(parent)
{// 加载图片pixmap.load(D:/PIC/01.png); // 替换为你的图片路径// 设置窗口大小resize(400, 300);
}// 监听绘制事件使用 QPainter 进行绘制
void MainWindow::paintEvent(QPaintEvent *event)
{QMainWindow::paintEvent(event); // 调用基类的 paintEvent 以确保正常绘制QPainter painter(this);// 确保图片加载成功再绘制if (!pixmap.isNull()) {painter.drawPixmap(0, 0, pixmap.scaled(size(), Qt::KeepAspectRatio, Qt::SmoothTransformation));}
}MainWindow::~MainWindow()
{
}main.cpp
#include mainwindow.h
#include QApplicationint main(int argc, char *argv[])
{QApplication a(argc, argv);MainWindow w;w.show();return a.exec();
}修改mainwindow.cpp
#include mainwindow.h
#include QPainterMainWindow::MainWindow(QWidget *parent): QMainWindow(parent)
{// 加载图片pixmap.load(D:/PIC/01.png); // 替换为你的图片路径// 设置窗口大小resize(800, 400); // 调整窗口大小以适应对比显示
}// 监听绘制事件绘制原图和缩放后的图
void MainWindow::paintEvent(QPaintEvent *event)
{QMainWindow::paintEvent(event); // 调用基类 paintEvent 确保正常绘制QPainter painter(this);if (!pixmap.isNull()) {// 1. 绘制原图左侧painter.drawPixmap(10, 10, pixmap); // 原图按原始大小绘制// 2. 绘制缩放后的图右侧QPixmap scaledPixmap pixmap.scaled(size() / 2, Qt::KeepAspectRatio, Qt::SmoothTransformation);int x width() / 2; // 放在右侧int y (height() - scaledPixmap.height()) / 2; // 居中对齐painter.drawPixmap(x, y, scaledPixmap);}
}MainWindow::~MainWindow()
{
}✅ 左侧按原始大小显示 原图 ✅ 右侧自适应窗口大小的 缩放图 ✅ 缩放窗口时右侧图像会随窗口大小变化
如果希望固定原图的位置或大小可以手动调整 drawPixmap() 的 x, y 坐标。
QImage 和 QPixmap 的区别
QImage 和 QPixmap 都用于处理图像但它们的用途不同。
1. 用途
QPixmap用于屏幕显示针对 GUI 绘图进行了优化通常用于 QPainter 进行高效绘制。QImage用于图像处理支持像素级修改适合I/O 读写、图像转换、过滤处理等。
2. 平台依赖
QPixmap依赖于 底层平台的绘图引擎在不同系统上可能会有不同的显示效果如 Windows、Linux、Mac。QImage完全基于 Qt 自身的绘图引擎在不同平台上的显示效果 一致。
3. 线程
QPixmap不能在非 GUI 线程 中操作因为它依赖于 底层绘图系统。QImage可以在非 GUI 线程 操作因此适用于 多线程图像处理。
4. 像素操作
QPixmap不支持直接像素访问如果需要修改像素必须先转换为 QImage。QImage支持 像素级别访问可以用 setPixel() 和 pixel() 操作单个像素。
适用场景
QPixmapQImage用途绘图 显示处理 操作优化屏幕绘制优化像素处理优化像素级操作❌ 不能直接访问像素✅ 可直接操作像素线程支持仅 GUI 线程可用于非 GUI 线程跨平台显示可能不同保持一致
如果只是显示图片使用 QPixmap性能更好如果要修改图片像素使用 QImage如果要在多线程中操作图片使用 QImage 如果要在绘图中使用 QImage先转换为 QPixmap
② QBitmap
QBitmap 是 QPixmap 的子类表示 单色黑白位图用于 遮罩mask和透明度处理。
特点
仅支持 1-bit 深度0 黑色1 白色。用于透明遮罩例如创建窗口的 不规则形状 或 按钮透明背景。继承 QPixmap受 GPU 加速在绘制时效率较高。
示例创建一个黑白遮罩
#include QApplication
#include QWidget
#include QPainter
#include QBitmapclass BitmapWidget : public QWidget
{
public:BitmapWidget(QWidget *parent nullptr) : QWidget(parent) {}protected:void paintEvent(QPaintEvent *event) override{QPainter painter(this);// 创建 QBitmap黑白位图QBitmap bitmap(100, 100);bitmap.fill(Qt::color0); // 全部填充为黑色// 在 QBitmap 上绘制白色图形QPainter bmpPainter(bitmap);bmpPainter.setBrush(Qt::color1);bmpPainter.drawEllipse(20, 20, 60, 60);bmpPainter.end();// 显示位图painter.drawPixmap(50, 50, bitmap);}
};int main(int argc, char *argv[])
{QApplication app(argc, argv);BitmapWidget w;w.resize(200, 200);w.show();return app.exec();
}应用场景
场景说明遮罩效果例如 透明窗口、按钮背景透明化简单二值化图像处理 黑白图形如 OCR 预处理高效绘制由于 QBitmap 继承 QPixmap它使用 GPU 进行加速绘制
③ QImage
QImage 是 Qt 提供的 通用图像处理类用于 像素级 访问和 图像文件读写。
特点
支持多种格式RGB、灰度、ARGB、CMYK。可直接操作像素数据setPixel()、pixel()。支持 QPainter 进行绘制。可独立于 GUI 线程适合 后台线程 进行图像处理。支持 Alpha 透明度适用于 复杂的图像编辑。
示例加载 QImage 并修改像素
#include QApplication
#include QWidget
#include QImage
#include QPainterclass ImageWidget : public QWidget
{
public:ImageWidget(QWidget *parent nullptr) : QWidget(parent){// 加载图片image QImage(D:/PIC/01.png).scaled(300, 200, Qt::KeepAspectRatio);}protected:void paintEvent(QPaintEvent *event) override{QPainter painter(this);// 修改像素值将左上角 50x50 区域变红for (int y 0; y 50; y){for (int x 0; x 50; x){image.setPixel(x, y, qRgb(255, 0, 0));}}// 绘制 QImagepainter.drawImage(50, 50, image);}private:QImage image;
};int main(int argc, char *argv[])
{QApplication app(argc, argv);ImageWidget w;w.resize(400, 300);w.show();return app.exec();
}应用场景
场景说明图像处理进行 滤波、变换、像素修改图片加载与保存QImage::load() / QImage::save() 支持 BMP, JPG, PNG 等格式多线程处理可以在 后台线程 进行图像计算透明度处理QImage::Format_ARGB32 处理带透明通道的图像
QBitmap vs QImage vs QPixmap
特性QBitmapQImageQPixmap颜色深度1-bit (黑白)8-bit, 16-bit, 32-bit (支持透明)受 平台优化用途遮罩、透明背景像素级处理、文件读写高效屏幕绘制像素操作❌不可修改像素✅ setPixel() / pixel()❌不能修改存储方式GPU内存GPU支持 Alpha 透明❌✅ARGB✅但像素不可直接操作多线程支持❌✅❌
④ QPicture 介绍
QPicture 是 Qt 提供的一种绘图设备它可以 记录 和 重现 QPainter 的绘图命令。
特点
记录绘图操作可以存储 QPainter 的绘制命令并在稍后回放。跨平台使用 平台无关的二进制格式与 Windows、Linux、Mac 兼容。支持多种设备可以绘制到 屏幕、SVG、PDF、PS、打印机等 设备上。高效存储不像 QPixmap 或 QImage 存储像素数据QPicture 仅存储绘图命令占用的存储空间较小。适用于复杂绘制在需要 多次重复相同绘制 时QPicture 可以减少 绘图计算量提高效率。
QPicture 的使用
1. 记录绘制命令
使用 QPainter::begin() 让 QPicture 记录绘制命令使用 end() 停止记录。
#include QApplication
#include QWidget
#include QPainter
#include QPicture
#include QPushButtonclass PictureWidget : public QWidget
{
public:PictureWidget(QWidget *parent nullptr) : QWidget(parent){setFixedSize(400, 300);// 创建 QPicture 并记录绘制操作QPicture picture;QPainter painter;painter.begin(picture); // 开始记录绘图命令painter.setPen(Qt::blue);painter.setFont(QFont(Arial, 20));painter.drawText(50, 50, Hello QPicture);painter.drawRect(100, 100, 200, 100);painter.end(); // 结束记录// 保存到文件picture.save(drawing.dat);}protected:void paintEvent(QPaintEvent *event) override{QPainter painter(this);// 读取 QPicture 并绘制QPicture picture;picture.load(drawing.dat);painter.drawPicture(0, 0, picture);}
};int main(int argc, char *argv[])
{QApplication a(argc, argv);PictureWidget w;w.show();return a.exec();
}QPicture 使用流程
创建 QPicture 对象。使用 QPainter::begin(picture) 开始记录绘图命令。执行 QPainter 相关绘图操作如 drawText()、drawLine()。使用 QPainter::end() 结束绘制记录保存。调用 QPicture::save(filename) 保存到文件可选。使用 QPicture::load(filename) 重新加载绘图数据。在 paintEvent() 里调用 QPainter::drawPicture() 进行绘制。
适用场景
适用情况说明重复绘制相同图形QPicture 存储的是绘制命令不占用大量存储空间提高效率。存储复杂绘图适合用于 矢量图形存储可以绘制到 屏幕、PDF、SVG、打印机 等不同设备上。减少 CPU 计算直接回放绘图命令而不是重新计算图形减少 QPainter 计算量。
QPicture 适用于 记录和回放绘图操作节省资源。QPixmap 适用于 高效屏幕绘制但不易存储和修改。QImage 适用于 像素级处理和 I/O 读写可以直接访问像素数据。
如果你需要在 多个设备上显示相同的矢量图形或者需要 保存绘图过程QPicture 是一个很好的选择 文件处理 (File Handling)
QT 提供了一些类来帮助你处理文件读写、文件选择、目录遍历等操作。
QFile用来处理文件的基本操作如打开文件、读取、写入、关闭文件等。
QFile file(example.txt);
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {QTextStream in(file);QString content in.readAll();qDebug() content;file.close();
}QFileDialog用于显示文件对话框允许用户选择文件或目录。
QString fileName QFileDialog::getOpenFileName(this, Open File, , Text Files (*.txt));
if (!fileName.isEmpty()) {// 处理文件
}QDir用于处理目录的操作如列出目录中的文件、创建目录等。
QDir dir(/path/to/directory);
QStringList files dir.entryList(QDir::Files);
for (const QString file : files) {qDebug() file;
}总结
消息事件机制通过事件循环和事件处理函数来响应用户输入。绘图使用 QPainter、QPixmap 和 QGraphicsView 等类绘制图形、文本和图像。文件操作通过 QFile、QFileDialog 和 QDir 类来处理文件和目录的读写及选择。
这些功能为你在 QT 中开发丰富的 GUI 应用程序提供了强大的支持。