QPainter
Qt的二维绘图基本功能是使用QPainter在绘图设备上绘图,绘图设备包括QWidget、QPixmap等,通过绘制一些基本的点、线、圆等基本形状组成自己需要的图形,得到的图形是不可交互操作的图形。
QPainter的绘图设备包括:QWidget、QPixmap、QImage、QPicture、QPrinter等。 QPainter的绘图设备均继承自 QPaintDevice,核心区别在于用途和特性:
| 设备 | 核心特性 | 适用场景 |
|---|---|---|
QWidget | 实时界面绘制,依赖窗口刷新 | 自定义控件、动态图形显示 |
QImage | 内存像素操作,独立于硬件 | 图像处理、生成图像文件 |
QPixmap | 屏幕显示优化,绘图效率高 | 图像显示、绘图缓存(双缓冲) |
QPicture | 记录绘图命令,矢量格式 | 保存绘图过程、跨设备复用命令 |
QPrinter | 连接打印机,支持打印参数 | 文档、图像打印 |
QWidget类及其子类是最常用的绘图设备,从QWidget类继承的类都有paintEvent()事件,要
在设备上绘图,只需重定义此事件并编写响应代码。创建一个QPainter对象获取绘图设备的接口,然后就可以在绘图设备的“画布”上绘图了。
在paintEvent()事件里绘图的基本程序结构是:
void Widget::paintEvent(QPaintEvent *event){QPainter painter(this);// 创建与绘图设备关联的QPainter对象...//painter在设备的窗口上绘图
}
QPainter的属性
1.QPen
QPen属性决定了绘制线条、轮廓时的样式(如颜色、宽度、线条类型、端点样式、拐角样式等)的类,通常与QPainter配合使用(通过QPainter::setPen()生效)。以下是QPen的主要函数:
(1)构造函数
QPen提供多种构造方式,用于初始化画笔的基本属性:
默认构造
QPen pen;//初始化一个默认画笔:黑色(Qt::black)、线宽 1 像素、实线(Qt::SolidLine)、平端笔帽(Qt::SquareCap)、斜接拐角(Qt::MiterJoin)。
指定颜色构造
//QPen(const QColor &color)
//用指定颜色初始化画笔,其他属性(线宽、样式等)为默认值。
QPen pen(Qt::red); // 红色画笔
指定样式构造
//QPen(Qt::PenStyle style)
//用指定线条样式初始化画笔,颜色默认黑色,线宽 1 像素。
QPen pen(Qt::DashLine); // 黑色虚线画笔
指定画笔和样式构造
QPen(const QBrush &brush, qreal width, Qt::PenStyle style = Qt::SolidLine, Qt::PenCapStyle cap = Qt::SquareCap, Qt::PenJoinStyle join = Qt::MiterJoin)
最灵活的构造方式,可同时指定:
brush:线条填充的画笔(用于线宽较大时的填充,支持渐变、纹理等);
width:线宽(单位为像素,浮点数);
style:线条样式(如实线、虚线);
cap:笔帽样式(线条端点的样式);
join:连接样式(线条拐角的样式)。
(2)颜色相关函数
用于设置或获取线条的颜色(当画笔为纯色时生效)。
设置颜色
//void setColor(const QColor &color)
pen.setColor(QColor(255, 0, 0)); // 设置为红色
获取颜色
//QColor color() const
QColor c = pen.color(); // 获取当前颜色
(3)线宽相关函数
线宽决定线条的粗细,单位为像素(支持浮点数精度)。线宽为 0 时,Qt 会绘制 “最细的线”(通常为 1 像素,且不受缩放影响,类似 “ cosmetic pen ”);线宽 >0 时,线条粗细会随绘图设备的缩放比例变化(除非设置为 “cosmetic pen”)。
设置线宽
//void setWidth(int width)
pen.setWidth(2); // 线宽2像素//void setWidthF(qreal width)支持更精细的线宽(如 0.5 像素)
pen.setWidthF(0.5);
获取线宽(整数/浮点数)
int width() const // 返回整数线宽(四舍五入)
qreal widthF() const // 返回精确浮点数线宽int penWidth=pen.width();
Cosmetic Pen(装饰性画笔) 的线宽不随绘图设备的缩放而变化(始终保持视觉上的粗细一致),适合绘制界面元素(如边框);非装饰性画笔的线宽会随缩放比例变化(适合绘制图形数据)。
void setCosmetic(bool cosmetic)//设置是否为装饰性画笔
pen.setCosmetic(true); // 线宽不随缩放变化bool isCosmetic() const//判断是否为装饰性画笔
(4)线条样式
控制线条的外观(如实线、虚线、点线等),通过 Qt::PenStyle 枚举定义,常用值如下:
Qt::SolidLine:实线(默认);Qt::DashLine:虚线(短横线间隔);Qt::DotLine:点线(圆点间隔);Qt::DashDotLine: dash+dot 交替;Qt::DashDotDotLine: dash+dot+dot 交替;Qt::NoPen:无线条(不绘制)
//void setStyle(Qt::PenStyle style)
pen.setStyle(Qt::DotLine); // 设置为点线//Qt::PenStyle style() const 获取线条样式

