Qt实现简单图形绘制,双缓冲机制和显示SVG格式图片

        从去年到现在一直在断断续续学习Qt,这是第一次写博客,感觉学到的东西很少,希望以后能多学、多练、多写吧!(还有部分功能没有实现,等实现了再来补全。)
        首先使用了一个窗口布局来实现这三个功能,包括如何使用分割窗口和如何使用堆栈窗体。
        实现效果图如下:








 
/*插入三个页面*/
    mainwindow=new MainWindow();
    drawwidget=new DrawWidget();
    mainwindow2=new MainWindow2();
    stack->addWidget(mainwindow);
    stack->addWidget(drawwidget);
    stack->addWidget(mainwindow2);

/*创建两个按钮*/
    AmendBtn=new QPushButton(tr("修改"));
    CloseBtn=new QPushButton(tr("关闭"));
    QHBoxLayout *BtnLayout=new QHBoxLayout;
    BtnLayout->addStretch(1);
    BtnLayout->addWidget(AmendBtn);
    BtnLayout->addWidget(CloseBtn);

/*进行整体布局*/
    QVBoxLayout *RightLayout=new QVBoxLayout(this);
    RightLayout->setMargin(10);
    RightLayout->setSpacing(6);
    RightLayout->addWidget(stack);
    RightLayout->addLayout(BtnLayout);
之后再实现其它三个子窗口:
一、图形的绘制
1 绘图区实现

    
    
#include "paintarea.h" #include <Qpainter>
PaintArea::PaintArea(QWidget *parent) : QWidget(parent) {    setPalette(QPalette(Qt::white));    setAutoFillBackground(true);    setMaximumSize(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)     };//创建一个QPint的数组,包含四个点,为画多边形、多边线及点做准备。     int startAngle =30*16;//起始角(弧形的起始点与圆心之间的连线与水平方向的夹角);     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)     {     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 Point:         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;     } }
2 主窗口的实现
在里面实现了拓展对话框的功能:
MainWindow::MainWindow(QWidget *parent) : QWidget(parent) {     paintArea=new PaintArea;
    createBaseInfo();     createDetailInfo();     QVBoxLayout *rightlayout=new QVBoxLayout(this);     //layout->addWidget(paintArea);     rightlayout->addWidget(baseWidget);     rightlayout->addWidget(detailWidget);     rightlayout->setSizeConstraint(QLayout::SetFixedSize);//设置窗体的大小固定,不能利用拖拽改变大小,
//否则当再次单击“详细”按钮时,对话框不能恢复到初始状态。     rightlayout->setSpacing(10);     QHBoxLayout *mainLayout=new QHBoxLayout;//布局     mainLayout->addWidget(paintArea);     mainLayout->addLayout(rightlayout);     mainLayout->setStretchFactor(paintArea,1);     mainLayout->setStretchFactor(rightlayout,0);
createBaseInfo()函数完成部分信息窗体部分的构建,具体代码如下:
void MainWindow::createBaseInfo()
{
    //paintArea=new PaintArea;
    //QHBoxLayout *LeftLayout=new QHBoxLayout;
    //LeftLayout->addWidget(paintArea);




    baseWidget=new QWidget;
    QLabel *shapeLabel=new QLabel(tr("形状:"));
    QComboBox *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("Polyline"),PaintArea::Polyline);
    shapeComboBox->addItem(tr("Points"),PaintArea::Point);
    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)));


    QGridLayout *LeftLayout=new QGridLayout;
    LeftLayout->addWidget(shapeLabel,0,0);
    LeftLayout->addWidget(shapeComboBox,0,1);
    QPushButton *DetailBtn=new QPushButton(tr("详情"));
    QDialogButtonBox *btnBox=new QDialogButtonBox(Qt::Vertical);
    btnBox->addButton(DetailBtn,QDialogButtonBox::ActionRole);
    QHBoxLayout *mainLayout=new QHBoxLayout(baseWidget);
    //mainLayout->addWidget(paintArea);
   // mainLayout->addLayout(LeftLayout);
    mainLayout->addLayout(LeftLayout);
    //mainLayout->setStretchFactor(paintArea,1);
    //mainLayout->setStretchFactor(RightLayout,0);
    mainLayout->addWidget(btnBox);
    //
    connect(DetailBtn,SIGNAL(clicked()),this,SLOT(showDetailInfo()));
    //ShowShape(shapeComboBox->currentIndex());
}




