【QT开发笔记-基础篇】| 第五章 绘图QPainter | 5.7 画笔设置

news2025/1/20 16:28:48

本节对应的视频讲解:B_站_视_频

https://www.bilibili.com/video/BV16W4y1g7dM


经过前面几节课的讲解,学会了绘制点、线、多段线、多边形、矩形、圆角矩形

到这里就可以学习画笔和画刷的设置了,本节先讲解画笔的设置

Qt 中画笔的类是 QPen

QPainter 在绘制时,是有一个默认的画笔的。我们也可以设置一个自定义的画笔给它

可以设置画笔的线宽、颜色、样式、连接、末端等的样式

1. 相关 API

1.1 画笔宽度

// 获取和设置画笔的宽度
int width() const;
void setWidth(int width);

qreal widthF() const;
void setWidthF(qreal width);

1.2 画笔颜色

// 获取和设置画笔的颜色
QColor color() const;
void setColor(const QColor &color);

1.3 样式

// 获取和设置画笔的样式
Qt::PenStyle style() const;
void setStyle(Qt::PenStyle style);

其中,Qt::PenStyle 是一个枚举,取值和效果,如下:

image-20221208171459693


1.4 连接

// 获取和设置画笔的 Join 样式
Qt::PenJoinStyle joinStyle() const;
void setJoinStyle(Qt::PenJoinStyle style)

其中,Qt::PenJoinStyle 是一个枚举,取值和效果,如下:

image-20221208171646290


1.5 末端

// 获取和设置画笔的 Cap 样式
Qt::PenCapStyle capStyle() const;
void setCapStyle(Qt::PenCapStyle style)

其中,Qt::PenCapStyle 是一个枚举,取值和效果,如下:

image-20221208172142556


2. 具体实现

2.1 关联信号槽

为宽度、颜色、样式、连接、末端,这 5 个设置选项,关联信号槽:

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

    // 画笔宽度
    connect(ui->sbPenWidth, SIGNAL(valueChanged(int)), this, SLOT(penChanged()));
    // 画笔颜色
    connect(ui->btnPenColor, SIGNAL(clicked()), this, SLOT(onBtnPenColorClicked()));
    // 画笔样式
    connect(ui->cboPenStyle, SIGNAL(activated(QString)), this, SLOT(penChanged()));
    // 画笔末端
    connect(ui->cboPenCap, SIGNAL(activated(QString)), this, SLOT(penChanged()));
    // 画笔连接
    connect(ui->cboPenJoin, SIGNAL(activated(QString)), this, SLOT(penChanged()));
}

2.2 声明并实现槽函数

首先,在 widget.h 中声明 penChanged 和 onBtnPenColorClicked 这两个槽函数:

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

然后,在 widget.cpp 中实现这两个槽函数:

#include <QColorDialog>

void Widget::onBtnPenColorClicked()
{
    QColor color = QColorDialog::getColor(QColor(255, 0, 0), this, "画笔颜色");

    if ( !color.isValid() ) {
        return;
    }

    // 回显画笔颜色
    QPalette pal = ui->btnPenColor->palette();
    pal.setColor(QPalette::Button, color);
    ui->btnPenColor->setPalette(pal);
    ui->btnPenColor->setAutoFillBackground(true);
    ui->btnPenColor->setFlat(true);

    penChanged();
}

void Widget::penChanged()
{
    // 获取画笔宽度
    int width = ui->sbPenWidth->value();

    // 获取画笔颜色
    QPalette pal = ui->btnPenColor->palette();
    QColor color = pal.color(QPalette::Button);

    int styleIndex = ui->cboPenStyle->currentIndex();
    Qt::PenStyle style = (Qt::PenStyle)ui->cboPenStyle->itemData(styleIndex).toInt();

    int capIndex = ui->cboPenCap->currentIndex();
    Qt::PenCapStyle cap = Qt::PenCapStyle(ui->cboPenCap->itemData(capIndex).toInt());

    int joinIndex = ui->cboPenJoin->currentIndex();
    Qt::PenJoinStyle join = Qt::PenJoinStyle(ui->cboPenJoin->itemData(joinIndex).toInt());

    ui->paintWidget->setPen(QPen(color, width, style, cap, join));
}

2.3 实现 setPen 函数

在 widget.cpp 中的 penChanged 槽函数中,最终调用 PaintWidget 类中的 setPen 来设置画笔,完成绘制。

首先,在 PaintWidget.h 中声明 setPen 函数,并定义一个成员变量 mPen,如下:

#include <QPen>

class PaintWidget : public QWidget
{
public slots:
    void setPen(const QPen &pen);

private:
    QPen mPen;
};

然后,在 PaintWidget.cpp 中,实现 setPen 函数:

void PaintWidget::setPen(const QPen &pen)
{
    this->mPen = pen;
    update();
}

最后,由于上边调用了 update 之后,系统会自动调用 paintEvent

因此,在 paintEvent 中需要将画笔设置给 QPainter,来完成绘制

void PaintWidget::paintEvent(QPaintEvent *event)
{

    QPainter painter(this);
    painter.setPen(mPen);
}

这样就完成了画笔的设置


2.4 优化

修改 widget.cpp,设置画笔的默认颜色为红色

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

    // 6. 初始化
    // 回显画笔颜色
    QPalette pal = ui->btnPenColor->palette();
    pal.setColor(QPalette::Button, QColor(255, 0, 0));
    ui->btnPenColor->setPalette(pal);
    ui->btnPenColor->setAutoFillBackground(true);
    ui->btnPenColor->setFlat(true);
	
    penChanged();
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/105952.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

正则表达式验证合集

1.定义封装的公共js 在src下定义一个util文件夹&#xff0c;并且定义个validate.js(当然你想取什么名字就什么名字哈哈哈哈) 2.上代码 //邮箱 /*** 邮箱* param {*} s*/ export function isEmail(s) {return /^([a-zA-Z0-9_-])([a-zA-Z0-9_-])((.[a-zA-Z0-9_-]{2,3}){1,2}…

基于FPGA的 矩阵键盘按键识别 【原理+源码】

目录 引言 原理阐述 实现方法 源码分享 板级调试演示 引言 最近了解了矩阵键盘扫描的原理&#xff0c;动手实现了一下&#xff0c;在这里做一个简单的总结。 原理阐述 矩阵键盘典型电路&#xff1a; FPGA的应用电路&#xff1a; 其中&#xff0c;行信号为FPGA输入信号&a…

企业从哪里开始构建弹性 IT 基础架构

混合工作模式扩大了工作范围&#xff0c;增加了 IT 团队的负担&#xff0c;因为他们需要在面对增加的攻击面时保持弹性。入侵企业的 IT 基础架构只需要一个受损的身份。 什么是企业标识&#xff1f; 这些是用户名、密码、网络、端点、应用程序等&#xff0c;充当业务敏感信息…

CheatEngine教程-官方9关

文章目录第一步&#xff1a;环境准备&#xff0c;下载并安装CE第二关&#xff1a;精确扫描数值第三关&#xff1a;未知数值扫描第四关&#xff1a;浮点数的扫描第五关&#xff1a;代码替换功能第六关&#xff1a;关于指针第七关&#xff1a;简单代码注入第八关&#xff1a;查找…

力扣(LeetCode)173. 二叉搜索树迭代器(C++)

设计 根据二叉树的中序遍历的迭代解法&#xff0c;稍改代码&#xff0c;就是本题的解法。 初始化 : 传入了根结点&#xff0c;根据迭代思路&#xff0c;将结点的左链依次入栈。 nextnextnext : 栈顶结点就是所求。根据迭代思路&#xff0c;当前结点要变成栈顶结点的右儿子。由…

Openlayers:自定义坐标系

Openlayers天然支持EPSG:4326(WGS1984地理坐标系)、EPSG:3857(Web墨卡托投影坐标系,即:将WGS84坐标系投影到正方形,南北投影范围为[-85.051129,+85.051129])。同时,Openlayers也支持开发者自定义坐标系。那么具体如何操作呢? 相关的API ol.proj.projection ol.proj.…

Android设计模式详解之工厂方法模式

前言 工厂方式模式是创建型设计模式&#xff1b; 定义&#xff1a;定义一个用于创建对象的接口&#xff0c;让子类决定实例化哪个类。 使用场景&#xff1a;在任何需要生成复杂对象的地方&#xff0c;都可以使用工厂方法模式。复杂对象适合使用工厂模式&#xff0c;用new就可…

【Java|golang】1753. 移除石子的最大得分

你正在玩一个单人游戏&#xff0c;面前放置着大小分别为 a​​​​​​、b 和 c​​​​​​ 的 三堆 石子。 每回合你都要从两个 不同的非空堆 中取出一颗石子&#xff0c;并在得分上加 1 分。当存在 两个或更多 的空堆时&#xff0c;游戏停止。 给你三个整数 a 、b 和 c &a…

攻防世界新手练习区——unseping

目录 知识点 解读题目源码&#xff1a; 命令绕过 知识点 PHP代码审计PHP序列化和反序列化PHP中魔术方法命令执行绕过方式 解读题目源码&#xff1a; 这道题首先一上来就是一段PHP代码&#xff0c;其中看到unserialize()就知道考的是反序列化&#xff0c;但是我们再往上看代码…

rust编程-struct结构体(chapter 5.1 结构体定义和实例化)

