Qt涂鸦示例

本文档详细介绍了Qt的Scribble示例,展示了如何重新实现事件处理程序以实现绘图功能,包括鼠标事件、绘制事件、调整大小事件等。用户可以在自定义的Qt小部件上进行绘图,同时应用提供了菜单选项,允许打开、编辑、保存图像,选择笔颜色和宽度。示例由两个类构成:一个自定义小部件用于显示和编辑图像,另一个类提供菜单支持。文章涵盖了类的定义、实现以及相关的事件处理逻辑。
摘要由CSDN通过智能技术生成

Scribble 示例演示如何重新实现某些 的事件处理程序,以接收为应用程序的小部件生成的事件。

我们重新实现鼠标事件处理程序以实现绘图,重新实现绘制事件处理程序以更新应用程序,重新实现调整大小事件处理程序以优化应用程序的外观。此外,我们重新实现 close 事件处理程序,以便在终止应用程序之前拦截 close 事件。

该示例还演示了如何使用实时绘制图像,以及重新绘制小部件。

使用涂鸦应用程序,用户可以绘制图像。该菜单使用户可以打开和编辑现有图像文件,保存图像并退出应用程序。绘图时,菜单允许用户选择笔颜色和笔宽,以及清除屏幕。此外,该菜单还为用户提供了有关Scribble示例以及一般Qt的信息。

该示例由两个类组成:

  • ScribbleArea是一个自定义小部件,显示并允许用户在其上绘制。
  • MainWindow在 上方提供了一个菜单。ScribbleArea

我们将从复习课程开始。然后我们将回顾该类,该类使用 .ScribbleAreaMainWindowScribbleArea

涂鸦区域类定义