createDetailInfo()函数实现其他信息窗体部分detailWidget的构建,并在函数的最后调用hide()隐藏此部分窗体,实现代码如下:
void MainWindow::createDetailInfo()
{
    detailWidget=new QWidget;
    QLabel *penColorLabel=new QLabel(tr("画笔颜色"));
    QFrame *penColorFrame=new QFrame;
    penColorFrame->setFrameStyle(QFrame::Panel|QFrame::Sunken);
    penColorFrame->setAutoFillBackground(true);
    penColorFrame->setPalette(QPalette(Qt::blue));

    QPushButton *penColorBtn=new QPushButton(tr("更改"));
    connect(penColorBtn,SIGNAL(clicked()),
            this,SLOT(ShowPenColor()));

    QLabel *penWidthLabel=new QLabel(tr("画笔线宽:"));
    QSpinBox *penWidthSpinBox=new QSpinBox;
    penWidthSpinBox->setRange(0,20);
    connect(penWidthSpinBox,SIGNAL(valueChanged(int)),
            this,SLOT(ShowPenWidth(int)));

    QLabel *penStyleLabel=new QLabel(tr("画笔风格:"));
    QComboBox *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)));

    QLabel *penCapLabel =new QLabel(tr("画笔顶帽:"));
    QComboBox *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)));

    QLabel *penJoinLabel =new QLabel(tr("画笔连接点:"));
    QComboBox *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)));

    QLabel *fillRuleLabel =new QLabel(tr("填充模式:"));
    QComboBox *fillRuleComboBox =new QComboBox;
    fillRuleComboBox->addItem(tr("Odd Even"),Qt::OddEvenFill);
    fillRuleComboBox->addItem(tr("Winding"),Qt::WindingFill);
    connect(fillRuleComboBox,SIGNAL(activated(int)),
                this,SLOT (ShowFillRule()));

    QLabel *spreadLabel =new QLabel(tr("铺展效果:"));
    QComboBox *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()));

    QLabel *brushColorLabel =new QLabel(tr("画刷颜色:"));
    QFrame *brushColorFrame =new QFrame;
    brushColorFrame->setFrameStyle(QFrame::Panel|QFrame::Sunken);
    brushColorFrame->setAutoFillBackground(true);
    brushColorFrame->setPalette(QPalette(Qt::green));

    QPushButton *brushColorBtn =new QPushButton(tr("更改"));
    connect(brushColorBtn,SIGNAL(clicked()),
                this,SLOT (ShowBrushColor()));

    QLabel *brushStyleLabel =new QLabel(tr("画刷风格:"));
    QComboBox *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("RadialGradientPattern"),
                      static_cast<int>(Qt:: RadialGradientPattern));
    brushStyleComboBox->addItem(tr("TexturePattern"),
                      static_cast<int>(Qt::TexturePattern));
    connect(brushStyleComboBox,SIGNAL(activated(int)),
                this,SLOT (ShowBrush(int)));


    QGridLayout *mainLayout=new QGridLayout(detailWidget);
    mainLayout->addWidget(penColorLabel,0,0);
    mainLayout->addWidget(penColorFrame,0,1);
    mainLayout->addWidget(penColorBtn,0,2);
    mainLayout->addWidget(penWidthLabel,1,0);
    mainLayout->addWidget(penWidthSpinBox,1,1);
    mainLayout->addWidget(penStyleLabel,2,0);
    mainLayout->addWidget(penStyleComboBox,2,1);
    mainLayout->addWidget(penCapLabel,3,0);
    mainLayout->addWidget(penCapComboBox,3,1);
    mainLayout->addWidget(penJoinLabel,4,0);
    mainLayout->addWidget(penJoinComboBox,4,1);
    mainLayout->addWidget(fillRuleLabel,5,0);
    mainLayout->addWidget(fillRuleComboBox,5,1);
    mainLayout->addWidget(spreadLabel,6,0);
    mainLayout->addWidget(spreadComboBox,6,1);
    mainLayout->addWidget(brushColorLabel,7,0);
    mainLayout->addWidget(brushColorFrame,7,1);
    mainLayout->addWidget(brushColorBtn,7,2);
    mainLayout->addWidget(brushStyleLabel,8,0);
    mainLayout->addWidget(brushStyleComboBox,8,1);
    
    //QHBoxLayout *mainLayout =new QHBoxLayout(this);

    //mainLayout->addLayout(rightLayout);
    //mainLayout->setStretchFactor(paintArea,1);
   // mainLayout->setStretchFactor(rightLayout,0);

    //ShowShape(shapeComboBox->currentIndex());

    detailWidget->hide();

}


showDetailInfo()函数完成窗体拓展切换工作,其具体代码如下:

void MainWindow ::showDetailInfo ()
{
    if(detailWidget->isHidden())
        detailWidget->show();
    else detailWidget->hide();
}
在主窗体实现过程中还有其它一些槽函数的调用,这里就不具体写出了。



