布局完成后,就可以修改控件的名称,以及添加初始化数据

1. 控件添加数据

来到widget.cpp的构造中,为控件添加初始化数据,如下:

Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget)
{
    ui->setupUi(this);

    this->setWindowTitle("明王讲QT | 第六章 绘图、自定义控件 | 基本绘制");

    // 1. 初始化字体
    this->setStyleSheet("QWidget{font: 18px;}");
    QString str = "QLabel{font: bold 18px;}";
    ui->lblShape->setStyleSheet(str);
    ui->lblPen->setStyleSheet(str);
    ui->lblBrush->setStyleSheet(str);
    ui->lblAdvance->setStyleSheet(str);

    // 2. 初始化画笔
    // 2.1 线宽
    ui->spinPenWidth->setRange(1, 10);

    // 2.2 线型-实线、虚线、点画线等
    ui->comboPenStyle->addItem("None", static_cast<int>(Qt::NoPen));
    ui->comboPenStyle->addItem("Solid", static_cast<int>(Qt::SolidLine));
    ui->comboPenStyle->addItem("Dash", static_cast<int>(Qt::DashLine));
    ui->comboPenStyle->addItem("Dot", static_cast<int>(Qt::DotLine));
    ui->comboPenStyle->addItem("Dash Dot", static_cast<int>(Qt::DashDotLine));
    ui->comboPenStyle->addItem("Dash Dot Dot", static_cast<int>(Qt::DashDotDotLine));

    // 2.3 线型-两根线的连接处的样式
    ui->comboPenJoin->addItem("Miter", static_cast<int>(Qt::MiterJoin));
    ui->comboPenJoin->addItem("Bevel", static_cast<int>(Qt::BevelJoin));
    ui->comboPenJoin->addItem("Round", static_cast<int>(Qt::RoundJoin));

    // 2.4 线型-线的端点的样式
    ui->comboPenCap->addItem("Flat", static_cast<int>(Qt::FlatCap));
    ui->comboPenCap->addItem("Square", static_cast<int>(Qt::SquareCap));
    ui->comboPenCap->addItem("Round", static_cast<int>(Qt::RoundCap));

    // 3. 初始化画刷
    ui->comboBrushStyle->addItem(tr("None"), static_cast<int>(Qt::NoBrush));
    ui->comboBrushStyle->addItem(tr("Solid"), static_cast<int>(Qt::SolidPattern));
    ui->comboBrushStyle->addItem(tr("Horizontal"), static_cast<int>(Qt::HorPattern));
    ui->comboBrushStyle->addItem(tr("Vertical"), static_cast<int>(Qt::VerPattern));
    ui->comboBrushStyle->addItem(tr("Cross"), static_cast<int>(Qt::CrossPattern));
    ui->comboBrushStyle->addItem(tr("Backward Diagonal"), static_cast<int>(Qt::BDiagPattern));
    ui->comboBrushStyle->addItem(tr("Forward Diagonal"), static_cast<int>(Qt::FDiagPattern));
    ui->comboBrushStyle->addItem(tr("Diagonal Cross"), static_cast<int>(Qt::DiagCrossPattern));
    ui->comboBrushStyle->addItem(tr("Linear Gradient"), static_cast<int>(Qt::LinearGradientPattern));
    ui->comboBrushStyle->addItem(tr("Radial Gradient"), static_cast<int>(Qt::RadialGradientPattern));
    ui->comboBrushStyle->addItem(tr("Conical Gradient"), static_cast<int>(Qt::ConicalGradientPattern));
    ui->comboBrushStyle->addItem(tr("Dense 1"), static_cast<int>(Qt::Dense1Pattern));
    ui->comboBrushStyle->addItem(tr("Dense 7"), static_cast<int>(Qt::Dense7Pattern));
    ui->comboBrushStyle->addItem(tr("Texture"), static_cast<int>(Qt::TexturePattern));
}

2. 关联信号槽

首先,来到widget.h中声明相关的成员变量、槽函数,并空实现,如下:

#include <QButtonGroup>

class Widget : public QWidget {
private slots:
    void onBtnPenColorClicked();
    void penChanged();

    void onBtnBrushColorClicked();
    void brushChanged();

private:
    QButtonGroup *btnGroup;
};