<span style="color:#404244"><span style="background-color:#3a4055"><span style="color:#ffffff"><span style="color:#ffff55">class</span> <span style="color:#4f9d08">ScribbleArea</span> <span style="color:#ffffff">:</span> <span style="color:#ffff55">public</span> <a data-cke-saved-href="https://doc.qt.io/qt-6/qwidget.html" href="https://doc.qt.io/qt-6/qwidget.html"><span style="color:#21be2b">QWidget</span></a>
<span style="color:#ffffff">{</span><span style="color:#ffffff">
    Q_OBJECT

</span><span style="color:#ffff55">public</span><span style="color:#ffffff">:</span>
    <span style="color:#4f9d08">ScribbleArea</span><span style="color:#ffffff">(</span><a data-cke-saved-href="https://doc.qt.io/qt-6/qwidget.html" href="https://doc.qt.io/qt-6/qwidget.html"><span style="color:#21be2b">QWidget</span></a> <span style="color:#ffffff">*</span><span style="color:#ffffff">parent </span><span style="color:#ffffff">=</span> <span style="color:#ffff55">nullptr</span><span style="color:#ffffff">);</span>

    <span style="color:#ffff55">bool</span><span style="color:#ffffff"> openImage</span><span style="color:#ffffff">(</span><span style="color:#ffff55">const</span> <a data-cke-saved-href="https://doc.qt.io/qt-6/qstring.html" href="https://doc.qt.io/qt-6/qstring.html"><span style="color:#21be2b">QString</span></a> <span style="color:#ffffff">&</span><span style="color:#ffffff">fileName</span><span style="color:#ffffff">);</span>
    <span style="color:#ffff55">bool</span><span style="color:#ffffff"> saveImage</span><span style="color:#ffffff">(</span><span style="color:#ffff55">const</span> <a data-cke-saved-href="https://doc.qt.io/qt-6/qstring.html" href="https://doc.qt.io/qt-6/qstring.html"><span style="color:#21be2b">QString</span></a> <span style="color:#ffffff">&</span><span style="color:#ffffff">fileName</span><span style="color:#ffffff">,</span> <span style="color:#ffff55">const</span> <span style="color:#ffff55">char</span> <span style="color:#ffffff">*</span><span style="color:#ffffff">fileFormat</span><span style="color:#ffffff">);</span>
    <span style="color:#ffff55">void</span><span style="color:#ffffff"> setPenColor</span><span style="color:#ffffff">(</span><span style="color:#ffff55">const</span> <a data-cke-saved-href="https://doc.qt.io/qt-6/qcolor.html" href="https://doc.qt.io/qt-6/qcolor.html"><span style="color:#21be2b">QColor</span></a> <span style="color:#ffffff">&</span><span style="color:#ffffff">newColor</span><span style="color:#ffffff">);</span>
    <span style="color:#ffff55">void</span><span style="color:#ffffff"> setPenWidth</span><span style="color:#ffffff">(</span><span style="color:#ffff55">int</span><span style="color:#ffffff"> newWidth</span><span style="color:#ffffff">);</span>

    <span style="color:#ffff55">bool</span><span style="color:#ffffff"> isModified</span><span style="color:#ffffff">()</span> <span style="color:#ffff55">const</span> <span style="color:#ffffff">{</span> <span style="color:#ffff55">return</span><span style="color:#ffffff"> modified</span><span style="color:#ffffff">;</span> <span style="color:#ffffff">}</span>
    <a data-cke-saved-href="https://doc.qt.io/qt-6/qcolor.html" href="https://doc.qt.io/qt-6/qcolor.html"><span style="color:#21be2b">QColor</span></a><span style="color:#ffffff"> penColor</span><span style="color:#ffffff">()</span> <span style="color:#ffff55">const</span> <span style="color:#ffffff">{</span> <span style="color:#ffff55">return</span><span style="color:#ffffff"> myPenColor</span><span style="color:#ffffff">;</span> <span style="color:#ffffff">}</span>
    <span style="color:#ffff55">int</span><span style="color:#ffffff"> penWidth</span><span style="color:#ffffff">()</span> <span style="color:#ffff55">const</span> <span style="color:#ffffff">{</span> <span style="color:#ffff55">return</span><span style="color:#ffffff"> myPenWidth</span><span style="color:#ffffff">;</span> <span style="color:#ffffff">}</span>

<span style="color:#ffff55">public</span> <span style="color:#ffffff">slots</span><span style="color:#ffffff">:</span>
    <span style="color:#ffff55">void</span><span style="color:#ffffff"> clearImage</span><span style="color:#ffffff">();</span>
    <span style="color:#ffff55">void</span> <span style="color:#ffff55">print</span><span style="color:#ffffff">();</span>

<span style="color:#ffff55">protected</span><span style="color:#ffffff">:</span>
    <span style="color:#ffff55">void</span><span style="color:#ffffff"> mousePressEvent</span><span style="color:#ffffff">(</span><a data-cke-saved-href="https://doc.qt.io/qt-6/qmouseevent.html" href="https://doc.qt.io/qt-6/qmouseevent.html"><span style="color:#21be2b">QMouseEvent</span></a> <span style="color:#ffffff">*</span><span style="color:#ffff55">event</span><span style="color:#ffffff">)</span> <span style="color:#ffff55">override</span><span style="color:#ffffff">;</span>
    <span style="color:#ffff55">void</span><span style="color:#ffffff"> mouseMoveEvent</span><span style="color:#ffffff">(</span><a data-cke-saved-href="https://doc.qt.io/qt-6/qmouseevent.html" href="https://doc.qt.io/qt-6/qmouseevent.html"><span style="color:#21be2b">QMouseEvent</span></a> <span style="color:#ffffff">*</span><span style="color:#ffff55">event</span><span style="color:#ffffff">)</span> <span style="color:#ffff55">override</span><span style="color:#ffffff">;</span>
    <span style="color:#ffff55">void</span><span style="color:#ffffff"> mouseReleaseEvent</span><span style="color:#ffffff">(</span><a data-cke-saved-href="https://doc.qt.io/qt-6/qmouseevent.html" href="https://doc.qt.io/qt-6/qmouseevent.html"><span style="color:#21be2b">QMouseEvent</span></a> <span style="color:#ffffff">*</span><span style="color:#ffff55">event</span><span style="color:#ffffff">)</span> <span style="color:#ffff55">override</span><span style="color:#ffffff">;</span>
    <span style="color:#ffff55">void</span><span style="color:#ffffff"> paintEvent</span><span style="color:#ffffff">(</span><a data-cke-saved-href="https://doc.qt.io/qt-6/qpaintevent.html" href="https://doc.qt.io/qt-6/qpaintevent.html"><span style="color:#21be2b">QPaintEvent</span></a> <span style="color:#ffffff">*</span><span style="color:#ffff55">event</span><span style="color:#ffffff">)</span> <span style="color:#ffff55">override</span><span style="color:#ffffff">;</span>
    <span style="color:#ffff55">void</span><span style="color:#ffffff"> resizeEvent</span><span style="color:#ffffff">(</span><a data-cke-saved-href="https://doc.qt.io/qt-6/qresizeevent.html" href="https://doc.qt.io/qt-6/qresizeevent.html"><span style="color:#21be2b">QResizeEvent</span></a> <span style="color:#ffffff">*</span><span style="color:#ffff55">event</span><span style="color:#ffffff">)</span> <span style="color:#ffff55">override</span><span style="color:#ffffff">;</span>

<span style="color:#ffff55">private</span><span style="color:#ffffff">:</span>
    <span style="color:#ffff55">void</span><span style="color:#ffffff"> drawLineTo</span><span style="color:#ffffff">(</span><span style="color:#ffff55">const</span> <a data-cke-saved-href="https://doc.qt.io/qt-6/qpoint.html" href="https://doc.qt.io/qt-6/qpoint.html"><span style="color:#21be2b">QPoint</span></a> <span style="color:#ffffff">&</span><span style="color:#ffffff">endPoint</span><span style="color:#ffffff">);</span>
    <span style="color:#ffff55">void</span><span style="color:#ffffff"> resizeImage</span><span style="color:#ffffff">(</span><a data-cke-saved-href="https://doc.qt.io/qt-6/qimage.html" href="https://doc.qt.io/qt-6/qimage.html"><span style="color:#21be2b">QImage</span></a> <span style="color:#ffffff">*</span><span style="color:#ffffff">image</span><span style="color:#ffffff">,</span> <span style="color:#ffff55">const</span> <a data-cke-saved-href="https://doc.qt.io/qt-6/qsize.html" href="https://doc.qt.io/qt-6/qsize.html"><span style="color:#21be2b">QSize</span></a> <span style="color:#ffffff">&</span><span style="color:#ffffff">newSize</span><span style="color:#ffffff">);</span>

    <span style="color:#ffff55">bool</span><span style="color:#ffffff"> modified </span><span style="color:#ffffff">=</span> <span style="color:#ffff55">false</span><span style="color:#ffffff">;</span>
    <span style="color:#ffff55">bool</span><span style="color:#ffffff"> scribbling </span><span style="color:#ffffff">=</span> <span style="color:#ffff55">false</span><span style="color:#ffffff">;</span>
    <span style="color:#ffff55">int</span><span style="color:#ffffff"> myPenWidth </span><span style="color:#ffffff">=</span> <span style="color:#ff55ff">1</span><span style="color:#ffffff">;</span>
    <a data-cke-saved-href="https://doc.qt.io/qt-6/qcolor.html" href="https://doc.qt.io/qt-6/qcolor.html"><span style="color:#21be2b">QColor</span></a><span style="color:#ffffff"> myPenColor </span><span style="color:#ffffff">=</span> <a data-cke-saved-href="https://doc.qt.io/qt-6/qt.html" href="https://doc.qt.io/qt-6/qt.html"><span style="color:#21be2b">Qt</span></a><span style="color:#ffffff">::</span><span style="color:#ffffff">blue</span><span style="color:#ffffff">;</span>
    <a data-cke-saved-href="https://doc.qt.io/qt-6/qimage.html" href="https://doc.qt.io/qt-6/qimage.html"><span style="color:#21be2b">QImage</span></a><span style="color:#ffffff"> image</span><span style="color:#ffffff">;</span>
    <a data-cke-saved-href="https://doc.qt.io/qt-6/qpoint.html" href="https://doc.qt.io/qt-6/qpoint.html"><span style="color:#21be2b">QPoint</span></a><span style="color:#ffffff"> lastPoint</span><span style="color:#ffffff">;</span>
<span style="color:#ffffff">};</span></span></span></span>

