基本图形绘制
QPainter绘制基本图形
**注意:**QPainter画弧度所使用的角度值,是以1/16°为单位的,在画弧度的时候1°用16表示。
**例如:**30°——30 x 16
兼容模式QPainer::CompositionMode
**例如:**可用于图片叠加,达到你想要的效果。
QPainterPath绘制简单图形
QPainterPath为QPainter类提供一个存储容器,里面包含了所要绘制的内容的集合及绘制顺序,如长方形、多边形、曲线等各种任意图形。当需要绘制此预先存储在QPainterPath对象中的内容时,只需调用QPainter类的DrawPath()即可,如addRect()加入一个方形,addEllipse加入一个椭圆形,addText()加入文本。
画笔笔刷风格
画笔风格——Qt::PenStyle
笔帽风格——Qt::PenCapStyle
Qt::SquareCap 方形线端,不覆盖线的端点
Qt::FlatCap 方形线端,覆盖线的端点,并以线框一半向外延伸
Qt::RoundCap 圆线端
连接点——Qt::PenJoinStyle
Qt::BevelJoin 两条线相汇形成方形连接
Qt::MiterJoin 两条线相汇形成尖角连接
Qt::RoundJoin两条线相汇形成圆角连接
填充模式——Qt::FillRule
- Qt::OddEventFill填充规则:从图形中某一点画一条水平线到图形外,若这条线与图形边线的交点为奇数则说明此点位与图形的内部;若交点为偶数则此点在图形的外部。
- Qt::WindingFill填充规则:从图形中某一点画一条水平线到图形外,每个交点外边线方向可能向上、向下、方向相反的相互抵消,若结果不为0表示此点在图形内,若为0则在图形外。其中边线的方向是由QPainterPath创建时根据描述的顺序决定的,如果采用addRect()或addPolygon()等函数加入的图形默认为顺时针方向。
铺展效果——Qt::Gradient::Type
QGradient::PadSpread :默认风格
QGradient::RepeatSpread:线性渐变
QGradient::ReflectSpread:圆形渐变
画刷风格——Qt::BrushStyle
示例
mainwidget.h
#ifndef MAINWIDGET_H
#define MAINWIDGET_H
#include <QWidget>
#include<paintarea.h>
#include<QLabel>
#include<QComboBox>
#include<QSpinBox>
#include<QPushButton>
#include<QGridLayout>
class MainWidget : public QWidget
{
Q_OBJECT
public:
MainWidget(QWidget *parent = 0);
~MainWidget();
void initWidgets();
private slots:
void ShowShape(int value);
void ShowPenColor();
void ShowPenWidth(int value);
void ShowPenStyle(int value);
void ShowPenCap(int value);
void ShowPenJoin(int value);
void ShowFillRule(int value);
void ShowSpreadStyle(int value);
void ShowBrushColor();
void ShowBrush(int value);
private:
PaintArea* m_paintArea; //绘图区域
QLabel* m_shapeLabel ; //形状
QComboBox* m_shapeCombox;
QLabel* m_penWidthLabel;//线宽
QSpinBox *m_penWithSpinBox;
QLabel* m_penColorLabel;//画笔颜色
QFrame* m_penColorFrame;
QPushButton* m_penColorBtn;//确认选择画笔颜色按钮
QLabel* m_penStyleLabel;//画笔风格
QComboBox* m_penStyleComboBox;
QLabel* m_penCapLabel;//笔帽风格
QComboBox* m_penCapComboBox;
QLabel* m_penJoinLabel;//画笔连接点
QComboBox* m_penJoinComboBox;
QLabel* m_fillRuleLabel;//填充模式
QComboBox* m_fillRuleComboBox;
QLabel* m_spreadLabel;//铺展效果
QComboBox* m_spreadComboBox;
QGradient::Spread m_spread;
QLabel* m_brushColorLabel;//画刷颜色
QFrame* m_brushColorFrame;
QPushButton* m_brushColorBtn;
QLabel* m_brushStyleLabel;//画刷风格
QComboBox* m_brushStytleComboBox;
QGridLayout* m_rightLayout;
};
#endif // MAINWIDGET_H
mainwidget.cpp
#include "mainwidget.h"
#include<QColorDialog>
MainWidget::MainWidget(QWidget *parent)
: QWidget(parent)
{
initWidgets();
}
MainWidget::~MainWidget()
{
}
//初始化部件
void MainWidget::initWidgets()
{
m_paintArea = new PaintArea;
m_shapeLabel = new QLabel(tr("形状"));
m_shapeCombox = new QComboBox;
m_shapeCombox->addItem(tr("Line"),PaintArea::Line);
m_shapeCombox->addItem(tr("Rectangle"),PaintArea::Rectangle);
m_shapeCombox->addItem(tr("RoundedRect"),PaintArea::Rectangle);
m_shapeCombox->addItem(tr("Ellipse"),PaintArea::Ellipse);
m_shapeCombox->addItem(tr("Polygon"),PaintArea::Polygon);
m_shapeCombox->addItem(tr("Polyline"),PaintArea::Polyline);
m_shapeCombox->addItem(tr("Points"),PaintArea::Points);
m_shapeCombox->addItem(tr("Arc"),PaintArea::Arc);
m_shapeCombox->addItem(tr("Path"),PaintArea::Path);
m_shapeCombox->addItem(tr("Text"),PaintArea::Text);
m_shapeCombox->addItem(tr("Pixmap"),PaintArea::Pixmap);
connect(m_shapeCombox,SIGNAL(activated(int)),this,SLOT(ShowShape(int)));
m_penColorLabel = new QLabel(tr("画笔颜色"));
m_penColorFrame = new QFrame;
m_penColorFrame->setFrameStyle(QFrame::Panel | QFrame::Sunken);//设置风格
m_penColorFrame->setAutoFillBackground(true);
m_penColorFrame->setPalette(QPalette(Qt::black));
m_penColorBtn = new QPushButton(tr("更改"));
connect(m_penColorBtn,SIGNAL(clicked(bool)),this,SLOT(ShowPenColor()));
m_penWidthLabel = new QLabel(tr("画线宽度"));
m_penWithSpinBox = new QSpinBox;
m_penWithSpinBox->setRange(1,20);
connect(m_penWithSpinBox,SIGNAL( valueChanged(int)),SLOT(ShowPenWidth(int)));
m_penStyleLabel = new QLabel(tr("画笔风格"));
m_penStyleComboBox = new QComboBox;
m_penStyleComboBox->addItem(tr("SolidLine"),static_cast<int>(Qt::SolidLine ));
m_penStyleComboBox->addItem(tr("DashLine"),static_cast<int>(Qt::DashLine));
m_penStyleComboBox->addItem(tr("DotLine"),static_cast<int>(Qt::DotLine));
m_penStyleComboBox->addItem(tr("DashDotLine"),static_cast<int>(Qt::DashDotLine ));
m_penStyleComboBox->addItem(tr("DashDotDotLine"),static_cast<int>(Qt::DashDotDotLine ));
m_penStyleComboBox->addItem(tr("CustomDashLine"),static_cast<int>(Qt::CustomDashLine));
connect(m_penStyleComboBox,SIGNAL(activated(int)),this,SLOT(ShowPenStyle(int)));
m_penCapLabel = new QLabel(tr("画笔笔帽"));
m_penCapComboBox = new QComboBox;
m_penCapComboBox->addItem(tr("SquareCap"),Qt::SquareCap);
m_penCapComboBox->addItem(tr("FlatCap"),Qt::FlatCap);
m_penCapComboBox->addItem(tr("RoundCap"),Qt::RoundCap);
connect(m_penCapComboBox,SIGNAL(activated(int)),this,SLOT(ShowPenCap(int)));
m_penJoinLabel = new QLabel(tr("画笔连接点"));
m_penJoinComboBox = new QComboBox;
m_penJoinComboBox->addItem(tr("BevelJoin"),Qt::BevelJoin);
m_penJoinComboBox->addItem(tr("MiterJoin"),Qt::MiterJoin);
m_penJoinComboBox->addItem(tr("RoundJoin"),Qt::RoundJoin);
connect(m_penJoinComboBox,SIGNAL(activated(int)),this,SLOT(ShowPenJoin(int)));
m_fillRuleLabel = new QLabel(tr("填充模式"));
m_fillRuleComboBox = new QComboBox;
m_fillRuleComboBox->addItem(tr("Odd Even"),Qt::OddEvenFill);
m_fillRuleComboBox->addItem(tr("Winding"),Qt::WindingFill);
connect(m_fillRuleComboBox,SIGNAL(activated(int)),this,SLOT(ShowFillRule(int)));
m_spreadLabel = new QLabel(tr("铺展效果"));
m_spreadComboBox = new QComboBox;
m_spreadComboBox->addItem(tr("PadStread"),QGradient::PadSpread);
m_spreadComboBox->addItem(tr("RepeatSpread"),QGradient::RepeatSpread);
m_spreadComboBox->addItem(tr("ReflectSpread"),QGradient::ReflectSpread);
connect(m_spreadComboBox,SIGNAL(activated(int)),this,SLOT(ShowSpreadStyle(int)));
m_brushColorLabel = new QLabel(tr("画刷颜色"));
m_brushColorFrame = new QFrame;
m_brushColorFrame->setFrameStyle(QFrame::Panel | QFrame::Sunken);
m_brushColorFrame->setAutoFillBackground(true);
m_brushColorFrame->setPalette(QPalette(Qt::green));
m_brushColorBtn = new QPushButton(tr("更改"));
connect(m_brushColorBtn,SIGNAL(clicked()),this,SLOT(ShowBrushColor()) );
m_brushStyleLabel = new QLabel(tr("画刷风格"));
m_brushStytleComboBox = new QComboBox;
m_brushStytleComboBox->addItem(tr("SolidPattern"),static_cast<int>(Qt::SolidPattern));
m_brushStytleComboBox->addItem(tr("Dense1Pattern"),static_cast<int>(Qt::Dense1Pattern));
m_brushStytleComboBox->addItem(tr("Dense2Pattern"),static_cast<int>(Qt::Dense2Pattern));
m_brushStytleComboBox->addItem(tr("Dense3Pattern"),static_cast<int>(Qt::Dense3Pattern));
m_brushStytleComboBox->addItem(tr("Dense4Pattern"),static_cast<int>(Qt::Dense4Pattern));
m_brushStytleComboBox->addItem(tr("Dense5Pattern"),static_cast<int>(Qt::Dense5Pattern));
m_brushStytleComboBox->addItem(tr("Dense6Pattern"),static_cast<int>(Qt::Dense6Pattern));
m_brushStytleComboBox->addItem(tr("Dense7Pattern"),static_cast<int>(Qt::Dense7Pattern));
m_brushStytleComboBox->addItem(tr("HorPattern"),static_cast<int>(Qt::HorPattern));
m_brushStytleComboBox->addItem(tr("VerPattern"),static_cast<int>(Qt::VerPattern));
m_brushStytleComboBox->addItem(tr("CrossPattern"),static_cast<int>(Qt::CrossPattern));
m_brushStytleComboBox->addItem(tr("BDiagPattern"),static_cast<int>(Qt::BDiagPattern));
m_brushStytleComboBox->addItem(tr("FDiagPattern"),static_cast<int>(Qt::FDiagPattern));
m_brushStytleComboBox->addItem(tr("DiagCrossPattern"),static_cast<int>(Qt::DiagCrossPattern));
m_brushStytleComboBox->addItem(tr("LinearGradientPattern"),static_cast<int>(Qt::LinearGradientPattern));
m_brushStytleComboBox->addItem(tr("ConicalGradientPattern"),static_cast<int>(Qt::ConicalGradientPattern));
m_brushStytleComboBox->addItem(tr("RadialGradientPattern"),static_cast<int>(Qt::RadialGradientPattern));
m_brushStytleComboBox->addItem(tr("TexturePattern"),static_cast<int>(Qt::TexturePattern));
connect(m_brushStytleComboBox,SIGNAL(activated(int)),this,SLOT(ShowBrush(int)));
//添加布局
m_rightLayout = new QGridLayout;
m_rightLayout->addWidget(m_shapeLabel,0,0);
m_rightLayout->addWidget(m_shapeCombox,0,1);
m_rightLayout->addWidget(m_penColorLabel,1,0);
m_rightLayout->addWidget(m_penColorFrame,1,1);
m_rightLayout->addWidget(m_penColorBtn,1,2);
m_rightLayout->addWidget(m_penWidthLabel,2,0);
m_rightLayout->addWidget(m_penWithSpinBox,2,1);
m_rightLayout->addWidget(m_penStyleLabel,3,0);
m_rightLayout->addWidget(m_penStyleComboBox,3,1);
m_rightLayout->addWidget(m_penCapLabel,4,0);
m_rightLayout->addWidget(m_penCapComboBox,4,1);
m_rightLayout->addWidget(m_penJoinLabel,5,0);
m_rightLayout->addWidget(m_penJoinComboBox,5,1);
m_rightLayout->addWidget(m_fillRuleLabel,6,0);
m_rightLayout->addWidget(m_fillRuleComboBox,6,1);
m_rightLayout->addWidget(m_spreadLabel,7,0);
m_rightLayout->addWidget(m_spreadComboBox,7,1);
m_rightLayout->addWidget(m_brushColorLabel,8,0);
m_rightLayout->addWidget(m_brushColorFrame,8,1);
m_rightLayout->addWidget(m_brushColorBtn,8,2);
m_rightLayout->addWidget(m_brushStyleLabel,9,0);
m_rightLayout->addWidget(m_brushStytleComboBox,9,1);
QHBoxLayout* mainLayout = new QHBoxLayout(this);
mainLayout->addWidget(m_paintArea);
mainLayout->addLayout(m_rightLayout);
ShowShape(m_shapeCombox->currentIndex());
}
//变更每项设置后,更新图像
void MainWidget::ShowShape(int value)
{
PaintArea::Shape shape =PaintArea::Shape (m_shapeCombox->itemData(value).toInt());//获取用户选择的形状
m_paintArea->setShape(shape);
}
void MainWidget::ShowPenColor()
{
QColor color = QColorDialog::getColor(Qt::black);
m_penColorFrame->setPalette(QPalette(color));
int value = m_penWithSpinBox->value();
int styleIndex = m_penStyleComboBox->currentIndex();
Qt::PenStyle style = Qt::PenStyle(m_penStyleComboBox->itemData(styleIndex).toInt());
int capIndex = m_penCapComboBox->currentIndex();
Qt::PenCapStyle cap = Qt::PenCapStyle(m_penCapComboBox->itemData(capIndex).toInt());
int joinIndex = m_penJoinComboBox->currentIndex();
Qt::PenJoinStyle join = Qt::PenJoinStyle(m_penJoinComboBox->itemData(joinIndex).toInt());
//将当前画笔的各个参数传递-设置
m_paintArea->setPen(QPen(color,value,style,cap,join));
}
void MainWidget::ShowPenWidth(int value)
{
QColor color = m_penColorFrame->palette().color(QPalette::Window);//获取颜色框中关于窗体的颜色值
m_penColorFrame->setPalette(QPalette(color));
int penWidth =value;
int styleIndex = m_penStyleComboBox->currentIndex();
Qt::PenStyle style = Qt::PenStyle(m_penStyleComboBox->itemData(styleIndex).toInt());
int capIndex = m_penCapComboBox->currentIndex();
Qt::PenCapStyle cap = Qt::PenCapStyle(m_penCapComboBox->itemData(capIndex).toInt());
int joinIndex = m_penJoinComboBox->currentIndex();
Qt::PenJoinStyle join = Qt::PenJoinStyle(m_penJoinComboBox->itemData(joinIndex).toInt());
//将当前画笔的各个参数传递-设置
m_paintArea->setPen(QPen(color,penWidth,style,cap,join));
}
void MainWidget::ShowPenStyle(int value)
{
QColor color = m_penColorFrame->palette().color(QPalette::Window);//获取颜色框中关于窗体的颜色值
m_penColorFrame->setPalette(QPalette(color));
int penWidth = m_penWithSpinBox->value();
Qt::PenStyle style = Qt::PenStyle(m_penStyleComboBox->itemData(value).toInt());
if(style == Qt::CustomDashLine)//如果是自定义的
{
QVector<qreal> dashes;
qreal space = 4;
dashes<<1<<space<<2<<space<<3<<space<<4<<space;
m_paintArea->m_pen.setDashPattern(dashes);
m_paintArea->update();
}
else
{
int capIndex = m_penCapComboBox->currentIndex();
Qt::PenCapStyle cap = Qt::PenCapStyle(m_penCapComboBox->itemData(capIndex).toInt());
int joinIndex = m_penJoinComboBox->currentIndex();
Qt::PenJoinStyle join = Qt::PenJoinStyle(m_penJoinComboBox->itemData(joinIndex).toInt());
//将当前画笔的各个参数传递-设置
m_paintArea->setPen(QPen(color,penWidth,style,cap,join));
}
}
void MainWidget::ShowPenCap(int value)
{
QColor color = m_penColorFrame->palette().color(QPalette::Window);//获取颜色框中关于窗体的颜色值
m_penColorFrame->setPalette(QPalette(color));
int penWidth =m_penWithSpinBox->value();
int styleIndex = m_penStyleComboBox->currentIndex();
Qt::PenStyle style = Qt::PenStyle(m_penStyleComboBox->itemData(styleIndex).toInt());
// int capIndex = m_penCapComboBox->currentIndex();
Qt::PenCapStyle cap = Qt::PenCapStyle(m_penCapComboBox->itemData(value).toInt());
int joinIndex = m_penJoinComboBox->currentIndex();
Qt::PenJoinStyle join = Qt::PenJoinStyle(m_penJoinComboBox->itemData(joinIndex).toInt());
//将当前画笔的各个参数传递-设置
m_paintArea->setPen(QPen(color,penWidth,style,cap,join));
}
void MainWidget::ShowPenJoin(int value)
{
QColor color = m_penColorFrame->palette().color(QPalette::Window);//获取颜色框中关于窗体的颜色值
m_penColorFrame->setPalette(QPalette(color));
int penWidth =m_penWithSpinBox->value();
int styleIndex = m_penStyleComboBox->currentIndex();
Qt::PenStyle style = Qt::PenStyle(m_penStyleComboBox->itemData(styleIndex).toInt());
int capIndex = m_penCapComboBox->currentIndex();
Qt::PenCapStyle cap = Qt::PenCapStyle(m_penCapComboBox->itemData(capIndex).toInt());
// int joinIndex = m_penJoinComboBox->currentIndex();
Qt::PenJoinStyle join = Qt::PenJoinStyle(m_penJoinComboBox->itemData(value).toInt());
//将当前画笔的各个参数传递-设置
m_paintArea->setPen(QPen(color,penWidth,style,cap,join));
}
void MainWidget::ShowFillRule(int value)
{
Qt::FillRule rule = Qt::FillRule(value);
m_paintArea->setFillRule(rule);
}
void MainWidget::ShowSpreadStyle(int value)
{
m_spread = QGradient::Spread(value);
}
void MainWidget::ShowBrushColor()
{
QColor color = QColorDialog::getColor(Qt::green);
m_brushColorFrame->setPalette(QPalette(color));
ShowBrush(m_brushStytleComboBox->currentIndex());
}
void MainWidget::ShowBrush(int value)
{
QColor color = m_brushColorFrame->palette().color(QPalette::Window);
int brush = m_brushStytleComboBox->itemData(value).toInt();
Qt::BrushStyle style = Qt::BrushStyle(brush);
//线性渐变
if(style == Qt::LinearGradientPattern)
{
//指定线性渐变的区域
QLinearGradient lineGradient(0,0,400,400);
//指定某个位置的渐变色,pos取值范围0~1
lineGradient.setColorAt(0.0,Qt::white);
lineGradient.setColorAt(0.2,color);
lineGradient.setColorAt(1.0,Qt::black);
lineGradient.setSpread(m_spread);
m_paintArea->setBrush(lineGradient);
}
//环形渲染
else if(style == Qt::RadialGradientPattern)
{
//中心坐标,半径长度,焦点坐标,如果需要对称,则中心坐标和焦点坐标保持一致
QRadialGradient radiaGrdient(200,200,150,200,200);
radiaGrdient.setColorAt(0.0,Qt::white);
radiaGrdient.setColorAt(0.2,color);
radiaGrdient.setColorAt(1.0,Qt::black);
m_paintArea->setBrush(radiaGrdient);
}
//弧度渲染
else if(style == Qt::ConicalGradientPattern)
{
//中心坐标,角度
QConicalGradient conicaoGradient(200,200,30);
conicaoGradient.setColorAt(0.0,Qt::white);
conicaoGradient.setColorAt(0.2,color);
conicaoGradient.setColorAt(1.0,Qt::black);
m_paintArea->setBrush(conicaoGradient);
}
else if(style == Qt::TexturePattern)
{
m_paintArea->setBrush(QBrush(QPixmap("test1.jpg")));
}
//其他
else
{
m_paintArea->setBrush(QBrush(color,style));
}
}
paintarea.h
#ifndef PAINTAREA_H
#define PAINTAREA_H
#include <QWidget>
#include<QPen>
#include<QBrush>
class PaintArea : public QWidget
{
Q_OBJECT
public:
enum Shape{Line,Rectangle,RoundRect,Ellipse,Polygon,Polyline,Points,Arc,Path,Text,Pixmap};
explicit PaintArea(QWidget *parent = nullptr);
public:
void setShape(Shape shape);
void setPen(QPen pen);
void setBrush(QBrush brush);
void setFillRule(Qt::FillRule rule);
protected:
void paintEvent(QPaintEvent *event)override;
public:
QPen m_pen;
private:
Shape m_shape;
QBrush m_brush;
Qt::FillRule m_fillrule;
signals:
public slots:
};
#endif // PAINTAREA_H
paintarea.cpp
#include "paintarea.h"
#include<QPainter>
PaintArea::PaintArea(QWidget *parent) : QWidget(parent)
{
setPalette(QPalette(Qt::white));
setAutoFillBackground(true);//设置背景自动填充
setFixedSize(400,400);
}
void PaintArea::setShape(PaintArea::Shape shape)
{
m_shape = shape;
update();
}
void PaintArea::setPen(QPen pen)
{
m_pen = pen;
update();
}
void PaintArea::setBrush(QBrush brush)
{
m_brush = brush;
update();
}
void PaintArea::setFillRule(Qt::FillRule rule)
{
m_fillrule = rule;
update();
}
void PaintArea::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
painter.setPen(m_pen);
painter.setBrush(m_brush);
QRect rect(50,100,300,200);//起始位置,宽高
const QPoint points[4]= {
QPoint(150,100),
QPoint(300,150),
QPoint(100,300),
QPoint(100,300)
};
int startAngle = 30 * 16;//1/16
int spanAngle = 120 * 16;
QPainterPath path;
path.addRect(150,150,100,100);
path.moveTo(100,200);
path.cubicTo(300,100,200,200,300,300);
path.cubicTo(100,300,200,200,100,100);
path.setFillRule(m_fillrule);
switch(m_shape)
{
case Line:
painter.drawLine(rect.topLeft(),rect.bottomRight());
break;
case Rectangle:
painter.drawRect(rect);
break;
case RoundRect:
painter.drawRoundRect(rect);
break;
case Ellipse:
painter.drawEllipse(rect);
break;
case Polygon://多边形,默认为4变形
painter.drawPolygon(points,4);
break;
case Polyline:
painter.drawPolyline(points,4);
break;
case Points:
painter.drawPoints(points,4);
break;
case Arc:
painter.drawArc(rect, startAngle,spanAngle);
break;
case Path:
painter.drawPath(path);
break;
case Text:
painter.drawText(rect,Qt::AlignCenter,tr("Hello world!"));
break;
case Pixmap:
painter.drawPixmap(50,100,QPixmap("test1.jpg"));
break;
default:
break;
}
}