当前位置: 首页 > news >正文

《Qt6开发及实例》6-2 Qt6基础图形的绘制

目录

一、绘图框架设计

二、绘图区的实现

2.1 PaintArea类

2.2 PaintArea类讲解

三、主窗口的实现

3.1 MainWidget类

3.2 MainWidget类讲解

3.3 槽函数编写

3.5 其他内容


一、绘图框架设计

界面

两个类

二、绘图区的实现

2.1 PaintArea类

​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);void setShape(Shape);void setPen(QPen);void setBrush(QBrush);void setFileRule(Qt::FillRule);void paintEvent(QPaintEvent *);signals:private:Shape shape;QPen pen;QBrush brush;Qt::FillRule fillRule;
};#endif // PAINTAREA_H

 paintarea.cpp

#include "paintarea.h"
#include <QPainter>
#include <QPainterPath>PaintArea::PaintArea(QWidget *parent) : QWidget(parent)
{//QPalete::Window——通常指窗口部件的背景色;setPalette(QPalette(Qt::white));  //给窗口设置背景图片无效//上面的代码可替换为下面三行//QPalette p = palette();//p.setColor(QPalette::Window, Qt::white);//setPalette(p);setAutoFillBackground(true);setMinimumSize(400, 400);
}//设置形状
void PaintArea::setShape(PaintArea::Shape s)
{shape = s;update();
}// 设置画笔
void PaintArea::setPen(QPen p)
{pen = p;update();
}// 设置画刷
void PaintArea::setBrush(QBrush b)
{brush = b;update();
}// 设置填充模式
void PaintArea::setFileRule(Qt::FillRule rule)
{fillRule = rule;update();
}void PaintArea::paintEvent(QPaintEvent *)
{QPainter p(this);                //新建一个QPainter对象p.setPen(pen);                   //设置QPainter对象的画笔p.setBrush(brush);               //设置QPainter对象的画刷QRect rect(50, 100, 300, 200);   //(a)static const QPoint points[4] =  //(b){QPoint(150, 100),QPoint(300, 150),QPoint(300, 250),QPoint(100, 300)};int startAngle = 30 * 16;        //(c)int spanAngle = 120 * 16;QPainterPath path;               //新建一个QPainterPath对象为路径做准备path.addRect(150, 150, 100, 100);path.moveTo(100, 100);path.cubicTo(300, 100, 200, 200, 300, 300);path.cubicTo(100, 300, 200, 200, 100, 100);path.setFillRule(fillRule);switch (shape)                   //(d){case Line:                   //直线p.drawLine(rect.topLeft(), rect.bottomRight()); break;case Rectangle:              //长方形p.drawRect(rect); break;case RoundRect:              //圆角方形p.drawRoundedRect(rect, 4, 4); break;case Ellipse:                //椭圆形p.drawEllipse(rect); break;case Polygon:                //多边形p.drawPolygon(points, 4); break;case Points:                 //点p.drawPoints(points, 4); break;case Arc:                    //弧p.drawArc(rect, startAngle, spanAngle); break;case Path:                   //路径p.drawPath(path); break;case Text:                   //文字p.drawPolygon(points, 4); break;case DrawPixmap:             //图片p.Pixmap(150, 150, QPixmap("butterfly.png")); break;default: break;}
}

2.2 PaintArea类讲解

(a) 用QPainter画弧形所使用的角度值,是以 1/16° 为单位的,startAngle=30*16 和 spanAngle=120*16 能绘制出下面的图像

(d) QPainter 对象内置了很多函数,能绘制多种图形

(d) QPointerPath 类为 QPointer 类提供了一个存储容器,里面包含了所要绘制的内容的集合及绘制的顺序,我们只需要调用 QPainter 类的 drawPath() 函数即可

QPointer 对象提供了许多函数接口。可以很方便地加入一些规则图形。例如,addRect() 函数加入一个方形,addEllipse() 函数加入一个椭圆形,addText() 函数加入一个字符串,addPolygon() 函数加入一个多边形等。同时,QPainterPath 类还提供了 addPath() 函数,用于加入另一个 QPainter 对象中保存的内容

QPainterPath 对象的当前点自动处在上一部分图形内容的结束点上,若下一部分图形的起点不在此结束点,则需调用 moveTo() 函数将当前点移动到下一部分图形的起点

cubicTo() 函数绘制的是贝塞尔曲线,需要三个点的坐标 cubicTo(c1, c2, endPoint)

​QPainterPath path;

path.moveTo(0,0);

path.lineTo(200, 0);

path.lineTo(200,100);