该类继承自 。我们重新实现 和 函数来实现绘图。我们重新实现函数以更新涂鸦区域,并重新实现函数以确保我们绘制的函数在任何时候至少与小部件一样大。ScribbleAreamousePressEvent()mouseMoveEvent()mouseReleaseEvent()paintEvent()resizeEvent()

我们需要几个公共函数:将图像从文件加载到涂鸦区域,允许用户编辑图像; 将当前显示的图像写入文件; 插槽清除涂鸦区域中显示的图像。我们需要私有函数来实际绘制,并更改 .插槽处理打印。openImage()save()clearImage()drawLineTo()resizeImage()print()

我们还需要以下私有变量:

  • modified是涂鸦区域中显示的图像是否有未保存的更改。true
  • scribbling当用户在涂鸦区域内按鼠标左键时。true
  • penWidth并按住应用程序中使用的笔的当前设置的宽度和颜色。penColor
  • image存储用户绘制的图像。
  • lastPoint在上次按下鼠标或鼠标移动事件时保持光标的位置。

涂鸦区域类实现

<span style="color:#404244"><span style="background-color:#3a4055"><span style="color:#ffffff"><span style="color:#4f9d08">ScribbleArea</span><span style="color:#ffffff">::</span><span style="color:#4f9d08">ScribbleArea</span><span style="color:#ffffff">(</span><a data-cke-saved-href="https://doc.qt.io/qt-6/qwidget.html" href="https://doc.qt.io/qt-6/qwidget.html"><span style="color:#21be2b">QWidget</span></a> <span style="color:#ffffff">*</span><span style="color:#ffffff">parent</span><span style="color:#ffffff">)</span>
    <span style="color:#ffffff">:</span> <a data-cke-saved-href="https://doc.qt.io/qt-6/qwidget.html" href="https://doc.qt.io/qt-6/qwidget.html"><span style="color:#21be2b">QWidget</span></a><span style="color:#ffffff">(</span><span style="color:#ffffff">parent</span><span style="color:#ffffff">)</span>
