QT5图形与画图
Qt5位置相关函数
区别概述
Qt提供了很多关于获取窗体位置及显示区域大小的函数,如x( )、y()和pos()、 rect()、size()、geometry()等,统称为“位置相关函数”或"位置函数”,如图6.1 所示是几种主要的位置函数,图中清楚地标出了它们之间的区别。
其中,
• x()、y()和pos()函数的作用都是获得整个窗体左上角的坐标位置。
• frameGeometry()与 geometry()相对应。frameGeometry()是获得整个窗体的左 上顶点和长、宽值,而geometry()函数获得的是窗体内中央区域的左上顶点坐标及 长、宽值。
•直接调用width()和height()函数获得的是中央区域的长、宽值。
• rect(),size()函数获得的结果也都是对于窗体的中央区域而言的。size())获得 的是窗体中央区域的长、宽值,rect()与geometry()相同,返回一个QRect对象,这 两个函数获得的长、宽值是相同的,都是窗体中央区域的长、宽值,只是左上顶点 的坐标值不一样,geometry()获得的左上顶点坐标是相对于父窗体而言的坐标,而 rect()获得的左上顶点坐标始终为(0,0)。
在实际应用中需要根据情况使用正确的位置信息函数以获得准确的位置尺寸 信息,尤其是在编写对位置精度要求较高的程序(如地图浏览程序)时,更应注意 函数的选择,避免产生不必要的误差。
示例代码:
Geometry.h
#ifndef TEST_GEOMETRY_H #define TEST_GEOMETRY_H #include <QLabel> #include <QGridLayout> #include <QDialog> class Geometry : public QDialog { Q_OBJECT public: explicit Geometry(QWidget *parent = 0); ~Geometry() override = default; void updateLabel (); private: QLabel *xLabel; QLabel *xValueLabel; QLabel *yLabel; QLabel *yValueLabel; QLabel *FrmLabel; QLabel *FrmValueLabel; QLabel *posLabel; QLabel *posValueLabel; QLabel *geoLabel; QLabel *geoValueLabel; QLabel *widthLabel; QLabel *widthValueLabel; QLabel *heightLabel; QLabel *heightValueLabel; QLabel *rectLabel; QLabel *rectValueLabel; QLabel *sizeLabel; QLabel *sizeValueLabel; QGridLayout *mainLayout; protected: void moveEvent(QMoveEvent *) override; void resizeEvent(QResizeEvent *) override; }; #endif //TEST_GEOMETRY_H
Geometry.cpp
#include "Geometry.h" Geometry::Geometry(QWidget *parent) { mainLayout =new QGridLayout(this); xLabel = new QLabel("x()",this); xValueLabel = new QLabel(this); yLabel = new QLabel("y()",this); yValueLabel = new QLabel(this); posLabel = new QLabel("pos()",this); posValueLabel = new QLabel(this); FrmLabel = new QLabel("frm()",this); FrmValueLabel = new QLabel(this); geoLabel = new QLabel("geo()",this); geoValueLabel = new QLabel(this); widthLabel = new QLabel("width()",this); widthValueLabel = new QLabel(this); heightLabel = new QLabel("height()",this); heightValueLabel = new QLabel(this); rectLabel = new QLabel("rect()",this); rectValueLabel = new QLabel(this); sizeLabel = new QLabel("size()",this); sizeValueLabel = new QLabel(this); mainLayout->addWidget(xLabel, 0,0); mainLayout->addWidget(xValueLabel,0,1); mainLayout->addWidget(yLabel,1,0); mainLayout->addWidget(yValueLabel,1,1); mainLayout->addWidget(posLabel,2,0); mainLayout->addWidget(posValueLabel, 2,1); mainLayout->addWidget(FrmLabel,3,0); mainLayout->addWidget(FrmValueLabel,3,1); mainLayout->addWidget(geoLabel,4,0); mainLayout->addWidget(geoValueLabel, 4,1); mainLayout->addWidget(widthLabel,5,0); mainLayout->addWidget(widthValueLabel,5,1); mainLayout->addWidget(heightLabel,6,0); mainLayout->addWidget(heightValueLabel,6,1); mainLayout->addWidget(rectLabel,7,0); mainLayout->addWidget(rectValueLabel,7,1); mainLayout->addWidget(sizeLabel,8,0); mainLayout->addWidget(sizeValueLabel,8,1); updateLabel (); } void Geometry::updateLabel() { QString xStr; //获得x ()函数的结果并显示 xValueLabel->setText(xStr.setNum(x())); QString yStr; //获得y ()函数的结果并显示 yValueLabel->setText(yStr.setNum(y())); QString frameStr; //获得 f rameGeometry ()函数的结果并显示 QString tempStr1,tempStr2,tempStr3,tempStr4; frameStr = tempStr1.setNum(frameGeometry() .x ())+"," + tempStr2.setNum(frameGeometry().y())+","+ tempStr3.setNum(frameGeometry().width())+","+ tempStr4.setNum(frameGeometry().height()); FrmValueLabel->setText(frameStr); QString positionStr; //获得pos ()函数的结果并显示 QString tempStrll,tempStrl2; positionStr =tempStrll.setNum(pos().x())+"," + tempStrl2.setNum(pos() .y ()); posValueLabel->setText(positionStr); QString geoStr; //获得geometry ()函数的结果并显示 QString tempStr21,tempStr22,tempStr23,tempStr24; geoStr =tempStr21.setNum(geometry() .x ())+"," + tempStr22.setNum(geometry().y())+","+ tempStr23.setNum(geometry().width())+","+ tempStr24.setNum(geometry() .height ()); geoValueLabel->setText(geoStr); QString wStr, hStr; //获得 width () > height ()函数的结果并显示 widthValueLabel->setText(wStr.setNum(width())); heightValueLabel->setText(hStr.setNum(height())); QString rectStr; //获得rect ()函数的结果并显小 QString tempStr31,tempStr32,tempStr33,tempStr34; rectStr =tempStr31.setNum(rect ().x())+"," + tempStr32.setNum(rect().y())+","+ tempStr33.setNum(rect().width()/width())+","+ tempStr34.setNum(height()/rect ().height()); rectValueLabel->setText(rectStr); QString sizeStr; //获得size ()函数的结果并显示 QString tempStr41,tempStr42; sizeStr =tempStr41.setNum(size().width())+","+ tempStr42.setNum(size().height()); sizeValueLabel->setText(sizeStr); } void Geometry::moveEvent(QMoveEvent *) { updateLabel(); } void Geometry::resizeEvent(QResizeEvent *) { updateLabel(); }
main.cpp
#include <QApplication> #include "Geometry.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); Geometry gg; gg.show(); return a.exec (); }
示例图片:
QT5基础图形的绘制
示例代码:
main.cpp
#include <QApplication> #include "mainwidget.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWidget gg; gg.show(); return a.exec (); }
paintarea.h
#ifndef TEST_PAINTAREA_H #define TEST_PAINTAREA_H #include <QPen> #include <QBrush> #include <QWidget> class PaintArea : public QWidget { Q_OBJECT public: enum Shape{ Line, Rectangle, RoundRect, Ellipse, Polygon, Polyline, Points, Arc, Path, Text, Pixmap }; explicit PaintArea(QWidget *parent=0); void setShape(Shape); void setPen(QPen); void setBrush(QBrush); void setFillRule(Qt::FillRule); void paintEvent(QPaintEvent *); signals: public slots: private: Shape shape; QPen pen; QBrush brush; Qt::FillRule fillRule; }; #endif //TEST_PAINTAREA_H
paintarea.cpp
#include "paintarea.h" #include <QPainter> #include <QPainterPath> PaintArea::PaintArea(QWidget *parent): QWidget(parent) { setPalette(QPalette(Qt::white)); setAutoFillBackground(true); setMinimumSize(400,400); } void PaintArea::setShape(Shape s) { shape = s; update(); } void PaintArea::setPen(QPen p) { pen = p; update(); } void PaintArea::setBrush(QBrush b) { brush = b; update(); } void PaintArea::setFillRule(Qt::FillRule rule) { fillRule =rule; update () ; //重画绘制区窗体 } void PaintArea::paintEvent(QPaintEvent *) { QPainter p(this); p.setPen (pen); p.setBrush (brush); QRect rect (50,100,300,200); static const QPoint points [4]= { QPoint (150,100), QPoint(300,150), QPoint(350,250), QPoint(100,300) }; int startAngle =30*16; int spanAngle =120*16; QPainterPath path; 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) { case Line : //直线 p.drawLine(rect.topLeft(), rect.bottomRight()); break; case Rectangle: //长方形 p.drawRect(rect); break; case RoundRect: //圆角方形 p.drawRoundRect(rect); break; case Ellipse: //椭圆形 p.drawEllipse(rect) ; break; case Polygon: //多边形 p.drawPolygon(points,4); break; case Polyline: //多边线 p.drawPolyline(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.drawText(rect,Qt::AlignCenter,tr("Hello Qt!")); break; case Pixmap: //图片 p. drawPixmap (150,150,QPixmap ("butterfly.png") ) ; break; default: break; } }
mainwidget.h
#ifndef TEST_MAINWIDGET_H #define TEST_MAINWIDGET_H #include <QWidget> #include "paintarea.h" #include <QLabel> #include <QComboBox> #include <QSpinBox> #include <QPushButton> #include <QGridLayout> #include <QGradient> class MainWidget : public QWidget { Q_OBJECT public: MainWidget(QWidget *parent = 0); ~MainWidget() override = default; 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 //TEST_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); 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)); 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 ("ifil笔顶帽:")); //画笔顶帽风格选择下拉列表框 penCapComboBox =new QComboBox; penCapComboBox->addItem(tr("SquareCap"),Qt::SquareCap); 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); 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); connect(fillRuleComboBox,SIGNAL(activated(int)),this, SLOT (ShowFillRule())); spreadLabel =new QLabel (tr ("铺展效果:"));//铺展效果选择下拉列表框 spreadComboBox =new QComboBox; spreadComboBox->addItem(tr("PadSpread"),QGradient::PadSpread); 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)); brushStyleComboBox->addItem(tr("Dense1Pattern"), 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 ( "RadialGradientPattern1"), 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()) ; } void MainWidget::ShowShape(int value) { PaintArea::Shape shape =PaintArea::Shape(shapeComboBox->itemData(value,Qt::UserRole).toInt()); paintArea->setShape(shape); } 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::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::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::ShowSpreadStyle() { spread = QGradient::Spread(spreadComboBox->itemData( spreadComboBox->currentIndex(),Qt::UserRole).toInt()); } void MainWidget::ShowFillRule() { Qt::FillRule rule = Qt::FillRule(fillRuleComboBox->itemData( fillRuleComboBox->currentIndex(),Qt::UserRole).toInt()); paintArea->setFillRule(rule); } 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()); if(style == Qt::LinearGradientPattern) { 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) { 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)); } }
示例图片:
具体函数不做具体解释,后续的内容中如果涉及到绘制这块,会单独的讲出绘制的具体内容,相关的具体绘制信息可以在QT的官方文档中看到具体的样式。
双缓冲机制
所谓双缓冲机制,即在绘制控件时,首先将要绘制的内容绘制在一个图片中, 再将图片一次性绘制到控件上。在早期的Qt版本中,若直接在控件上进行绘制工 作,则在控件重绘时会产生闪烁的现象,控件重绘频繁时闪烁尤为明显。双缓冲机 制可以有效地消除这种闪烁现象。自Qt5版本之后,QWidget控件已经能够自动处 理闪烁的问题。因此,在控件上直接绘图时,不用再操心显示的闪烁问题,但双缓 冲机制在很多场合仍然有其用武之地,当所需绘制的内容较复杂并需要频繁刷新, 或者每次只需要刷新整个控件的一小部分时,仍应尽量采用双缓冲机制。
QT5与SVG
SVG的英文全称是Scalable Vector Graphics,即可缩放的矢量图形。它是由万 维网联盟(World Wide Web Consortium, W3C)在2000年8月制订的一种新的二 维矢量图形格式,也是规范中的网格矢量图形标准,是一个开放的图形标准。
SVG格式的特点如下:
(1) 基于XML。
(2) 釆用文本来描述对象。
(3) 具有交互性和动态性。
(4) 完全支持DOM。
SVG相对于GIF、JPEG格式的优势是,SVG是一种矢量图形格式,比GIF、JPEG等栅格格式具有众多优势,如文件小,对于网络而言下载速度快;可任意缩 放而不会破坏图像的清晰度和细节;图像中的文字独立于图像,文字保留可编辑和 可搜寻的状态,也没有字体的限制,用户系统即使没有安装某一种字体,也可看到 与制作时完全相同的画面等。正是基于它的格式的各种优点及开放性,SVG得到了 众多组织和知名厂商的支持与认可,因此能够迅速地开发和推广应用。
Qt为SVG格式的图形显示与生成提供了专门的QtSvg模块,此模块中包含了 与 SVG 图形相关的所有类,主要有 QSvgWidget、QSvgRender 和 QGraphicsSvgltem。
Qt的XML模块支持两种XML解析方法,DOM和SAX。其中,DOM方法将 XML文件表示为一棵树,便于随机访问其中的节点,但消耗内存相对多一些。而 SAX是一种事件驱动的XML API,速度快,但不便于随机访问任意节点。因此, 通常根据实际应用选用合适的解析方法。这里只介绍DOM使用方法。
文档对象模型(Document Object Model, DOM)是W3C开发的独立于平台和 语言的接口,它可以使程序和脚本能够动态地存取和更新XML文档的内容、结构 和风格。
DOM在内存中将XML文件表示为一棵树,用户通过API可以随意地访问树 的任意节点内容。在Qt中,XML文档自身用QDomDocument表示,所有的节点 类都从QDomNode继承。
下面通过实现一个读取SVG文件中的部分绘图元素绘制其图形的例子,介绍 DOM的应用。SVG文件是利用XML表示的矢量图形文件,每种图形都用XML标 签表示。例如,在SVG中画折线的标签如下:
<svg height="200" width="500"> <polyline points="20,20 40,25 60,40 80,120 120,140 200,180" style="fill:none;stroke:black;stroke-width:3" /> </svg>
其中:
• polyline: 表示绘制折线。
• fill: 属性表示填充。
• stroke: 表示画笔颜色。
• stroke-width: 表示画笔宽度。
• points: 表示折线的点。