三、主窗口的实现

3.1 MainWidget类

​mainwidget.h

#ifndef MAINWIDGET_H
#define MAINWIDGET_H#include <QWidget>
#include "paintarea.h"
#include <QLabel>
#include <QComboBox>
#include <QSpinBox>
#include <QPushButton>
#include <QGridLayout>
#include <QGradient>class MainWidget : public QWidget
{Q_OBJECTpublic:MainWidget(QWidget *parent = nullptr);~MainWidget();private:PaintArea *paintArea;QLabel *shapeLabel;QComboBox *shapeComboBox;QLabel *penWidthLabel;QSpinBox *penWidthSpinBox;QLabel *penColorLabel;QFrame *penColorFrame;QPushButton *penColorBtn;QLabel *penStyleLabel;QComboBox *penStyleComboBox;QLabel *penCapLabel;QComboBox *penCapComboBox;QLabel *penJoinLabel;QComboBox *penJoinComboBox;QLabel *fillRuleLabel;QComboBox *fillRuleComboBox;QLabel *spreadLabel;QComboBox *spreadComboBox;QGradient::Spread spread;QLabel *brushStyleLabel;QComboBox *brushStyleComboBox;QLabel *brushColorLabel;QFrame *brushColorFrame;QPushButton *brushColorBtn;QGridLayout *rightLayout;protected slots:void ShowShape(int);void ShowPenWidth(int);void ShowPenColor();void ShowPenStyle(int);void ShowPenCap(int);void ShowPenJoin(int);void ShowSpreadStyle();void ShowFillRule();void ShowBrushColor();void ShowBrush(int);
};
#endif // MAINWIDGET_H

mainwidget.cpp