<span style="color:#ffffff">{</span><span style="color:#ffffff">
    setAttribute</span><span style="color:#ffffff">(</span><a data-cke-saved-href="https://doc.qt.io/qt-6/qt.html" href="https://doc.qt.io/qt-6/qt.html"><span style="color:#21be2b">Qt</span></a><span style="color:#ffffff">::</span><span style="color:#ffffff">WA_StaticContents</span><span style="color:#ffffff">);</span>
<span style="color:#ffffff">}</span></span></span></span>

在构造函数中,我们设置了小部件的属性,指示小部件内容根植于左上角,并且在调整小部件大小时不会更改。Qt使用此属性来优化调整大小时的绘画事件。这纯粹是一种优化,只应用于内容是静态的并且根植于左上角的小部件。

<span style="color:#404244"><span style="background-color:#3a4055"><span style="color:#ffffff"><span style="color:#ffff55">bool</span> <span style="color:#4f9d08">ScribbleArea</span><span style="color:#ffffff">::</span><span style="color:#ffffff">openImage</span><span style="color:#ffffff">(</span><span style="color:#ffff55">const</span> <a data-cke-saved-href="https://doc.qt.io/qt-6/qstring.html" href="https://doc.qt.io/qt-6/qstring.html"><span style="color:#21be2b">QString</span></a> <span style="color:#ffffff">&</span><span style="color:#ffffff">fileName</span><span style="color:#ffffff">)</span>
<span style="color:#ffffff">{</span>
    <a data-cke-saved-href="https://doc.qt.io/qt-6/qimage.html" href="https://doc.qt.io/qt-6/qimage.html"><span style="color:#21be2b">QImage</span></a><span style="color:#ffffff"> loadedImage</span><span style="color:#ffffff">;</span>
    <span style="color:#ffff55">if</span> <span style="color:#ffffff">(</span><span style="color:#ffffff">!</span><span style="color:#ffffff">loadedImage</span><span style="color:#ffffff">.</span><span style="color:#ffffff">load</span><span style="color:#ffffff">(</span><span style="color:#ffffff">fileName</span><span style="color:#ffffff">))</span>
        <span style="color:#ffff55">return</span> <span style="color:#ffff55">false</span><span style="color:#ffffff">;</span>

    <a data-cke-saved-href="https://doc.qt.io/qt-6/qsize.html" href="https://doc.qt.io/qt-6/qsize.html"><span style="color:#21be2b">QSize</span></a><span style="color:#ffffff"> newSize </span><span style="color:#ffffff">=</span><span style="color:#ffffff"> loadedImage</span><span style="color:#ffffff">.</span><span style="color:#ffffff">size</span><span style="color:#ffffff">()</span><span style="color:#ffffff">.</span><span style="color:#ffffff">expandedTo</span><span style="color:#ffffff">(</span><span style="color:#ffffff">size</span><span style="color:#ffffff">());</span><span style="color:#ffffff">
    resizeImage</span><span style="color:#ffffff">(</span><span style="color:#ffffff">&</span><span style="color:#ffffff">loadedImage</span><span style="color:#ffffff">,</span><span style="color:#ffffff"> newSize</span><span style="color:#ffffff">);</span><span style="color:#ffffff">
    image </span><span style="color:#ffffff">=</span><span style="color:#ffffff"> loadedImage</span><span style="color:#ffffff">;</span><span style="color:#ffffff">
    modified </span><span style="color:#ffffff">=</span> <span style="color:#ffff55">false</span><span style="color:#ffffff">;</span><span style="color:#ffffff">
    update</span><span style="color:#ffffff">();</span>
    <span style="color:#ffff55">return</span> <span style="color:#ffff55">true</span><span style="color:#ffffff">;</span>
<span style="color:#ffffff">}</span></span></span></span>

