QT学习之 画家、画笔、画刷、字体(附 相册代码)

目录

         一、Qt绘图基础:事件、画笔、字体、画刷与画家

1、绘图事件(Paint Event)

2、画家(QPainter)

3、画笔(QPen)

4、字体(QFont)

5、画刷(QBrush)

二、综合示例一

三、综合示例二


一、Qt绘图基础:事件、画笔、字体、画刷与画家

在Qt中创建图形界面或进行自定义绘制时,理解其核心绘图机制至关重要。这一切通常围绕着绘图事件以及几个关键的类展开。

1、绘图事件(Paint Event)

Qt的绘图不是即时发生的,而是通过事件驱动的。当窗口首次显示、被其他窗口遮挡后重新显示、窗口大小改变,或者我们显式地调用QWidget::update()QWidget::repaint()时,Qt会向窗口发送一个绘图事件(Paint Event)

为了响应这个事件并执行自定义的绘制逻辑,我们需要重写(Override) QWidget(或其子类,如QPushButton、QLabel等)中的paintEvent(QPaintEvent *event)虚函数。

protected:
    void paintEvent(QPaintEvent *event) override {
        // 在这里执行所有的绘图操作
        Q_UNUSED(event); // 通常我们只关心需要绘制的区域,event->region()可以获取,但简单绘制时可忽略
    }

当Qt调用我们的paintEvent函数时,我们就获得了在特定窗口或控件上绘制的机会。在这个函数内部,我们通常会创建一个QPainter对象,并利用它来进行实际的绘图工作。

2、画家(QPainter)

QPainter是Qt绘图系统的核心类,可以将其理解为一位“画家”,负责实际执行绘图操作。我们通常在paintEvent函数内部创建一个QPainter对象,并将其与需要绘制的窗口或控件(通过begin()或更推荐的QPainter构造函数/重载的drawXXX函数的device参数关联起来)。

void MyWidget::paintEvent(QPaintEvent *event) {
    QPainter painter(this); // 创建画家,并指定绘制目标为当前窗口(this)
    // ... 设置画笔、画刷、字体等
    // ... 调用drawRect, drawText等绘图函数
}

QPainter提供了丰富的绘图函数,如drawRect()drawLine()drawText()drawPixmap()等,用于绘制各种图形和图像。

3、画笔(QPen)

QPen定义了绘制线条和形状轮廓的样式。它决定了线条的颜色、宽度、样式(如实线、虚线、点线)等。

QPen pen(Qt::black, 2, Qt::SolidLine); // 创建画笔:黑色实线,宽度为2
painter.setPen(pen); // 将设置好的画笔应用到画家上
painter.drawRect(50, 50, 200, 100); // 使用当前画笔绘制矩形框

这段代码表示:在paintEvent中,我们创建了一个黑色、宽度为2像素的实线画笔,并将其设置为当前QPainter使用的画笔。然后,调用drawRect绘制一个矩形。此时,这个矩形的边框将呈现为黑色、宽度为2像素的实线。画笔决定了框的边框样式和颜色

4、字体(QFont)

QFont定义了绘制文本的字体属性,如字体家族、大小、重量(粗体/正常)、斜体等。

QFont font("SimSun", 12, QFont::Bold); // 创建字体:宋体,12号字,粗体
painter.setFont(font); // 将设置好的字体应用到画家上
painter.drawText(70, 80, "Hello, World!"); // 使用当前字体在指定位置绘制文本

这段代码表示:在paintEvent中,我们创建了一个宋体、12号、粗体的字体,并将其设置为当前QPainter使用的字体。然后,调用drawText在坐标(70, 80)处绘制文本"Hello, World!"。此时,文本将使用指定的宋体、12号粗体样式显示。字体决定了文本的样式和大小

5、画刷(QBrush)

QBrush定义了填充形状内部的样式。它可以是纯色、渐变色或图案。

QBrush brush(Qt::yellow); // 创建画刷:黄色填充
painter.setBrush(brush); // 将设置好的画刷应用到画家上
painter.drawRect(50, 50, 200, 100); // 使用当前画刷填充矩形

二、综合示例一

结合上述所有组件,我们可以完整地实现Pointer画框、写字、涂色的场景:

#include <QApplication>
#include <QWidget>
#include <QPainter>
#include <QPen>
#include <QFont>
#include <QBrush>