#include "mainwidget.h"
#include <QColorDialog>MainWidget::MainWidget(QWidget *parent): QWidget(parent)
{paintArea = new PaintArea;shapeLabel = new QLabel(tr("形状:"));                       //形状选择下拉列表框shapeComboBox = new QComboBox;shapeComboBox->addItem(tr("Line"), PaintArea::Line);        //(a)shapeComboBox->addItem(tr("Rectangle"), PaintArea::Rectangle);shapeComboBox->addItem(tr("RoundedRect"), PaintArea::RoundRect);shapeComboBox->addItem(tr("Ellipse"), PaintArea::Ellipse);shapeComboBox->addItem(tr("Polygon"), PaintArea::Polygon);shapeComboBox->addItem(tr("PolyLine"), PaintArea::PolyLine);shapeComboBox->addItem(tr("Points"), PaintArea::Points);shapeComboBox->addItem(tr("Arc"), PaintArea::Arc);shapeComboBox->addItem(tr("Path"), PaintArea::Path);shapeComboBox->addItem(tr("Text"), PaintArea::Text);shapeComboBox->addItem(tr("Pixmap"), PaintArea::Pixmap);connect(shapeComboBox, SIGNAL(activated(int)), this, SLOT(ShowShape(int)));penColorLabel = new QLabel(tr("画笔颜色: "));                 //画笔颜色选择控件penColorFrame = new QFrame;penColorFrame->setFrameStyle(QFrame::Panel|QFrame::Sunken);penColorFrame->setAutoFillBackground(true);penColorFrame->setPalette(QPalette(Qt::blue));penColorBtn = new QPushButton(tr("更改"));connect(penColorBtn,SIGNAL(clicked()),this,SLOT(ShowPenColor()));penWidthLabel = new QLabel(tr("画笔线宽: "));                 //画笔线宽选择控件penWidthSpinBox = new QSpinBox;penWidthSpinBox->setRange(0,20);connect(penWidthSpinBox, SIGNAL(valueChanged(int)), this, SLOT(ShowPenWidth(int)));penStyleLabel = new QLabel(tr("画笔风格: "));                 //画笔风格选择下拉列表框penStyleComboBox= new QComboBox;penStyleComboBox->addItem(tr("SolidLine"), static_cast<int>(Qt::SolidLine));  //(b)penStyleComboBox->addItem(tr("DashLine"), static_cast<int>(Qt::DashLine));penStyleComboBox->addItem(tr("DotLine"), static_cast<int>(Qt::DotLine));penStyleComboBox->addItem(tr("DashDotLine"), static_cast<int>(Qt::DashDotLine));penStyleComboBox->addItem(tr("DashDotDotLine"), static_cast<int>(Qt::DashDotDotLine));penStyleComboBox->addItem(tr("CustomDashLine"), static_cast<int>(Qt::CustomDashLine));connect(penStyleComboBox, SIGNAL(activated(int)), this, SLOT(ShowPenStyle(int)));penCapLabel = new QLabel(tr("画笔顶帽: "));                   //画笔顶帽风格选择下拉列表框penCapComboBox= new QComboBox;penCapComboBox->addItem(tr("Squarecap"), Qt::SquareCap);    //(c)penCapComboBox->addItem(tr("FlatCap"), Qt::FlatCap);penCapComboBox->addItem(tr("RoundCap"), Qt::RoundCap);connect(penCapComboBox, SIGNAL(activated(int)), this, SLOT(ShowPenCap(int)));penJoinLabel = new QLabel(tr("画笔连接点:"));                //画笔连接点风格选择下拉列表框penJoinComboBox = new QComboBox;penJoinComboBox->addItem(tr("BevelJoin"), Qt::BevelJoin);   //(d)penJoinComboBox->addItem(tr("MiterJoin"), Qt::MiterJoin);penJoinComboBox->addItem(tr("RoundJoin"), Qt::RoundJoin);connect(penJoinComboBox, SIGNAL(activated(int)), this, SLOT(ShowPenJoin(int)));fillRuleLabel = new QLabel(tr("填充模式: "));                 //填充模式选择下拉列表能fillRuleComboBox = new QComboBox;fillRuleComboBox->addItem(tr("Odd Even"), Qt::OddEvenFill);fillRuleComboBox->addItem(tr("Winding"), Qt::WindingFill);    //(e)connect(fillRuleComboBox, SIGNAL(activated(int)), this, SLOT(ShowFillRule()));spreadLabel = new QLabel(tr("铺展效果: "));                   //铺展效果选择下拉列表框spreadComboBox = new QComboBox;spreadComboBox->addItem(tr("PadSpread"),QGradient::PadSpread); //(f)spreadComboBox->addItem(tr("RepeatSpread"), QGradient::RepeatSpread);spreadComboBox->addItem(tr("ReflectSpread"), QGradient::ReflectSpread);connect (spreadComboBox, SIGNAL(activated(int)), this, SLOT(ShowSpreadStyle()));brushColorLabel = new QLabel(tr("画刷颜色: "));               //画刷颜色选择控件brushColorFrame = new QFrame;brushColorFrame->setFrameStyle(QFrame::Panel|QFrame::Sunken);brushColorFrame->setAutoFillBackground(true);brushColorFrame->setPalette(QPalette(Qt::green));brushColorBtn = new QPushButton(tr("更改"));connect (brushColorBtn,SIGNAL(clicked()),this,SLOT(ShowBrushColor()));brushStyleLabel = new QLabel(tr("画刷风格: "));               //画刷风格选择下拉列表框brushStyleComboBox = new QComboBox;                         brushStyleComboBox->addItem(tr("Solidpattern"), static_cast<int>(Qt::SolidPattern));  //(g)brushStyleComboBox->addItem(tr("DenselPattern"), static_cast<int>(Qt::Dense1Pattern));brushStyleComboBox->addItem(tr("Dense2Pattern"), static_cast<int>(Qt::Dense2Pattern));brushStyleComboBox->addItem(tr("Dense3Pattern"), static_cast<int>(Qt::Dense3Pattern));brushStyleComboBox->addItem(tr("Dense4Pattern"), static_cast<int>(Qt::Dense4Pattern));brushStyleComboBox->addItem(tr("Dense5Pattern"), static_cast<int>(Qt::Dense5Pattern));brushStyleComboBox->addItem(tr("Dense6Pattern"), static_cast<int>(Qt::Dense6Pattern));brushStyleComboBox->addItem(tr("Dense7Pattern"), static_cast<int>(Qt::Dense7Pattern));brushStyleComboBox->addItem(tr("HorPattern"), static_cast<int>(Qt::HorPattern));brushStyleComboBox->addItem(tr("VerPattern"), static_cast<int>(Qt::VerPattern));brushStyleComboBox->addItem(tr("CrossPattern"), static_cast<int>(Qt::CrossPattern));brushStyleComboBox->addItem(tr("BDiagPattern"), static_cast<int>(Qt::BDiagPattern));brushStyleComboBox->addItem(tr("FDiagPattern"), static_cast<int>(Qt::FDiagPattern));brushStyleComboBox->addItem(tr("DiagCrossPattern"), static_cast<int>(Qt:: DiagCrossPattern));brushStyleComboBox->addItem(tr("LinearGradientPattern"), static_cast<int>(Qt::LinearGradientPattern));brushStyleComboBox->addItem(tr("ConicalGradientPattern"), static_cast<int>(Qt::ConicalGradientPattern));brushStyleComboBox->addItem(tr("RadialGradientPattern"), static_cast<int>(Qt::RadialGradientPattern));brushStyleComboBox->addItem(tr("TexturePattern"), static_cast<int>(Qt::TexturePattern));connect(brushStyleComboBox, SIGNAL(activated(int)), this, SLOT(ShowBrush(int)));rightLayout = new QGridLayout;rightLayout->addWidget(shapeLabel, 0, 0);                   //控制面板的布局rightLayout->addWidget(shapeComboBox, 0, 1);rightLayout->addWidget(penColorLabel, 1, 0);rightLayout->addWidget(penColorFrame, 1, 1);rightLayout->addWidget(penColorBtn, 1, 2);rightLayout->addWidget(penWidthLabel, 2, 0);rightLayout->addWidget(penWidthSpinBox, 2, 1);rightLayout->addWidget (penStyleLabel, 3, 0);rightLayout->addWidget(penStyleComboBox, 3, 1);rightLayout->addWidget(penCapLabel, 4, 0);rightLayout->addWidget(penCapComboBox, 4, 1);rightLayout->addWidget(penJoinLabel, 5, 0);rightLayout->addWidget(penJoinComboBox, 5, 1);rightLayout->addWidget(fillRuleLabel, 6, 0);rightLayout->addWidget(fillRuleComboBox, 6, 1);rightLayout->addWidget(spreadLabel, 7, 0);rightLayout->addWidget(spreadComboBox, 7, 1);rightLayout->addWidget(brushColorLabel, 8, 0);rightLayout->addWidget(brushColorFrame, 8, 1);rightLayout->addWidget(brushColorBtn, 8, 2);rightLayout->addWidget (brushStyleLabel, 9, 0);rightLayout->addWidget(brushStyleComboBox, 9, 1);QHBoxLayout *mainLayout = new QHBoxLayout(this);            //整体的布局mainLayout->addWidget(paintArea);mainLayout->addLayout(rightLayout);mainLayout->setStretchFactor(paintArea, 1);mainLayout->setStretchFactor(rightLayout, 0);ShowShape(shapeComboBox->currentIndex());                   //显示默认的图形
}MainWidget::~MainWidget()
{
}void MainWidget::ShowShape(int)
{}void MainWidget::ShowPenWidth(int)
{}void MainWidget::ShowPenColor()
{}void MainWidget::ShowPenStyle(int)
{}void MainWidget::ShowPenCap(int)
{}void MainWidget::ShowPenJoin(int)
{}void MainWidget::ShowSpreadStyle()
{}void MainWidget::ShowFillRule()
{}void MainWidget::ShowBrushColor()
{}void MainWidget::ShowBrush(int)
{}