除了基本的线条样式,还可以通过setDashOffset()和setDashPattern()函数自定义线条样式。
对于 Qt::CustomDashLine 样式,可通过以下函数定义虚线的 “线段长度” 和 “间隔长度”:
//参数 pattern 是一个浮点数数组,依次表示 “线段长度” 和 “间隔长度”(单位为线宽的倍数)。
void setDashPattern(const QVector<qreal> &pattern)
//短横线+长间隔
pen.setStyle(Qt::CustomDashLine);
QVector<qreal> dash;
dash << 2 << 5; // 线段长度=2×线宽,间隔长度=5×线宽
pen.setDashPattern(dash);
pen.setWidth(2); // 线宽2像素 → 线段实际长度=4像素,间隔=10像素//获取自定义虚线模式
QVector<qreal> dashPattern() const
(5)线条端点样式
控制线条端点的外观(仅当线宽 >1 时明显),通过 Qt::PenCapStyle 枚举定义,常用值:
Qt::SquareCap:方形端点(默认,端点超出线条终点半个线宽);Qt::FlatCap:平端(端点与线条终点对齐,无超出);Qt::RoundCap:圆形端点(端点为半圆,直径等于线宽)。
//void setCapStyle(Qt::PenCapStyle cap)设置端点样式
pen.setCapStyle(Qt::RoundCap); // 圆形端点
//Qt::PenCapStyle capStyle() const 获取端点样式

(6)线条连接样式
控制两条线段拐角的外观(仅当线宽 >1 且线条有拐角时明显),通过 Qt::PenJoinStyle 枚举定义,常用值:
Qt::MiterJoin:斜接(拐角尖锐,默认);Qt::RoundJoin:圆角(拐角为圆弧);Qt::BevelJoin:斜切(拐角被截断为直角)。
void setJoinStyle(Qt::PenJoinStyle join)//设置连接样式
pen.setJoinStyle(Qt::RoundJoin); // 圆角拐角Qt::PenJoinStyle joinStyle() const//获取连接样式

2.QBrush画笔填充
QBrush定义了QPainter绘图时的填充特性,包括填充颜色、填充样式、材质填充时的材质图
片等。


渐变填充需要使用专门的类作为Brush赋值给QPainter。其他各种线型填充只需设置类型参数即可,使用材质需要设置材质图片。
(1)线性填充

(2)材质填充
使用材质填充需要设置图片作为画刷的图片,void setTexture(QPixmap &pixmap)用来设置QPixmap类型的图片,void setTextureImage(QImage &image)用来设置QImage类型的图片。用材质图片填充矩形:
void Widget::paintEvent(QPaintEvent *event)
{QPainter painter(this);int W=this->width();//绘图区宽度intH=this->height();//绘图区高度QRectrect(W/4,H/4,W/2,H/2);//中间区域矩形框//设置画笔QPen pen;pen.setwidth(3);//线宽pen.setColor(Qt::red);//划线颜色pen.setStyle(Qt::SolidLine);//线的类型,实线、虚线等painter.setPen(pen);//设置画刷QPixmap texturePixmap(":images/images/texture.jpg");QBrush brush;brush.setStyle(Qt::TexturePattern);//画刷填充样式brush.setTexture(texturePixmap);//设置材质图片painter.setBrush (brush);//绘图painter.drawRect(rect);
}
最终效果:

(3)渐变填充
使用渐变填充需要用渐变类的对象作为Painter的brush,有3个实现渐变填充的类。
QLinearGradient:线性渐变。指定一个起点及其颜色,终点及其颜色,还可以指定中间的某个点的颜色,起点至终点之间的颜色会线性插值计算,得到线性渐变的填充颜色。
QRadialGradient:有简单辐射渐变和扩展辐射渐变两种方式。简单辐射渐变是在一个圆内的一个焦点和一个端点之间生成渐变颜色,扩展辐射渐变是在一个焦点圆和一个中心圆之间生成渐变色。
QConicalGradient:圆锥形渐变,围绕一个中心点逆时针生成渐变颜色。
以下依次为QLinearGradient、QRadialGradient、QConicalGradient的效果:

这3个渐变类都继承自QGradient类,除了生成渐变颜色的方式不同之外,在设定的渐变颜色坐标范围之外,还需要用QGradient类的setSpread(QGradient::Spreadmethod)函数设置延展式。
枚举类型QGradient:Spread有3种取值,分别表示3种延展效果,下图使用辐射渐变时3种延展方式的效果。setSpread()对圆锥形渐变不起作用。
- PadSpread模式是用结束点的颜色填充外部区域,这是缺省的方式。
- RepeatSpread模式是重复使用渐变方式填充外部区域。
- ReflectSpread是反射式重复使用渐变方式填充外部区域。

使用渐变填充效果的例子:
void Widget::paintEvent(QPaintEvent *event)
{QPainterpainter(this);int W=this->width();int H=this->height();//径向渐变QRadialGradientradialGrad(W/2,H/2,qMax(W/8,H/8),W/2,H/2);//设置辐射渐变的起点颜色和终点颜色,0表示起点,1表示终点,即填充区圆的圆周radialGrad.setColorAt(O,Qt::green);radialGrad.setColorAt(l,Qt::blue);//设置延展方式为QGradient::ReflectSpreadradialGrad.setSpread(QGradient::ReflectSpread);painter.setBrush(radialGrad);//绘图painter.drawRect(this->rect());//填充更大区域,会有延展效果
}
上面的代码中定义QRadialGradient对象时使用的构造函数原型是:
QRadialGradient(qreal cx, qreal cy, qreal radius, qreal fx, qreal fy)
其中,(cx,cy)是辐射填充的中心点,程序中设置为(W/2,H/2),也就是Widget窗口的中心;radius是辐射填充区的半径,程序中设置为qMax(W/8,H/8);(fx,fy)是焦点坐标,程序中设置为(W/2,H/2),与中心点相同。最终效果如下:

若使用线性渐变填充,示例代码如下(只列出QLinearGradient定义的部分)。定义QLinearGradient对象时指定了线性渐变的起点和终点,设置颜色时可以在起点和终点之间设置多个点的颜色值。
//QLinearGradientlinearGrad(rect.left(),rect.top(),rect.right(),rect.bottom());//对角线
QLinearGradientlinearGrad(rect.left(),rect.top(),rect.right(),rect.top());//从左到右
linearGrad.setColorAt(0,Qt::blue);//起点颜色
linearGrad.setcolorAt(0.5,Qt::green);//中间点颜色
linearGrad.setColorAt(l,Qt::red);//终点颜色
linearGrad.setSpread(QGradient::ReflectSpread);//展布模式
painter.setBrush(linearGrad);
创建QLinearGradient对象时传递了两个坐标点,分别表示填充区的起点和终点,起点和终点
的定义方式不同,可以实现水平渐变、垂直渐变、或对角渐变等不同效果。
使用圆锥形渐变的示例代码如下。创建QConicalGradient对象时指定了中心点坐标和起始角
度,然后设置多个点的颜色。但是注意,圆锥形填充没有延展效果。
QConicalGradientconiGrad(W/2,H/2,45);
coniGrad.setColorAt(0,Qt::yellow);
coniGrad.setColorAt(0.5,Qt::blue);
coniGrad.setColorAt(l,Qt::green);
painter.setBrush (coniGrad);
3.文本属性
QPainter 支持绘制文本,文本的外观(字体、大小、对齐方式等)由文本相关属性控制。
(1)字体
决定文本的字体、大小、加粗等样式,由 QFont 类定义。
| 函数原型 | 作用 | 示例 |
|---|---|---|
void setFont(const QFont &font) | 设置文本字体 | QFont font("Arial", 12, QFont::Bold); painter.setFont(font); |
QFont font() const | 获取当前字体 | QFont currentFont = painter.font(); |
(2)字体度量
用于获取当前字体的度量信息(如字符宽度、行高),辅助文本布局。
| 函数原型 | 作用 | 示例 |
|---|---|---|
QFontMetrics fontMetrics() const | 获取当前字体的度量对象 | int textHeight = painter.fontMetrics().height(); |
(3)文本对齐(Text Alignment)
绘制文本时的对齐方式(如左对齐、居中、右对齐),通过 Qt::Alignment 枚举设置(通常作为 drawText() 的参数,而非直接属性,但逻辑上属于文本绘制的控制属性)。
// 绘制文本时设置居中对齐(水平+垂直居中)
painter.drawText(rect, Qt::AlignCenter, "居中文本");
4.变换
变换属性用于对绘图坐标进行平移、旋转、缩放或剪切,实现图形的几何变换,由类定义。QPainter默认的坐标系如下:


(1)使用QTransform
//设置变换矩阵(combine=true 时与当前变换组合)
//void setTransform(const QTransform &transform, bool combine = false)
QTransform transform;
transform.rotate(45);
painter.setTransform(transform);//获取当前变换矩阵
//QTransform transform() const
QTransform currentTransform = painter.transform();//重置变换矩阵为单位矩阵(取消所有变换)
//void resetTransform()
painter.resetTransform();
(2)使用QPainter自带的坐标变换函数
1. 平移(Translate):移动坐标原点
作用:将坐标系的原点 (0,0) 移动到新位置 (dx, dy),后续绘图的坐标会基于新原点计算。
//void QPainter::translate(qreal dx, qreal dy);
//dx:x 轴方向的偏移量(正数向右,负数向左);
//dy:y 轴方向的偏移量(正数向下,负数向上)。//效果:两个矩形水平间隔 100 像素(因平移了 100)。
void MyWidget::paintEvent(QPaintEvent *e) {Q_UNUSED(e);QPainter painter(this);// 绘制第一个矩形(基于原始原点 (0,0))painter.drawRect(10, 10, 50, 50); // 左上角 (10,10),宽50,高50// 平移:将原点移动到 (100, 0)painter.translate(100, 0);// 绘制第二个矩形(基于新原点 (100,0),实际位置为 100+10=110, 0+10=10)painter.drawRect(10, 10, 50, 50);
}
2. 旋转(Rotate):绕原点旋转坐标系
作用:将坐标系绕原点旋转指定角度(顺时针为正,逆时针为负),后续绘图会随坐标系一起旋转。
//void QPainter::rotate(qreal angle); // 2D 绘图中默认绕 z 轴旋转(平面内旋转)
//angle:旋转角度(单位为度,如 90 表示顺时针旋转 90 度,-90表示逆时针旋转90度)。
//旋转默认绕当前原点,若需绕图形自身中心旋转,需先平移到中心(translate(centerX, centerY)),旋转后再平移回去(translate(-centerX, -centerY)),即 “平移 - 旋转 - 反平移” 三步。void MyWidget::paintEvent(QPaintEvent *e) {Q_UNUSED(e);QPainter painter(this);painter.setRenderHint(QPainter::TextAntialiasing); // 文本抗锯齿// 绘制原始文本(不旋转)painter.drawText(50, 50, "未旋转文本");// 平移到 (200, 50),再旋转 45 度(先平移再旋转,避免绕原点旋转导致偏移)painter.translate(200, 50); // 先将原点移到文本起点,避免旋转后位置偏移painter.rotate(45); // 旋转坐标系 45 度// 绘制旋转后的文本(基于旋转后的坐标系)painter.drawText(0, 0, "旋转45度文本");
}
3. 缩放(Scale):放大或缩小坐标系
作用:沿 x 轴和 y 轴缩放坐标系,后续绘图的尺寸会按比例放大或缩小(大于 1 为放大,0~1 为缩小)。
//void QPainter::scale(qreal sx, qreal sy);
//sx:x 轴缩放因子(如 2 表示 x 方向放大 2 倍);
//sy:y 轴缩放因子(如 0.5 表示 y 方向缩小到 1/2)。void MyWidget::paintEvent(QPaintEvent *e) {Q_UNUSED(e);QPainter painter(this);// 绘制原始矩形(100x50)painter.drawRect(10, 10, 100, 50);// 缩放:x 方向放大 2 倍,y 方向缩小到 1/2painter.scale(2, 0.5);// 绘制缩放后的矩形(实际尺寸:100*2=200 宽,50*0.5=25 高)// 注意:坐标也会缩放,所以 (10, 30) 实际位置为 (10*2, 30*0.5) = (20, 15)painter.drawRect(10, 30, 100, 50);
}
4. 剪切(Shear):扭曲坐标系
作用:使坐标系沿 x 轴或 y 轴产生剪切变形(类似平行四边形的倾斜效果),常用于绘制斜向图形或特殊视觉效果。
//void QPainter::shear(qreal sh, qreal sv);
//sh:水平剪切因子(x 轴随 y 轴变化的倾斜程度,正值向右倾斜,负值向左);
//sv:垂直剪切因子(y 轴随 x 轴变化的倾斜程度,正值向下倾斜,负值向上)。void MyWidget::paintEvent(QPaintEvent *e) {Q_UNUSED(e);QPainter painter(this);// 绘制原始矩形painter.drawRect(10, 10, 100, 50);// 水平剪切(sh=0.5 表示 y 每增加 1,x 增加 0.5)painter.shear(0.5, 0);// 绘制剪切后的矩形(右侧向右倾斜)painter.drawRect(10, 80, 100, 50);
}
5.变换的保存与恢复
当需要临时使用变换(不影响后续绘图)时,可通过 save() 和 restore() 保存和恢复当前变换状态(包括画笔、画刷等所有属性)。
save():将当前所有属性(包括变换矩阵)存入栈中;restore():从栈中弹出最近保存的属性,恢复到保存时的状态。
void MyWidget::paintEvent(QPaintEvent *e) {Q_UNUSED(e);QPainter painter(this);// 绘制第一个矩形(无变换)painter.drawRect(10, 10, 50, 50);// 保存当前状态(无变换)painter.save();// 临时旋转 45 度painter.rotate(45);painter.drawRect(80, 80, 50, 50); // 旋转后的矩形// 恢复到保存的状态(取消旋转)painter.restore();// 绘制第三个矩形(无变换,与第一个一致)painter.drawRect(150, 10, 50, 50);
}
6.重置变换
若需取消所有变换,恢复到原始坐标系,可使用 resetTransform():
painter.resetTransform(); // 清除所有平移、旋转、缩放等变换,矩阵恢复为单位矩阵
多个变换可以叠加(例如先平移再旋转,再缩放),但变换顺序会直接影响结果(因为矩阵乘法不满足交换律)。
5.渲染设置(Render Hints):控制绘图质量
渲染提示用于设置绘图的质量选项(如抗锯齿、文本平滑等),通过 QPainter::RenderHint 枚举指定。
//启用 / 禁用指定渲染提示
void setRenderHint(RenderHint hint, bool on = true)painter.setRenderHint(QPainter::Antialiasing); // 启用抗锯齿// 批量设置渲染提示
void setRenderHints(RenderHints hints, bool on = true)//检查是否启用了指定渲染提示
bool testRenderHint(RenderHint hint) constbool hasAA = painter.testRenderHint(QPainter::Antialiasing);
常用渲染提示:
QPainter::Antialiasing:启用图形抗锯齿(使线条 / 形状边缘更平滑)。QPainter::TextAntialiasing:启用文本抗锯齿(使文本边缘更清晰)。QPainter::SmoothPixmapTransform:启用图像平滑缩放(避免缩放后的锯齿)。
6.合成模式(Composition Mode):控制图形混合
合成模式决定了新绘制的图形与已有图形的颜色混合方式(如透明叠加、颜色叠加等),由 QPainter::CompositionMode 枚举定义。
//设置合成模式
//void setCompositionMode(CompositionMode mode)
painter.setCompositionMode(QPainter::CompositionMode_SourceOver); // 透明叠加(默认)//获取当前合成模式
//CompositionMode compositionMode() const
auto mode = painter.compositionMode();
常用合成模式:
CompositionMode_SourceOver:新图形覆盖在原有图形上,新图形的透明区域显示原有内容(默认)。CompositionMode_DestinationOver:原有图形覆盖新图形,原有图形的透明区域显示新内容。CompositionMode_Xor:新图形与原有图形的重叠区域颜色取异或(常用于临时高亮)。
7.剪辑区域(Clip Region):限制绘图范围
剪辑区域是一个 “可见区域”,QPainter 仅会绘制该区域内的内容,超出区域的部分会被裁剪掉,用于精确控制绘图范围。
| 函数原型 | 作用 | 示例 |
|---|---|---|
void setClipRegion(const QRegion ®ion, Qt::ClipOperation op = Qt::ReplaceClip) | 设置剪辑区域(op 控制与当前区域的关系:替换 / 交集 / 并集等) | QRegion clip(10, 10, 100, 100); painter.setClipRegion(clip); |
void setClipRect(const QRect &rect, Qt::ClipOperation op = Qt::ReplaceClip) | 用矩形设置剪辑区域(更常用) | painter.setClipRect(0, 0, 200, 200); |
QRegion clipRegion() const | 获取当前剪辑区域 | QRegion currentClip = painter.clipRegion(); |
void setClipping(bool enable) | 启用 / 禁用剪辑(默认启用) | painter.setClipping(false); // 关闭剪辑 |
8.背景设置(Background):控制背景填充
背景属性用于设置绘图时的背景颜色和模式(如是否填充背景),使用较少(通常直接用画刷填充背景)。
| 函数原型 | 作用 | 示例 |
|---|---|---|
void setBackground(const QBrush &brush) | 设置背景画刷 | painter.setBackground(QBrush(Qt::gray)); |
QBrush background() const | 获取当前背景画刷 | QBrush bg = painter.background(); |
void setBackgroundMode(Qt::BGMode mode) | 设置背景模式(Qt::OpaqueMode 不透明,Qt::TransparentMode 透明) | painter.setBackgroundMode(Qt::OpaqueMode); |
9.窗口与视口(Window/Viewport):坐标映射
绘图设备的物理坐标是基本的坐标系,通过QPainter的平移、旋转等变换可以得到更容易操
作的逻辑坐标。
为了实现更方便的坐标,QPainter还提供了视口(Viewport)和窗口(Window)坐标系,通
过QPainter内部的坐标变换矩阵自动转换为绘图设备的物理坐标。
视口表示绘图设备的任意一个矩形区域的物理坐标,可以只选取物理坐标的一个矩形区域用
于绘图。默认情况下,视口等于绘图设备的整个矩形区。
窗口与视口是同一个矩形,只不过是用逻辑坐标定义的坐标系。窗口可以直接定义矩形区的
逻辑坐标范围。下面是对视口和窗口的图示说明。