目录 1. 结构体定义和实例化 1.1 struct介绍 1.2 使用字段简写进行实例化 1.3 从其它对象实例化新结构体对象 1.4 使用无命名字段的struct类型 1.5 没有任何字段的structs结构体 1.6 结构体字段的值所有权 结构(struct)是一种自定义数据类型&#xff0c;可以将多个相关类…

存量时代下 用低代码开发平台提升你的CEM

随着人口及流量红利的逐步见顶&#xff0c;我国经济从增量市场迈入存量市场。在充分竞争的存量市场环境下&#xff0c;传统的初级竞争模式无法支撑产业的发展&#xff0c;相反还会让企业陷入持续烧钱的恶性循环中&#xff0c;获客难度的提升无疑加速了体验经济时代的到来&#…

modbus介绍、环境搭建测试与qt下串口/Tcp的demo工程测试

一、modbus的介绍 1.简介 Modbus是一种串行通信协议&#xff0c;于1979年为使用可编程逻辑控制器&#xff08;PLC&#xff09;通信而发表。Modbus已经成为工业领域通信协议的业界标准&#xff08;De facto&#xff09;&#xff0c;并且现在是工业电子设备之间常用的连接方式&a…

SSM框架项目实战-CRM(客户关系管理1)

目录​​​​​​​ 1 项目介绍 1.1 crm简介 1.2 业务流程 1.3 crm的技术架构 2 物理模型设计 2.1 crm表的结构 2.2 主键字段 2.2 外键字段 2.3 关于日期和时间的字段 3 搭建项目环境 3.1 添加maven依赖 3.2 添加配置文件 3.3 添加页面和静态资源 ​编辑 4 首页…

超标量处理器设计——第九章_执行

参考《超标量处理器》姚永斌著 文章目录超标量处理器设计——第九章_执行9.1 概述9.2 FU类型9.2.1 ALU9.2.2 AGU9.2.3 BRU条件码分支正确性检查9.3 旁路网络9.3.1 简单设计的旁路网络9.3.2 复杂设计的旁路网络9.4 操作数的选择9.5 Cluster9.5.1 Cluster IQ9.5.2 Cluster Bypass…

Python 自动化测试(四):数据驱动

在实际的测试工作中&#xff0c;通常需要对多组不同的输入数据&#xff0c;进行同样的测试操作步骤&#xff0c;以验证我们的软件质量。这种测试&#xff0c;在功能测试中非常耗费人力物力&#xff0c;但是在自动化中&#xff0c;却比较好实现&#xff0c;只要实现了测试操作步…

前端基础_fillStyle和strokeStyle属性

fillStyle和strokeStyle属性 在前面的章节&#xff0c;在绘制图形时只用到默认的线条和填充样式。而在本节中将会探讨canvas全部的可选项&#xff0c;来绘制出更加吸引人的内容。如果想要给图形上色&#xff0c;有两个重要的属性可以做到&#xff1a;fillStyle和strokeStyle。…

社科院与杜兰大学金融管理硕士12门课程简介,其中有你心心念念的课程吗

当我们考量一个项目是否符合自身时&#xff0c;首先对课程设置是有要求的&#xff0c;课程设置是一个项目的灵魂所在&#xff0c;优质的课程与强大的师资更能体现项目的与众不同&#xff0c;下面一起去了解社科院与杜兰大学金融管理硕士项目12门必修课程概要&#xff0c;看看其…

【Java】java | maven | nexus私服 | maven私服 | docker安装nexus私服

一、说明 1、centos 7 2、docker 3、idea的maven项目 二、安装 1、拉取镜像 docker pull sonatype/nexus3:latest 2、创建映射目录并授权 mkdir /home/nexus/nexus-data && chown -R 200 /home/nexus/nexus-data 3、启动镜像 docker run -d -p 8081:8081 -p 8082:8082…

antd+vue——实现按钮始终固定在顶部,且根据权限的不同控制按钮组件的显示与隐藏——技能提升

最近在写后台管理系统&#xff0c;遇到一个小功能&#xff0c;就是一个按钮组件集合。 之前写过一篇文章&#xff0c;是关于按钮集合固定到页面顶部的文章。vue——实现页面滚动时&#xff0c;dom固定在顶部——基础积累 原理就是&#xff1a;监听页面的滚动&#xff0c;如果…

QT Qmake OpenGL osg笔记

文章目录概述QT修改样式qmake概述库引用和库路径指定QT创建动态库和使用小例子写动态库用动态库参考资料附录概述 需要先安装osg&#xff0c;然后再编译安装osgQOpenGL的插件。 其中&#xff0c;osgQOpenGL是OSG嵌入到qt中的一种实现方式&#xff0c;换言之&#xff0c;能够支…