二、双缓冲机制
1 绘图区实现
#include "drawwidget9.h"
#include <QtGui>
#include <QPen>
 
 
DrawWidget9::DrawWidget9(QWidget *parent) : QWidget(parent)
{
    setAutoFillBackground(true);//对窗体背景色的设置
    setPalette(QPalette(Qt::white));
    pix=new QPixmap(size());此QPixmap对象用来准备随时接收绘制的内容
    pix->fill(Qt::white);
    setMinimumSize(600,400);
 
}
 
void DrawWidget9::setStyle(int s)//线型风格
{
    style=s;
}
 
void DrawWidget9::setWidth(int w)//线宽
{
    weight=w;
}
 
void DrawWidget9::setColor(QColor c)//画笔颜色
{
    color=c;
}
 
void DrawWidget9::mousePressEvent(QMouseEvent *e)//按下事件mousePressEvent(),鼠标按下时,记录当前的鼠标位置值startPos。
{
    startPos=e->pos();
}
 
void DrawWidget9::mouseMoveEvent(QMouseEvent *e)
{
    QPainter *painter=new QPainter;
    QPen pen;
    pen.setStyle((Qt::PenStyle)style);
    pen.setWidth(weight);
    pen.setColor(color);
    painter->begin(pix);
    painter->setPen(pen);
 
    painter->drawLine(startPos,e->pos());
    painter->end();
    startPos=e->pos();
    update();
}
 
void DrawWidget9::paintEvent(QPaintEvent *)//完成绘图区的更新工作
{
    QPainter painter(this);
    painter.drawPixmap(QPoint(0,0),*pix);
}
 
void DrawWidget9::resizeEvent(QResizeEvent *event)//调整绘图区的大小
{
    if(height()>pix->height()||width()>pix->width())
    {
        QPixmap *newPix = new QPixmap(size());
        newPix->fill(Qt::white);
        QPainter p(newPix);
        p.drawPixmap(QPoint(0,0),*pix);
        pix = newPix;
    }
    QWidget::resizeEvent(event);
}
 
void DrawWidget9::clear()//完成绘图区的清除工作
{
    QPixmap *clearPix =new QPixmap(size());
    clearPix->fill(Qt::white);
    pix = clearPix;
    update();
}


 
2  主函数drawwidget的实现
DrawWidget::DrawWidget(QWidget *parent) : QMainWindow(parent){    drawWidget9 =new DrawWidget9;    //新建一个DrawWidget对象      setCentralWidget(drawWidget9); //新建的DrawWidget对象作为主窗口的中央窗体
      createToolBar();                //实现一个工具栏
      setMinimumSize(600,400);        //设置主窗口的最小尺寸
      ShowStyle();                    //初始化线型,设置控件中的当前值作为初始值      drawWidget9->setWidth(widthSpinBox->value());  //初始化线宽      drawWidget9->setColor(Qt::black);              //初始化颜色  }
 // DrawWidget::~DrawWidget()
  //createToolBar()函数完成工具栏的创建:  void DrawWidget::createToolBar()  {      QToolBar *toolBar = addToolBar("Tool");    //为主窗口新建一个工具栏对象
      styleLabel =new QLabel(tr("线型风格:"));    //创建线型选择控件      styleComboBox =new QComboBox;      styleComboBox->addItem(tr("SolidLine"),static_cast<int>(Qt::SolidLine));      styleComboBox->addItem(tr("DashLine"),static_cast<int>(Qt::DashLine));      styleComboBox->addItem(tr("DotLine"),static_cast<int>(Qt::DotLine));      styleComboBox->addItem(tr("DashDotLine"),static_cast<int>(Qt::DashDotLine));      styleComboBox->addItem(tr("DashDotDotLine"),static_cast<int>(Qt::DashDotDotLine));      connect(styleComboBox,SIGNAL(activated(int)),this,SLOT(ShowStyle())); //关联相应的槽函数
      widthLabel =new QLabel(tr("线宽:"));      //创建线宽选择控件      widthSpinBox =new QSpinBox;      connect(widthSpinBox,SIGNAL(valueChanged(int)),drawWidget9,SLOT(setWidth(int)));      colorBtn =new QToolButton;                  //创建颜色选择控件      QPixmap pixmap(20,20);      pixmap.fill(Qt::black);      colorBtn->setIcon(QIcon(pixmap));      connect(colorBtn,SIGNAL(clicked()),this,SLOT(ShowColor()));
      clearBtn =new QToolButton();                //创建清除按钮      clearBtn->setText(tr("清除"));      connect(clearBtn,SIGNAL(clicked()),drawWidget9,SLOT(clear()));
      toolBar->addWidget(styleLabel);      toolBar->addWidget(styleComboBox);      toolBar->addWidget(widthLabel);      toolBar->addWidget(widthSpinBox);      toolBar->addWidget(colorBtn);      toolBar->addWidget(clearBtn);  }
  void DrawWidget::ShowStyle()   //改变线型参数的槽函数ShowStyle()  {      drawWidget9->setStyle(styleComboBox->itemData(          styleComboBox->currentIndex(),Qt::UserRole).toInt());  }  void DrawWidget::ShowColor()   //设置画笔颜色的槽函数ShowColor()  {      QColor color = QColorDialog::getColor(static_cast<int>(Qt::black),this); //使用标准颜色对话框QColorDialog获得一个颜色值      if(color.isValid())      {          drawWidget9->setColor(color);          QPixmap p(20,20);          p.fill(color);          colorBtn->setIcon(QIcon(p));      }  }