class MyWidget : public QWidget {
protected:
    void paintEvent(QPaintEvent *event) override {
        QPainter painter(this);

        // 1. 画笔:绘制矩形框
        QPen pen(Qt::black, 2, Qt::SolidLine);
        painter.setPen(pen);
        painter.drawRect(50, 50, 200, 100);

        // 2. 字体:在框内写宋体字
        QFont font("SimSun", 12, QFont::Bold);
        painter.setFont(font);
        painter.drawText(70, 80, "Hello, World!");

        // 3. 画刷:用黄色填充框
        QBrush brush(Qt::yellow);
        painter.setBrush(brush);
        painter.drawRect(50, 50, 200, 100);
    }
};

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);
    MyWidget widget;
    widget.resize(300, 200);
    widget.show();
    return app.exec();
}

这段代码展示了如何结合QPainter、QPen、QFont和QBrush来实现Pointer的场景。首先用画笔绘制矩形框,然后用字体在框内写宋体字,最后用画刷将框填充为黄色。
在这里插入图片描述

三、综合示例二

在box框内显示图片,按左右键更新图片;
picturesdialog.cpp

#include "picturesdialog.h"
#include "ui_picturesdialog.h"
#include <QPainter>

PicturesDialog::PicturesDialog(QWidget *parent)
    : QDialog(parent)
    , ui(new Ui::PicturesDialog)
    ,m_imageIndex(0)
{
    ui->setupUi(this);
    enableButtons();
}

PicturesDialog::~PicturesDialog()
{
    delete ui;
}

void PicturesDialog::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    QRect framRect = ui->m_frmImage->rect();
    framRect.translate(ui->m_frmImage->pos());
    QImage image(":/images/" + QString::number(m_imageIndex) + ".jpg");
    painter.drawImage(framRect,image);
}

void PicturesDialog::on_m_btnPrev_clicked()
{
    --m_imageIndex;
    enableButtons();
    update();
}

void PicturesDialog::on_m_btnNext_clicked()
{
    ++m_imageIndex;
    enableButtons();
    update();
}

 void PicturesDialog::enableButtons()
 {
     ui->m_btnPrev->setEnabled(m_imageIndex>0);
     ui->m_btnNext->setEnabled(m_imageIndex<6);
 }

picturesdialog.h

#ifndef PICTURESDIALOG_H
#define PICTURESDIALOG_H

#include <QDialog>

QT_BEGIN_NAMESPACE
namespace Ui { class PicturesDialog; }
QT_END_NAMESPACE

class PicturesDialog : public QDialog
{
    Q_OBJECT

public:
    PicturesDialog(QWidget *parent = nullptr);
    ~PicturesDialog();
protected:
    void paintEvent(QPaintEvent *);


private slots:
    void on_m_btnPrev_clicked();

    void on_m_btnNext_clicked();

private:
    void enableButtons();
private:
    Ui::PicturesDialog *ui;
    int m_imageIndex;
};
#endif // PICTURESDIALOG_H

picturesdialog.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>PicturesDialog</class>
 <widget class="QDialog" name="PicturesDialog">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>315</width>
    <height>560</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>图片</string>
  </property>
  <layout class="QVBoxLayout" name="m_layoutVer">
   <item>
    <widget class="QFrame" name="m_frmImage">
     <property name="enabled">
      <bool>true</bool>
     </property>
     <property name="sizePolicy">
      <sizepolicy hsizetype="Preferred" vsizetype="Expanding">
       <horstretch>0</horstretch>
       <verstretch>0</verstretch>
      </sizepolicy>
     </property>
     <property name="frameShape">
      <enum>QFrame::Box</enum>
     </property>
     <property name="frameShadow">
      <enum>QFrame::Plain</enum>
     </property>
     <property name="lineWidth">
      <number>1</number>
     </property>
    </widget>
   </item>
   <item>
    <layout class="QHBoxLayout" name="m_layoutHor">
     <item>
      <spacer name="m_spacerLeft">
       <property name="orientation">
        <enum>Qt::Horizontal</enum>
       </property>
       <property name="sizeHint" stdset="0">
        <size>
         <width>40</width>
         <height>20</height>
        </size>
       </property>
      </spacer>
     </item>
     <item>
      <widget class="QPushButton" name="m_btnPrev">
       <property name="text">
        <string>上一张</string>
       </property>
      </widget>
     </item>
     <item>
      <widget class="QPushButton" name="m_btnNext">
       <property name="text">
        <string>下一张</string>
       </property>
       <property name="default">
        <bool>true</bool>
       </property>
      </widget>
     </item>
     <item>
      <spacer name="m_spacerRight">
       <property name="orientation">
        <enum>Qt::Horizontal</enum>
       </property>
       <property name="sizeHint" stdset="0">
        <size>
         <width>40</width>
         <height>20</height>
        </size>
       </property>
      </spacer>
     </item>
    </layout>
   </item>
  </layout>
 </widget>
 <resources/>
 <connections/>
</ui>

效果图:在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

拥有阳光拥有爱

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

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

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

打赏作者

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

抵扣说明:

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

余额充值