3.2 MainWidget类讲解

(a) shapeComboBox 增加选项。可以只插入前面的这个文本,也可以同时插入文本相应的具体数据(通常为枚举类型)

(b) penStyleComboBox->addItem(tr("SolidLine"), static_cast<int>(Qt::SolidLine));

这里是选择画笔的风格

​(c) penCapComboBox->addItem(tr("Squarecap"), Qt::SquareCap);

画笔顶帽风格

​(d) penJoinComboBox->addItem(tr("BevelJoin"), Qt::BevelJoin);

画笔连接点风格,分别是方、尖、圆

(e) fillRuleComboBox->addItem(tr("Winding"), Qt::WindingFill);

Qt 为 QPainterPath 类提供了两种填充规则,分别是 Qt::OddEvenFill 和 Qt::WindingFill,如下图所示

这两种填充规则在判定图形中某一点是处内部还是外部时,判断依据不同:

Qt::OddEvenFill 填充规则判断依据是从图形中某一点画一条水平线到图形外。若这条水平线与图形边线的交点数目为奇数,则说明此点位于图形的内部;若焦点数目为偶数,则此点位于图形的外部,如图 6.12

Qt::WindingFill 填充规则的判断依据是从图形中某一点画一条水平线到图形外,每个点外边线的方向可能向上,也可能向下,若最后结果为 0 则说明在图形外,如图 6.13 (边线的方向是由 QPainterPath 创建时根据描述的顺序决定的时候。如果采用 addRect() 或 addPolygon() 等函数加入的图形,默认是按照顺时针方向)

(g) brushStyleComboBox->addItem(tr("Solidpattern"), static_cast<int>(Qt::SolidPattern));

画刷的各种风格:

3.3 槽函数编写

​showShape() 槽函数,根据当前下拉列表框中选择的选项,调用 PaintArea 类的 setShape() 函数来设置 PaintArea 对象的形状参数:

void MainWidget::ShowShape(int value)
{PaintArea::Shape shape = PaintArea::Shape(shapeComboBox->itemData(value, Qt::UserRole).toInt());paintArea->setShape(shape);
}

QComboBox 类的 itemData 方法返回当前显示的下拉列表框数据,是一个 QVariant 对象,此对象与控件初始化时插入的枚举型数据相关,调用 QVariant 类的 toInt() 函数获得此数据在枚举型数据集合中的序号

其他槽函数比较简单就不做过多赘述。其中铺展效果好像演示不了,我不知道是不是我版本是 QT5 的缘故,还是我抄代码抄错了,有小伙伴知道的告诉我一声

//设置画笔颜色(边线颜色)
void MainWidget::ShowPenColor()
{QColor color = QColorDialog::getColor(static_cast<int>(Qt::blue));penColorFrame->setPalette(QPalette(color));int value = penWidthSpinBox->value();Qt::PenStyle style = Qt::PenStyle(penStyleComboBox->itemData(penStyleComboBox->currentIndex(), Qt::UserRole).toInt());Qt::PenCapStyle cap = Qt:: PenCapStyle(penCapComboBox->itemData(penCapComboBox->currentIndex(), Qt::UserRole).toInt());Qt::PenJoinStyle join = Qt::PenJoinStyle(penJoinComboBox->itemData(penJoinComboBox->currentIndex(), Qt::UserRole).toInt());paintArea->setPen(QPen(color, value, style, cap, join));
}//设置画笔宽度
void MainWidget::ShowPenWidth(int value)
{QColor color = penColorFrame->palette().color(QPalette::Window);Qt::PenStyle style = Qt::PenStyle(penStyleComboBox->itemData(penStyleComboBox->currentIndex(), Qt::UserRole).toInt());Qt::PenCapStyle cap = Qt::PenCapStyle(penCapComboBox->itemData(penCapComboBox->currentIndex(), Qt::UserRole).toInt());Qt::PenJoinStyle join = Qt::PenJoinStyle(penJoinComboBox->itemData(penJoinComboBox->currentIndex(), Qt::UserRole).toInt());paintArea->setPen(QPen(color, value, style, cap, join));
}//设置画笔风格
void MainWidget::ShowPenStyle(int stylevalue)
{QColor color = penColorFrame->palette().color(QPalette::Window);int value = penWidthSpinBox->value();Qt::PenStyle style = Qt::PenStyle(penStyleComboBox->itemData(stylevalue, Qt::UserRole).toInt());Qt::PenCapStyle cap = Qt::PenCapStyle(penCapComboBox->itemData(penCapComboBox->currentIndex(), Qt::UserRole).toInt());Qt::PenJoinStyle join = Qt::PenJoinStyle(penJoinComboBox->itemData(penJoinComboBox->currentIndex(), Qt::UserRole).toInt());paintArea->setPen(QPen(color, value, style, cap, join));
}//设置画笔顶帽
void MainWidget::ShowPenCap(int capValue)
{QColor color = penColorFrame->palette().color(QPalette::Window);int value = penWidthSpinBox->value();Qt::PenStyle style = Qt::PenStyle(penStyleComboBox->itemData(penStyleComboBox->currentIndex(), Qt::UserRole).toInt());Qt::PenCapStyle cap = Qt::PenCapStyle(penCapComboBox->itemData(capValue,Qt::UserRole).toInt());Qt::PenJoinStyle join = Qt::PenJoinStyle(penJoinComboBox->itemData(penJoinComboBox->currentIndex(), Qt::UserRole).toInt());paintArea->setPen(QPen(color,value,style,cap,join));
}//设置画笔连接点
void MainWidget::ShowPenJoin(int joinValue)
{QColor color = penColorFrame->palette().color (QPalette::Window);int value = penWidthSpinBox->value();Qt::PenStyle style = Qt::PenStyle(penStyleComboBox->itemData(penStyleComboBox->currentIndex(),Qt::UserRole).toInt());Qt::PenCapStyle cap = Qt::PenCapStyle(penCapComboBox->itemData(penCapComboBox->currentIndex(),Qt::UserRole).toInt());Qt::PenJoinStyle join = Qt::PenJoinStyle(penJoinComboBox->itemData(joinValue, Qt::UserRole).toInt());paintArea->setPen(QPen(color, value, style, cap, join));
}//设置填充模式(点在图形内还是图形外的判定规则)
void MainWidget::ShowFillRule()
{Qt::FillRule rule = Qt::FillRule(fillRuleComboBox->itemData(fillRuleComboBox->currentIndex(), Qt::UserRole).toInt());paintArea->setFileRule(rule);
}// 设置扩散方式
void MainWidget::ShowSpreadStyle()
{spread = QGradient::Spread(spreadComboBox->itemData(spreadComboBox->currentIndex(), Qt::UserRole).toInt());
}// 设置画刷颜色(内部颜色)
void MainWidget::ShowBrushColor()
{QColor color = QColorDialog::getColor(static_cast<int>(Qt::blue));brushColorFrame->setPalette(QPalette(color));ShowBrush(brushStyleComboBox->currentIndex());
}// 设置画刷风格(边线)和颜色(内部)
void MainWidget::ShowBrush(int value)
{//获得画刷的颜色QColor color = brushColorFrame->palette().color(QPalette:: Window);Qt::BrushStyle style = Qt::BrushStyle(brushStyleComboBox->itemData(value, Qt::UserRole).toInt());  //(a)if(style == Qt::LinearGradientPattern)  //(b){QLinearGradient linearGradient(0, 0, 400, 400);linearGradient.setColorAt(0.0, Qt::white);linearGradient.setColorAt(0.2, color);linearGradient.setColorAt (1.0, Qt::black);linearGradient.setSpread(spread);paintArea->setBrush(linearGradient);}else if(style == Qt::RadialGradientPattern)  //(c){QRadialGradient radialGradient(200, 200, 150, 150, 100);radialGradient.setColorAt(0.0, Qt::white);radialGradient.setColorAt(0.2, color);radialGradient.setColorAt(1.0, Qt::black);radialGradient.setSpread(spread);paintArea->setBrush(radialGradient);}else if(style == Qt::ConicalGradientPattern){QConicalGradient conicalGradient(200, 200, 30);conicalGradient.setColorAt(0.0, Qt::white);conicalGradient.setColorAt (0.2, color);conicalGradient.setColorAt(1.0, Qt::black);paintArea->setBrush(conicalGradient);}else if(style == Qt::TexturePattern){paintArea->setBrush(QBrush(QPixmap("butterfly.png")));}else{paintArea->setBrush(QBrush(color, style));}
}