在函数中,我们加载给定的图像。然后,我们使用私有函数将加载的大小调整为至少与两个方向上的小部件一样大,并将成员变量设置为加载的图像。最后,我们调用 () 来安排重绘。openImage()resizeImage()image

<span style="color:#404244"><span style="background-color:#3a4055"><span style="color:#ffffff"><span style="color:#ffff55">bool</span> <span style="color:#4f9d08">ScribbleArea</span><span style="color:#ffffff">::</span><span style="color:#ffffff">saveImage</span><span style="color:#ffffff">(</span><span style="color:#ffff55">const</span> <a data-cke-saved-href="https://doc.qt.io/qt-6/qstring.html" href="https://doc.qt.io/qt-6/qstring.html"><span style="color:#21be2b">QString</span></a> <span style="color:#ffffff">&</span><span style="color:#ffffff">fileName</span><span style="color:#ffffff">,</span> <span style="color:#ffff55">const</span> <span style="color:#ffff55">char</span> <span style="color:#ffffff">*</span><span style="color:#ffffff">fileFormat</span><span style="color:#ffffff">)</span>
<span style="color:#ffffff">{</span>
    <a data-cke-saved-href="https://doc.qt.io/qt-6/qimage.html" href="https://doc.qt.io/qt-6/qimage.html"><span style="color:#21be2b">QImage</span></a><span style="color:#ffffff"> visibleImage </span><span style="color:#ffffff">=</span><span style="color:#ffffff"> image</span><span style="color:#ffffff">;</span><span style="color:#ffffff">
    resizeImage</span><span style="color:#ffffff">(</span><span style="color:#ffffff">&</span><span style="color:#ffffff">visibleImage</span><span style="color:#ffffff">,</span><span style="color:#ffffff"> size</span><span style="color:#ffffff">());</span>

    <span style="color:#ffff55">if</span> <span style="color:#ffffff">(</span><span style="color:#ffffff">visibleImage</span><span style="color:#ffffff">.</span><span style="color:#ffffff">save</span><span style="color:#ffffff">(</span><span style="color:#ffffff">fileName</span><span style="color:#ffffff">,</span><span style="color:#ffffff"> fileFormat</span><span style="color:#ffffff">))</span> <span style="color:#ffffff">{</span><span style="color:#ffffff">
        modified </span><span style="color:#ffffff">=</span> <span style="color:#ffff55">false</span><span style="color:#ffffff">;</span>
        <span style="color:#ffff55">return</span> <span style="color:#ffff55">true</span><span style="color:#ffffff">;</span>
    <span style="color:#ffffff">}</span>
    <span style="color:#ffff55">return</span> <span style="color:#ffff55">false</span><span style="color:#ffffff">;</span>
<span style="color:#ffffff">}</span></span></span></span>