三、显示SVG格式图片
         通过利用QSvgWidget类和QSvgRenDer类实现一个SVG图片浏览器,显示以“.svg”结尾的文件以介绍SVG格式图片显示的方法:
1   显示图片功能
//获得本窗体对象
SVGWidget ::SVGWidget ( QWidget *parent )
     :QSvgWidget(parent)
{
    render=renderer();
 
}


//以下是鼠标滚轮的响应事件,使SVG图片能够通过鼠标滚轮的滚动进行缩放,具体的代码如下:
void SVGWidget::wheelEvent(QWheelEvent *e)
{
    const double diff=0.1;
    QSize size =render->defaultSize();
    int width =size.width();
    int height =size.height();
    if(e->delta()>0)
    {
        width =int(this->width()+this->width()*diff);
        height =int(this->height()+this->height()*diff);
    }
    else
    {
        width =int(this->width()-this->width()*diff);
        height =int(this->height()-this->height()*diff);
    }
    resize(width,height);
}

2   图片在放大到超过主窗口的大小时,能够通过拖拽滚动条的方式进行查看

#include "svgtest.h"
 
 
 
 
SVGTest::SVGTest(QWidget *parent)
 
 
    :QScrollArea(parent)
{
    svgWidget =new SVGWidget;
    setWidget(svgWidget);
}
 
 
void SVGTest::setFile(QString fileName)//文件进行了选择或修改时,调用setFile()函数设置新的文件
{
    svgWidget->load(fileName);//将新的SVG文件加载到svgWidget中进行显示
    QSvgRenderer *render =svgWidget->renderer();
    svgWidget->resize(render->defaultSize());
}
 
 
void SVGTest::mousePressEvent(QMouseEvent *event)
{
    mousePressPos =event->pos();
    scrollBarValuesOnMousePress.rx()=horizontalScrollBar()->value();
    scrollBarValuesOnMousePress.ry()=verticalScrollBar()->value();
    event->accept();
}
 
 
void SVGTest::mouseMoveEvent(QMouseEvent *event)
{
    horizontalScrollBar()->setValue(scrollBarValuesOnMousePress.x()-event->pos().x()+mousePressPos.x());	//对水平滑动条的新位置进行设置
    verticalScrollBar()->setValue(scrollBarValuesOnMousePress.y()-event->pos().y()+mousePressPos.y());      //对垂直滑动条的新位置进行设置
    horizontalScrollBar()->update();
    verticalScrollBar()->update();
    event->accept();
}

3  创建一个SvgWindow对象作为主窗口的中央窗体

MainWindow2 ::MainWindow2 ( QWidget *parent )
    : QMainWindow(parent)
{
    setWindowTitle(tr("SVG Viewer"));
    createMenu();
    svgTest=new SVGTest;
    setCentralWidget(svgTest);
 
 
}
 
 
void MainWindow2::createMenu()//创建菜单栏
{
    QMenu *fileMenu=menuBar()->addMenu(tr("文件"));
    QAction *openAct=new QAction(tr("打开"),this);
    connect(openAct,SIGNAL(triggered()),this,SLOT(slotOpenFile()));
    fileMenu->addAction(openAct);
}
 
 
void MainWindow2::slotOpenFile()
{
    QString name=QFileDialog::getOpenFileName(this,
                               "打开","/","svg files(*.svg)");
    svgTest->setFile(name);
}
 



这篇博客写的有点差,好多东西都不会,自己也没有那么耐心细致的去弄,觉得特别的惭愧。。。最近要忙别的事了,不知道什么时候能把它改改,或者开始写下一篇呢?好希望自己能在这条路上越走越远。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值