最后一个函数涉及到的内容很多,可以自己看一下源码。简单的意思就是下面两个图,根据 value 选择的值来对应 style,然后根据 style 的不同值做不同的处理。进入这个函数是 画刷风格触发的槽函数 或者 ShowBrushColor()函数

3.5 其他内容

Qt 画图的坐标系默认以左上角为原点,x 轴向右,y 轴向下。此坐标系可受到 QPainter 类的控制,QPainter 类提供了相应的变形函数,包括旋转、缩放、平移和切边。调用这些函数时,看起来是对绘制内容的改变,实际上是坐标系的改变。如果还需要实现更复杂的变形,则可以采用 QTransform 类实现

相关文章:

《Qt6开发及实例》6-2 Qt6基础图形的绘制

目录 一、绘图框架设计 二、绘图区的实现 2.1 PaintArea类 2.2 PaintArea类讲解 三、主窗口的实现 3.1 MainWidget类 3.2 MainWidget类讲解 3.3 槽函数编写 3.5 其他内容 一、绘图框架设计 界面 两个类 ​ 二、绘图区的实现 2.1 PaintArea类 ​paintarea.h #ifndef…...

LeetCode 382. 链表随机节点

原题链接 难度&#xff1a;middle\color{orange}{middle}middle 题目描述 给你一个单链表&#xff0c;随机选择链表的一个节点&#xff0c;并返回相应的节点值。每个节点 被选中的概率一样 。 实现 SolutionSolutionSolution 类&#xff1a; Solution(ListNodehead)Solution…...

iOS开发AppleDeveloper中给别人授权开发者权限后,对方一直显示不了我的开发账号team

在iOS开发经常出现多人协作开发的情况。这时我们通常要发邮件邀请别的用户为开发者或者app管理就可以开发我们自己的项目了。但是这次我给别人授权开发者权限后&#xff0c;发现别人权限中没有证书相关权限如图&#xff1a;并且别人登录该账号后&#xff0c;在xcode中只有一个看…...

FreeRTOS数据类型和编程规范

目录 数据类型 变量名 函数名 宏的名 数据类型 每个移植的版本都含有自己的portmacro.h头文件&#xff0c;里面定义了2个数据类型 TickType_t FreeRTOS配置了一个周期性的时钟中断&#xff1a;Tick Interrupt每发生一次中断&#xff0c;中断次数累加&#xff0c;这被称为t…...