该函数创建一个仅覆盖实际可见部分的对象,并使用 () 保存它。如果图像成功保存,我们将涂鸦区域的变量设置为 ,因为没有未保存的数据。saveImage()imagemodifiedfalse

<span style="color:#404244"><span style="background-color:#3a4055"><span style="color:#ffffff"><span style="color:#ffff55">void</span> <span style="color:#4f9d08">ScribbleArea</span><span style="color:#ffffff">::</span><span style="color:#ffffff">setPenColor</span><span style="color:#ffffff">(</span><span style="color:#ffff55">const</span> <a data-cke-saved-href="https://doc.qt.io/qt-6/qcolor.html" href="https://doc.qt.io/qt-6/qcolor.html"><span style="color:#21be2b">QColor</span></a> <span style="color:#ffffff">&</span><span style="color:#ffffff">newColor</span><span style="color:#ffffff">)</span>
<span style="color:#ffffff">{</span><span style="color:#ffffff">
    myPenColor </span><span style="color:#ffffff">=</span><span style="color:#ffffff"> newColor</span><span style="color:#ffffff">;</span>
<span style="color:#ffffff">}</span>

<span style="color:#ffff55">void</span> <span style="color:#4f9d08">ScribbleArea</span><span style="color:#ffffff">::</span><span style="color:#ffffff">setPenWidth</span><span style="color:#ffffff">(</span><span style="color:#ffff55">int</span><span style="color:#ffffff"> newWidth</span><span style="color:#ffffff">)</span>
<span style="color:#ffffff">{</span><span style="color:#ffffff">
    myPenWidth </span><span style="color:#ffffff">=</span><span style="color:#ffffff"> newWidth</span><span style="color:#ffffff">;</span>
<span style="color:#ffffff">}</span></span></span></span>

和函数设置当前笔的颜色和宽度。这些值将用于将来的绘图操作。setPenColor()setPenWidth()

<span style="color:#404244"><span style="background-color:#3a4055"><span style="color:#ffffff"><span style="color:#ffff55">void</span> <span style="color:#4f9d08">ScribbleArea</span><span style="color:#ffffff">::</span><span style="color:#ffffff">clearImage</span><span style="color:#ffffff">()</span>
<span style="color:#ffffff">{</span><span style="color:#ffffff">
    image</span><span style="color:#ffffff">.</span><span style="color:#ffffff">fill</span><span style="color:#ffffff">(</span><a data-cke-saved-href="https://doc.qt.io/qt-6/qcolor.html#qRgb" href="https://doc.qt.io/qt-6/qcolor.html#qRgb"><span style="color:#ffffff">qRgb</span></a><span style="color:#ffffff">(</span><span style="color:#ff55ff">255</span><span style="color:#ffffff">,</span> <span style="color:#ff55ff">255</span><span style="color:#ffffff">,</span> <span style="color:#ff55ff">255</span><span style="color:#ffffff">));</span><span style="color:#ffffff">
    modified </span><span style="color:#ffffff">=</span> <span style="color:#ffff55">true</span><span style="color:#ffffff">;</span><span style="color:#ffffff">
    update</span><span style="color:#ffffff">();</span>
<sp
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

亭台六七座

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值