往期回顾
【QT进阶】Qt线程与并发之QtConcurrent的简单介绍-优快云博客
Qt绘图与图形视图之常见图形、路径、文字、图片的绘制介绍
一、最终效果
实现常见18种图形、路径、文字、图片的绘制,点击左侧对应图形,右侧会自动绘制
二、主要设计实现
1、主要思路
看ui界面,主要分为两个类,一个QListWidget设置左边列表模式,虽然但是,这里没有用这个,而是改用了对象树;另一个就是很基础的一个widget窗口类,用来做画板,放绘制的图案
2、各个类具体实现
2.1、darwType.h
先设置好有哪些绘图类型,方便一会区分调用
#pragma once
enum class DRAW_TYPE
{
point,
multipoints,
line,
arc,
rect,
roundrect,
chord,
ellipse,
polygon,
polyline,
ConvexPloygon,
lines,
path,
pie,
image,
pixmap,
draw_text,
draw_erase,
draw_fillpath,
draw_fillrect
};
2.2、Widget
2.2.1、初始化对象树
初始化对象树,设置为不可编辑,并创建水平布局搭建出整体框架
Widget::Widget(QWidget* parent)
: QWidget(parent)
{
setWindowTitle(u8"draw all");
QHBoxLayout* pHLay = new QHBoxLayout(this);
m_pLeftTree = new QTreeView(this); //对象树
m_pLeftTree->setEditTriggers(QAbstractItemView::NoEditTriggers); //设置不可编辑
m_pLeftTree->setFixedWidth(300);
m_pPaintWidget = new CPaintWidget(this);
pHLay->addWidget(m_pLeftTree);
pHLay->addWidget(m_pPaintWidget);
treeView();
}
2.2.2、设置对象树的ui界面
设置对象树的ui界面,搭建出上图左边的样式,这里用了一个QStandardItemModel和QStandardItem,注意看其设置方式:
void Widget::treeView()
{
m_pLeftTree->setFrameShape(QFrame::NoFrame);
QStandardItemModel* model = new QStandardItemModel(m_pLeftTree);
//设置水平表头标签为"draw all"。
model->setHorizontalHeaderLabels(QStringList() << "draw all");
QStandardItem* pParentItem = NULL;
QStandardItem* pChildItem = NULL;
// 点
pParentItem = new QStandardItem(QIcon(":/resources/point.png"), "draw ponit");
model->appendRow(pParentItem);
pChildItem = new QStandardItem(QIcon(":/resources/point.png"), "point");
pParentItem->appendRow(pChildItem);
pChildItem = new QStandardItem(QIcon(":/resources/multipoints.png"), "multipoints");
pParentItem->appendRow(pChildItem);
m_pLeftTree->setModel(model);
connect(m_pLeftTree, &QAbstractItemView::clicked, this, &Widget::treeViewExpand);
}
2.2.3、实现点击item绘制对应图形
获取每个item的data值,并转为QString类型,通过data值判断属于哪个类型,从而决定当用户点击后右边窗口绘画哪个图案并及时更新
void Widget::treeViewExpand(const QModelIndex& index)
{
//点击的item的下标的数据值转为QString类型,然后拿去判断
//根据数据值设置对应的窗口显示类型,并更新
QString text = index.data().toString();
if (text.compare("point") == 0)
{
m_pPaintWidget->setDrawType(DRAW_TYPE::point);
m_pPaintWidget->update(); //不更新就不会立即显示
}
else if (text.compare("multipoints") == 0)
{
m_pPaintWidget->setDrawType(DRAW_TYPE::multipoints);
m_pPaintWidget->update();
}
}
2.3、CPaintWidget
2.3.1、初始化界面
初始化界面并设置初始显示图
CPaintWidget::CPaintWidget(QWidget* p)
:QWidget(p)
{
this->setMinimumSize(800, 600);
//默认设置为polygon,所以运行程序时最开始显示的就是polygon
m_drawType = DRAW_TYPE::polygon;
}
2.3.2、重写paintEvent方法
重写paintEvent方法,根据传入的type值来决定调用哪个绘图函数
void CPaintWidget::paintEvent(QPaintEvent* event)
{
//宽高设置为绘制图案窗口的宽高
W = this->width();
H = this->height();
//根据传入的类型判断该调用哪个图案绘画函数
switch (m_drawType)
{
case DRAW_TYPE::point:
draw_point();
break;
case DRAW_TYPE::multipoints:
draw_multipoints();
break;
default:
break;
}
}
2.3.3、实现绘图函数
针对每一个图案,实现其绘图函数
//画点
void CPaintWidget::draw_point()
{
QPainter painter(this);
QPen pen;
pen.setWidth(10);
pen.setColor(Qt::red);
pen.setStyle(Qt::SolidLine);
painter.setPen(pen);
painter.drawPoint(QPoint(W / 2, H / 2)); //点的位置坐标,在正中央
}
//画多个点
void CPaintWidget::draw_multipoints()
{
QPainter painter(this);
QPen pen;
pen.setWidth(10);
pen.setColor(Qt::blue);
pen.setStyle(Qt::SolidLine);
painter.setPen(pen);
// 画很多点,用数组
QPoint points[] = {
QPoint(5 * W / 12,H / 4),
QPoint(3 * W / 4, 5 * H / 12),
QPoint(2 * W / 4, 5 * H / 12) };
painter.drawPoints(points, 3); //数组名+点个数
}
3、主要知识点:QPen和QBrush
这里只是简单介绍,具体的大家可以多看看Qt助手,非常详细。
3.1、QPen
QPen用于定义绘制线条时的样式,包括线条颜色、线条宽度、线条风格等。
可以通过QPen的构造函数或者设置函数来设置画笔的属性。
例如,可以通过setStyle()设置线条的风格,通过setWidth()设置线条的宽度,通过setColor()设置线条的颜色等。
3.2、QBrush
QBrush用于定义填充区域的样式,包括填充颜色、填充纹理等。
可以通过QBrush的构造函数或者设置函数来设置填充样式
例如,可以通过setColor()设置填充的颜色,通过setStyle()设置填充的样式,如实色填充、纹理填充等。
3.3、常用思路
在绘图过程中,通常会使用QPen来设置绘制线条的样式,而使用QBrush来设置填充区域的样式。通过合理地组合QPen和QBrush的属性,可以实现各种绘图效果,如绘制带有不同线条风格和填充样式的图形元素。
以上就是Qt里常见图形、路径、文字、图片绘制的简单介绍
都看到这里了,点个赞再走呗朋友~
加油吧,预祝大家变得更强!