【python知识】win10下如何用python将网页转成pdf文件

一、说明 本篇记录一个自己享用的简单工具。在大量阅读网上文章中&#xff0c;常常遇到一个专题对应多篇文章&#xff0c;用浏览器的收藏根本不够。能否见到一篇文章具有搜藏价值&#xff0c;就转到线下&#xff0c;以备日后慢慢消化吸收。这里终于找到一个办法&#xff0c;将在…...

C语言常见关键字

写在前面 这个博客是结合C语言深度解剖这本书和我以前学的知识综合而成的,我希望可以更见详细的谈一下C语言的关键字,内容有点多,有错误还请斧正. 常见关键字 下面我们说下C语言的关键字,所谓的关键字是指具有特定功能的单词,我们可以使用关键字来帮助我们完成不同的事物.C语…...

【MT7628】固件开发-SDK4320添加MT7612E WiFi驱动操作说明

解压5G WiFi MT7612E驱动1.1解压指令 tar -xvf MT76x2E_MT7620_LinuxAP_V3.0.4.0_P2_DPA_20160308.tar.bz2 1.2解压之后会出现以下两个目录 rlt_wifi rlt_wifi_ap 1.3将解压后的文件拷贝到系统下 拷贝路径 RT288x_SDK/source/linux-2.6.36.x/drivers/net/wireless 内核中打开驱…...

如何从手工测试进阶自动化测试?阿里10年测开经验分享...

随着行业的竞争加剧&#xff0c;互联网产品迭代速度越来越快&#xff0c;QA 与测试工程师都需要在越来越短的测试周期内充分保证质量。可是&#xff0c;App 测试面临着很多挑战&#xff0c;比如多端发布、多版本发布、多机型发布等等&#xff0c;导致了手工测试很难完全胜任。因…...

C++复习笔记11

1. vector是表示可变大小数组的序列容器。 2. 就像数组一样&#xff0c;vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元素进行访问&#xff0c;和数组一样高效。但是又不像数组&#xff0c;它的大小是可以动态改变的&#xff0c;而且它的大小会被…...

【MT7628】固件开发-SDK4320添加MT7628 WiFi驱动操作说明

解压2.4G WiFi MT7628驱动1.1解压指令 tar -xvf MT7628_LinuxAP_V4.1.0.0_DPA_20160310.tar.bz2 1.2解压之后会出现以下两个目录 mt_wifi mt_wifi_ap 1.3将解压后的文件拷贝到系统下 拷贝路径 RT288x_SDK/source/linux-2.6.36.x/drivers/net/wireless 内核中打开驱动编译修改R…...

C#开发的OpenRA游戏加载界面的实现

C#开发的OpenRA游戏加载界面的实现 游戏的UI是一个游戏必备, 但是游戏的UI都是自己处理的,不能使用像Windows自带的UI。 这样游戏的UI,其实也是使用游戏的方式来显示的, 只不过使用了低帧率的方式来显示。 比如OpenRA游戏界面,就会显示如下: 游戏的界面有很多,先从一个简…...

渲染农场优势是什么_云渲染农场怎么用?

在回答渲染农场的优势这个问题之前&#xff0c;我先申明一下本文中提到的渲染农场/云渲染平台/云渲染农场&#xff0c;都特指CG领域内的专业3D渲染平台&#xff0c;有一些文章会强调这个叫法的区别&#xff0c;但是业内一般都不会分这么细&#xff0c;所以也就不赘述了。渲染农…...

SoapUI、Jmeter、Postman三种接口测试工具的比较分析

目录 前言 1. 用例组织方式 2. 支持的接口类型与测试类型 3. 配置不同接口类型 4. 自定义变量以及变量的作用域 5. 数据源、生成器&#xff0c;进行参数化 6. 流程控制 7. 结果解析、展示 8. 断言 9. 脚本扩展能力 10. 团队协作 总结 重点&#xff1a;配…...

Python内置函数 — sort,sorted

1、sort 列表的属性方法&#xff0c;对列表进行排序&#xff0c;默认升序&#xff0c;返回None值。 源码注释&#xff1a; """ Sort the list in ascending order and return None.The sort is in-place (i.e. the list itself is modified) and stable (i.e.…...

mysql事务隔离级别

mysql锁机制及原理1.隔离级别2.实践2.1查看事务隔离级别2.2 设置隔离级别2.3 不可重复读2.4 幻读3.幻读怎么解决3.1 Record Lock3.2 Gap Lock3.3 Next-Key Lock引用&#xff1a;https://blog.csdn.net/xinyuan_java/article/details/1284932051.隔离级别 SERIALIZABLE(序列化)…...