左图中的矩形框代表绘图设备的物理大小和坐标范围,假设宽度为300像素,高度为200像素。现在要取其中间的一个正方形区域作为视口,灰色的正方形就是视口,绘图设备的物理坐标中,视口的左上角坐标为(50,0),右下角坐标为(250,200)。定义此视口,可以使用QPainter的setViewport()函数,其函数为:
//void QPainter::setViewport(int x, int y, int width, int height)
painter.setviewport(50,0,200,200);
//表示从绘图设备物理坐标系统的起点(50,0)开始,取宽度为200、高度为200的一个矩形区域
作为视口。
对于左图的视口所表示的正方形区域,定义一个窗口(右图),窗口坐标的中心在正方形中心,并设置正方形的逻辑边长为100。可使用QPainter的setWindow()函数,其函数为:
//void QPainter::setWindow(int x, int Y, int width, int height)
painter.setwindow (-50,-50,100,100);
//表示对应于视口的矩形区域,其窗口左上角的逻辑坐标是(-50,-50),窗口宽度为100,高度
//为100。这里设置的窗口还是一个正方形,使得从视口到窗口变换时,长和宽的变化比例是相同
//的。实际可以任意指定窗口的逻辑坐标范围,长和宽的变化比例不相同也是可以的。
使用窗口坐标的优点是,只需按照窗口坐标定义来绘图,而不用管实际的物理坐标范围的大小。例如在一个固定边长为100的正方形窗口内绘图,当实际绘图设备大小变化时,绘制的图形会自动变化大小。这样,就可以将绘图功能与绘图设备隔离开来,使得绘图功能适用于不同大小、不同类型的设备。
获取当前窗口/视口区域的函数为:
//QRect window() const / QRect viewport() const
QRect logicWindow = painter.window();
QPainter绘制基本图形文件
QPainter painter(this);
int W=this->width();//绘图区宽度
int H=this->height();//绘图区高度