然后,来到paintwidget.h中声明相关的成员变量、槽函数,并空实现,如下:

#include <QBrush>
#include <QPen>

class PaintWidget : public QWidget {
public slots:
    void setShape(int shape);

    void setPen(const QPen pen);
    void setBrush(const QBrush brush);

    void setAntialias(bool antialias);
    void setTransform(bool transform);

protected:
    // paintEvent() 是一个绘图函数,它是由系统自动调用的,调用时机:
    // (1)窗口大小变化时:比如最大化、最小化、缩放窗口时,系统都会调用该函数
    // (2)手动调用 update():同样会触发系统调用 paintEvent(),从而完成界面的刷新
    void paintEvent(QPaintEvent *event) override;

private:
    int shape;
    QPen pen;
    QBrush brush;

    bool antialias = false;
    bool transform = false;
};

最后,来到widget.cpp构造中,关联信号槽,如下:

Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget)
{
    //...
    
    // 4. 信号槽
    // 4.1 形状
    btnGroup = new QButtonGroup(this);
    btnGroup->addButton(ui->checkPoint, 0);
    btnGroup->addButton(ui->checkLine, 1);
    btnGroup->addButton(ui->checkPolyline, 2);
    btnGroup->addButton(ui->checkPolygon, 3);
    btnGroup->addButton(ui->checkRect, 4);
    btnGroup->addButton(ui->checkRoundRect, 5);
    btnGroup->addButton(ui->checkCircle, 6);
    btnGroup->addButton(ui->checkEllipse, 7);
    btnGroup->addButton(ui->checkArc, 8);
    btnGroup->addButton(ui->checkPie, 9);
    btnGroup->addButton(ui->checkChord, 10);
    btnGroup->addButton(ui->checkBethel, 11);
    btnGroup->addButton(ui->checkText, 12);
    btnGroup->addButton(ui->checkPixmap, 13);
    // btnGroup->setExclusive(true);
    connect(btnGroup, &QButtonGroup::idClicked, ui->paintWidget, &PaintWidget::setShape);
    ui->checkCircle->click();  // 默认选中圆形

    // 4.2 画笔:宽度、颜色、样式、末端、连接
    connect(ui->spinPenWidth, &QSpinBox::valueChanged, this, &Widget::penChanged);
    connect(ui->btnPenColor, &QPushButton::clicked, this, &Widget::onBtnPenColorClicked);
    connect(ui->comboPenStyle, &QComboBox::currentIndexChanged, this, &Widget::penChanged);
    connect(ui->comboPenJoin, &QComboBox::currentIndexChanged, this, &Widget::penChanged);
    connect(ui->comboPenCap, &QComboBox::currentIndexChanged, this, &Widget::penChanged);

    ui->spinPenWidth->setValue(2);          // 默认宽度2
    ui->comboPenStyle->setCurrentIndex(1);  // 默认样式solid
    ui->comboPenJoin->setCurrentIndex(0);   // 默认样式Qt::MiterJoin
    ui->comboPenCap->setCurrentIndex(0);    // 默认样式Qt::FlatCap

    // 4.3 画刷:颜色、样式
    connect(ui->btnBrushColor, &QPushButton::clicked, this, &Widget::onBtnBrushColorClicked);
    connect(ui->comboBrushStyle, &QComboBox::currentIndexChanged, this, &Widget::brushChanged);
    ui->comboBrushStyle->setCurrentIndex(1);  // 默认样式solid

    // 4.4 抗锯齿、平移/旋转/缩放
    connect(ui->checkAntialias, &QCheckBox::toggled, ui->paintWidget, &PaintWidget::setAntialias);
    connect(ui->checkTransform, &QCheckBox::toggled, ui->paintWidget, &PaintWidget::setTransform);
}

3. 添加资源文件

由于后边有绘制图片,以及将图片作为画刷的填充,因此这里先把图片作为资源添加到工程中来

首先,将包含两个图片文件brick.pngqt-logo.pngimages文件夹,拷贝到项目目录下
image-20260812201819664

然后,在项目名称右键,“Add New …” -> “Qt Resouce File”,创建一个painter.qrc的资源文件

最后,依次点击 “Add Prefix” 和 “Add Files”,添加两张图片作为资源文件,如下:
image-20260812201835415

添加完毕之后,就可以直接在代码中引用这两个图片了!