【C++】string类(下)

文章目录1.迭代器(正向遍历)begin有两个版本2.反向迭代器(反向遍历)rbegin由两个版本3. at4. insert ——头插在pos位置前插入一个字符串在pos位置前插入n个字符在迭代器前插入一个字符5. erase从pos位置开始删除len个字符从迭代器位置开始删除6. replace——替换从pos位置开始…...

Elasticsearch: Prefix queries - 前缀查询

Prefix queries 被用于在查询时返回在提供的字段中包含特定前缀的文档。有时我们可能想使用前缀查询单词&#xff0c;例如 Leonardo 的 Leo 或 Marlon Brando、Mark Hamill 或 Martin Balsam 的 Mar。 Elasticsearch 提供了一个前缀查询&#xff0c;用于获取匹配单词开头部分&a…...

GEE学习笔记 七十七:GEE学习方法简介

这是一篇关于学习方法的思考探索&#xff0c;当然我不会大篇文章介绍什么学习方法&#xff08;因为我也不是这方面的专家?&#xff09;&#xff0c;这个只是总结一下我是如何学习GEE以及在学习中遇到问题时如何解决问题的。我写这篇文章的目的就是在和一些学习GEE的新同学接触…...

20基于主从博弈的智能小区代理商定价策略及电动汽车充电管理MATLAB程序

参考文档&#xff1a;《基于主从博弈的智能小区代理商定价策略及电动汽车充电管理》基本复现仿真平台&#xff1a;MATLABCPLEX/gurobi平台优势&#xff1a;代码具有一定的深度和创新性&#xff0c;注释清晰&#xff0c;非烂大街的代码&#xff0c;非常精品&#xff01;主要内容…...

长按power键,点击重启按钮,系统重启流程一

1.有可能会涉及到如下文件 2.文件流程...

CTF show Web 红包题第六弹

提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框&#xff0c;很难让人不联想到SQL注入&#xff0c;但提示都说了不是SQL注入&#xff0c;所以就不往这方面想了 ​ 先查看一下网页源码&#xff0c;发现一段JavaScript代码&#xff0c;有一个关键类ctfs…...

云计算——弹性云计算器(ECS)

弹性云服务器&#xff1a;ECS 概述 云计算重构了ICT系统&#xff0c;云计算平台厂商推出使得厂家能够主要关注应用管理而非平台管理的云平台&#xff0c;包含如下主要概念。 ECS&#xff08;Elastic Cloud Server&#xff09;&#xff1a;即弹性云服务器&#xff0c;是云计算…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件

在选煤厂、化工厂、钢铁厂等过程生产型企业&#xff0c;其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进&#xff0c;需提前预防假检、错检、漏检&#xff0c;推动智慧生产运维系统数据的流动和现场赋能应用。同时&#xff0c;…...

(二)TensorRT-LLM | 模型导出(v0.20.0rc3)

0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述&#xff0c;后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作&#xff0c;其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...

Objective-C常用命名规范总结

【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名&#xff08;Class Name)2.协议名&#xff08;Protocol Name)3.方法名&#xff08;Method Name)4.属性名&#xff08;Property Name&#xff09;5.局部变量/实例变量&#xff08;Local / Instance Variables&…...

python如何将word的doc另存为docx

将 DOCX 文件另存为 DOCX 格式&#xff08;Python 实现&#xff09; 在 Python 中&#xff0c;你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是&#xff0c;.doc 是旧的 Word 格式&#xff0c;而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...

uniapp中使用aixos 报错

问题&#xff1a; 在uniapp中使用aixos&#xff0c;运行后报如下错误&#xff1a; AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...

人工智能(大型语言模型 LLMs)对不同学科的影响以及由此产生的新学习方式

今天是关于AI如何在教学中增强学生的学习体验&#xff0c;我把重要信息标红了。人文学科的价值被低估了 ⬇️ 转型与必要性 人工智能正在深刻地改变教育&#xff0c;这并非炒作&#xff0c;而是已经发生的巨大变革。教育机构和教育者不能忽视它&#xff0c;试图简单地禁止学生使…...

AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别

【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而&#xff0c;传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案&#xff0c;能够实现大范围覆盖并远程采集数据。尽管具备这些优势&#xf…...

[免费]微信小程序问卷调查系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】

大家好&#xff0c;我是java1234_小锋老师&#xff0c;看到一个不错的微信小程序问卷调查系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】&#xff0c;分享下哈。 项目视频演示 【免费】微信小程序问卷调查系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…...