qt界面样式设置,qt打开新窗口及设置,opencv基础函数

该demo项目包含的知识:菜单栏设置,菜单栏图标设置,菜单栏打开新窗口(界面打开新窗口可以借鉴),以及将新窗口设置成表格,label各种设置,button各种设置,几种信号槽连接,打开图片,显示图片,状态栏,opencv图片转换(mat-Qimage),打开相机,以及处理图片的几种函数(灰度图,二值化,高斯滤波,边缘检测,像素输出)

可以将代码复制编译后在慢慢看。

 interface_vs.h:

#pragma once

#include <QtWidgets/QMainWindow>
#include "ui_interface_vs.h"
#include <QMenuBar>
#include <QLabel>
#include <QPushButton>
#include <QSlider>
#include<opencv2/opencv.hpp>
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/videoio/videoio.hpp"

#include <QWidget>
#include "newWindowClass.h"

using namespace cv;
using namespace std;
#pragma once
#pragma execution_character_set("utf-8")
class interface_vs : public QMainWindow
{
    Q_OBJECT

public:
    interface_vs(QWidget *parent = nullptr);
    ~interface_vs();
    //菜单栏
    QMenuBar *pMenuBar;
    //菜单项
    QMenu *pMenuTest;
    QMenu *pMenuTest1;
    QMenu *pMenuTest2;
    //子菜单
    QAction *pActionTest;
    QAction *pActionTest1;
    QAction *pActionTest2;
    QAction *pActionTest3;
    QAction *pActionTest4;
    QAction *pActionTest5;
    QAction *pActionTest6;

    QLabel *label;
    QLabel *label1;
    QLabel *label2;
    QLabel *label3;

    QPushButton * pButton;
    QPushButton * pButton1;
    QPushButton * pButton2;

    QSlider *slider;

    QPushButton * pButton3;
    QPushButton * pButton4;
    QPushButton * pButton5;
    QPushButton * pButton6;
    QPushButton * pButton7;

    QPushButton *btn_language;

    

public slots:
    //菜单响应函数
    void OnActionTest();
    void OnActionTest1();

    void ClickButton();
    void ClickButton1();
    void ClickButton2();
    void SliderChangeImageshow(int a);

    void OpenCamera();
    void print_px_value(Mat& im);
    void ShowPoint();
    void New_algorithm();
    void cvt();
    void vi();
    void newWindow();
private:
    newWindowClass * nw;
    Ui::interface_vsClass ui;
};
 

interface_vs.cpp:

#include "interface_vs.h"
#include "opencv2/opencv.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/videoio/videoio.hpp"
#include <QDialog>
#include <QFileDialog>
#include <QDebug>
#include <QMessageBox>
#include <qvector.h>
#include <QHeaderView>

QString image_address;
Mat After_processing;//处理后的图片
interface_vs::interface_vs(QWidget *parent)
    : QMainWindow(parent)
{
    ui.setupUi(this);
    //指定菜单栏
#ifdef USE_DEFAULT_MENU_BAR
    //添加菜单栏(此处添加为的为QMainWindow自带的菜单)
    pMenuBar = this->menuBar();
#else
    //添加自定义菜单
    pMenuBar = new QMenuBar(this);
#endif

    //定义菜单项
    //(&n)代表快捷方式,当窗口获得焦点时按alt+n即可打开“菜单”菜单项
    pMenuTest = new QMenu("菜单", this);
    pMenuTest1 = new QMenu("test1",this);
    pMenuTest2 = new QMenu("test2",this);

    //定义子菜单
    //(&s)为子菜单快捷键,当打开该菜单项后,按下‘s’键即可响应
    pActionTest = new QAction("打开新窗口", this);
    //新建一个带图标的菜单项,图标使用资源文件中的资源
    pActionTest1 = new QAction(QIcon("C:\\Users\\25125\\Desktop\\1.jpg"), "打开图片", this);
    //pActionTest2 = new QAction("测试2",this);
    pActionTest3 = new QAction("exit", this);
    pActionTest4 = new QAction("测试", this);
    pActionTest5 = new QAction("测试", this);
    pActionTest6 = new QAction("测试", this);
    //将菜单项添加到子菜单
    pMenuTest->addAction(pActionTest);
    pMenuTest->addAction(pActionTest1);
    //在菜单项之间添加分割线
    pMenuTest->addSeparator();
    //pMenuTest->addAction(pActionTest2);
    pMenuTest->addAction(pActionTest3);

    pMenuTest1->addAction(pActionTest4);

    pMenuTest2->addAction(pActionTest5);
    pMenuTest2->addAction(pActionTest6);

    //将子菜单添加到菜单栏
    pMenuBar->addMenu(pMenuTest);
    pMenuBar->addMenu(pMenuTest1);
    pMenuBar->addMenu(pMenuTest2);

    this->setMaximumSize(1600, 1200);
    this->setMinimumSize(1200, 1000);
    this->setWindowTitle("菜单项");

    QToolBar *toolbar = new QToolBar(this);
    addToolBar(Qt::TopToolBarArea, toolbar);
    toolbar->addAction("新建");
    toolbar->addSeparator();
    toolbar->addAction("打开");
    toolbar->addSeparator();
    toolbar->addAction("关闭");

    //显示图片label
    label = new QLabel(this);
    label->move(5, 100);                                //将标签移动到(0,100)位置
    label->resize(200, 160);                            //设定标签大小
    label->setStyleSheet("border:1px solid black");
    //显示文字label
    label1 = new QLabel(this);
    label1->setText(tr("显示图片"));                    //文本label
    label1->move(50, 280);
    //setCentralWidget(label); label居中
    //显示处理后图片的label
    label2 = new QLabel(this);                         //处理后label显示
    label2->move(500, 100);
    label2->resize(200, 160);
    label2->setStyleSheet("border:1px solid black");

    label3 = new QLabel(this);
    label3->move(800, 100);
    label3->resize(200, 100);
    label3->setStyleSheet("border:1px solid black");
    
    //label3->setWordWrap(true);
    //opencv高斯处理
    pButton = new QPushButton(this);
    pButton->move(220, 100);
    pButton->setText("高斯处理");
    //二值化
    pButton1 = new QPushButton(this);
    pButton1->move(220, 140);
    pButton1->setText("二值化(80)");
    //滑动条设置二值化值 
    slider = new QSlider(Qt::Horizontal, this);    //Qt::Horizontal设置为水平的滑动条
    //设置滑动条样式
    slider->setStyleSheet("QSlider::groove:horizontal{height:12px; left:0px; right:0px; border:0px; border-radius:6px; background:rgb(242,242,242);}    \
                           QSlider::handle:horizontal{width:24px; background:#1644B0; border-radius:12px; margin:-6px 0px;}  \
                           QSlider::sub-page:horizontal{background:#4C85FB; border:0px; border-radius:6px;}");
    slider->move(220, 180);//设置滑动条位置
    slider->setRange(0, 255);//设置滑动条取值范围
    slider->setFixedWidth(255);//设置滑动条长度
    //opencv边缘检测
    pButton2 = new QPushButton(this);
    pButton2->move(220, 220);
    pButton2->setText("canny");

    //opencv打开相机
    pButton3 = new QPushButton(this);
    pButton3->setText("打开相机");
    pButton3->move(5, 400);
        //给按钮设置图案
        QIcon icon(".\\ico\\U2.png");    //创建icon对象,保存相对应的图片路径。
        btn_language = new QPushButton(this);    //创建button对象
        btn_language->move(120, 400);
        btn_language->setFixedSize(100, 40); //设置按钮宽高
        //btn_language->setIcon(icon);//将图片填充进按钮中
        btn_language->setIcon(icon);//将图片填充进按钮中
        btn_language->setIconSize(QSize(btn_language->width(), btn_language->height()));//让图片的尺寸和按钮对应
        QImage image = QImage("C:\\MyGit\\mms_v2\\mms_v2\\mms_v2\\ico\\U2.png");
        label->setPixmap(QPixmap::fromImage(image));
        label->setScaledContents(true);//图片自适应大小

    pButton4 = new QPushButton(this);
    pButton4->move(220, 250);
    pButton4->setText("显示像素");

    pButton5 = new QPushButton(this);
    pButton5->setText("New_algorithm");
    pButton5->move(220, 300);
    pButton5->adjustSize();

    pButton6 = new QPushButton(this);
    pButton6->setText("灰度图");
    pButton6->move(220, 330);
    pButton6->adjustSize();

    pButton7 = new QPushButton(this);
    pButton7->setText("暂计数");
    pButton7->move(220, 370);
    pButton7->adjustSize();
    //QPixmap Images("C:/Users/25125/Pictures/Saved Pictures/hp/aa.jpg");
    //QPalette Palette = this->palette();//设置背景图
    //Palette.setBrush(QPalette::Background, Images);
    //this->setPalette(Palette);


    


#ifndef USE_DEFAULT_MENU_BAR
    //当不使用QMainWindow自带的菜单栏时,必须要加上此行
    setMenuBar(pMenuBar);
#endif

    //添加菜单响应函数
    connect(pActionTest, &QAction::triggered, this, &interface_vs::newWindow);
    connect(pActionTest3, &QAction::triggered, this, &interface_vs::OnActionTest);
    connect(pActionTest1, &QAction::triggered, this, &interface_vs::OnActionTest1);

//按钮响应函数
    connect(pButton, SIGNAL(clicked()), this, SLOT(ClickButton()));
    connect(pButton1, SIGNAL(clicked()), this, SLOT(ClickButton1()));
    connect(pButton2, SIGNAL(clicked()), this, SLOT(ClickButton2()));

//滑动条响应函数
    connect(slider, SIGNAL(valueChanged(int)), this, SLOT(SliderChangeImageshow(int)));
    connect(pButton3, SIGNAL(clicked()), this, SLOT(OpenCamera()));
    connect(pButton4, SIGNAL(clicked()), this, SLOT(ShowPoint()));
    connect(pButton5, SIGNAL(clicked()), this, SLOT(New_algorithm()));
    connect(pButton6, SIGNAL(clicked()), this, SLOT(cvt()));
    connect(pButton7, SIGNAL(clicked()), this, SLOT(vi()));
}


//菜单exit响应函数
void interface_vs::OnActionTest()
{
    QApplication *app;
    app->quit();
}


void interface_vs::newWindow() {
    nw = new newWindowClass();
    //设置几行几列
    nw->setRowAndCol(3, 5);
    //设置表格中每一行的表头
    QStringList header;
    header << "1" << "2" << "3" << "4" << "5";
    nw->setHorizontalHeaderLabels(header);
    //3行5列
    for (int i = 0; i < 3; i++)
        for (int j = 0; j < 5; j++)
        {
            QTableWidgetItem *item = new QTableWidgetItem(QIcon(":/image/search.png"), "td");
            nw->setItem(i, j, item);
        }

    nw->setMinimumSize(600, 400);
    nw->setWindowTitle("表格");
    nw->show();

}


//灰度图
void interface_vs::cvt() {
    Mat srcimage = imread(image_address.toStdString());//原始图片的路径来自于打开图片
    //变为灰度图
    cvtColor(srcimage, srcimage, COLOR_BGR2GRAY);
    After_processing = srcimage;
    QImage twoImage = QImage((const unsigned char*)(srcimage.data), srcimage.cols, srcimage.rows, QImage::Format_Grayscale8);
    twoImage = twoImage.scaled(label2->width(), label2->height());
    label2->setPixmap(QPixmap::fromImage(twoImage));
}

//该函数是之前项目设计算法时用到,可以不看
//遍历像素,连续的存入vector<int>中 
void interface_vs::vi() {
    Mat srcimage = imread(image_address.toStdString());//原始图片的路径来自于打开图片
    Mat originImg;
    //变为灰度图
    cvtColor(srcimage, originImg, COLOR_BGR2GRAY);


    vector<vector<int>> vv;
    int t_count = 0;//暂存数
    int rowNumber = originImg.rows;  //行数
    int colNumber = originImg.cols * originImg.channels();  //列数 x 通道数=每一行元素的个数
    //双重循环,遍历所有的像素值
    for (int i = 0; i < rowNumber; i++)  //行循环
    {
        //每张图片进来都会先找自己的暂存数,所以可以另外写一个函数做下面的操作 需要的参数:i,originImg,colNumber,返回值是vector<vector<int>>类型


            vector<int> ve;
            uchar* data = originImg.ptr<uchar>(i);  //获取第i行的首地址
            for (int j = 0; j < colNumber; j++)   //列循环
            {
                //data[j] = data[j] / div * div + div / 2;
                int a = 0;
                if ((int)data[j] >= 0 && (int)data[j] < 200) {//比较拿到黑色像素的
                    if (ve.empty()) {
                        ve.push_back(j);//记录位置而不是像素值
                        continue;
                    }
                    else {
                        for (int k = 0; k < ve.size(); k++) {
                            if (j == ve.at(k) + 1) {
                                ve.push_back(j);
                                a = 1;
                            }
                        }
                        if (a) {
                            a = 0;
                            continue;
                        }
                        vv.push_back(ve);
                        t_count++;//暂存计数
                        ve.clear();
                        ve.push_back(j);

                    }
                }
            }  //行处理结束
        

        }
        
    
    //遍历vector
    QString text;
    
    for (int k = 0; k < vv.size(); k++) {
        text += "(";
        for (int t = 0;t<vv.at(k).size();t++) {
            text += QString::number(vv.at(k).at(t));
        }
        text += ")";
    }
    label3->setText("暂计数:" + QString::number(t_count)+":"+ text);
    label3->adjustSize();
}


void interface_vs::New_algorithm(){
    Mat srcimage = imread(image_address.toStdString());//原始图片的路径来自于打开图片
    Mat originImg, binaryImage;
    //变为灰度图
    cvtColor(srcimage, originImg, COLOR_BGR2GRAY);
    QString text;

    vector<int> ve;
    vector<vector<int>> vv;
    int count = 0;//计数
    //遍历像素
    int rowNumber = originImg.rows;  //行数
    int colNumber = originImg.cols * originImg.channels();  //列数 x 通道数=每一行元素的个数
    //双重循环,遍历所有的像素值
    for (int i = 0; i < rowNumber; i++)  //行循环
    {

        uchar* data = originImg.ptr<uchar>(i);  //获取第i行的首地址
        for (int j = 0; j < 1; j++)   //列循环
        {
            //data[j] = data[j] / div * div + div / 2;
            if ((int)data[j] > 0 && (int)data[j] < 255) {//比较拿到黑色像素的
                ve.push_back((int)data[j]);
                count++;
            }
        }  //行处理结束
    }
    //遍历vector
    for (int k = 0; k < ve.size(); k++) {
        text += QString::number(ve.at(k))+",";
    }
    label3->setText(QString::number((int)ve.size())+";"+QString::number(count)+":"+text);
    label3->adjustSize();
}


//菜单打开图片响应函数
void interface_vs::OnActionTest1()
{

    QString filename = QFileDialog::getOpenFileName(this, tr("Open Image"), QDir::homePath(), tr("(*.jpg)\n(*.bmp)\n(*.png)"));   //打开图片文件,选择图片
    image_address = filename;
    qDebug() << "filename:" << filename;
    QImage image = QImage(filename);   //图片初始化
    qDebug() << "image:" << image;
    if (!image.isNull())
    {
        label->setPixmap(QPixmap::fromImage(image));
        label->setScaledContents(true);//图片自适应大小
        //label->show();
        ui.statusBar->showMessage(tr("Open Image Success!"), 3000); //打开成功时显示的内容

    }
    else
    {
        ui.statusBar->showMessage(tr("Save Image Failed!"), 3000);
        return;
    }

    //     QDialog dlg;
    //     dlg.setWindowTitle("测试菜单响应");
    //     dlg.exec();
}

void interface_vs::print_px_value(Mat& im)
{
    QString text;
    int rowNumber = im.rows;  //行数
    int colNumber = im.cols * im.channels();  //列数 x 通道数=每一行元素的个数
    text = QString::number(rowNumber) + "行;" + QString::number(colNumber)+"列";
    //双重循环,遍历所有的像素值
    for (int i = 0; i < rowNumber; i++)  //行循环
    {
        uchar* data = im.ptr<uchar>(i);  //获取第i行的首地址
        text += "<br>"+QString::number(i) + ":";
        for (int j = 0; j < colNumber; j++)   //列循环
        {
            //data[j] = data[j] / div * div + div / 2;
            text += QString::number((int)data[j])+",";
        }  //行处理结束
    }
    label3->setText(text);
    label3->adjustSize();   //自适应大小
}


//高斯滤波按钮响应函数
void interface_vs::ClickButton() {
    //读取原始图片
    if (image_address == "") {
        QMessageBox::critical(NULL, "警告", "未打开任何图片", QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
        return ;
    }

    Mat srcimage = imread(image_address.toStdString());//原始图片的路径来自于打开图片
    //Mat转QImage 颜色
    cvtColor(srcimage, srcimage, COLOR_BGR2RGB);
    //Mat转QImage 像素  oldlabel放置原图
    QImage disimage = QImage(srcimage.data, srcimage.cols, srcimage.rows, srcimage.cols*srcimage.channels(), QImage::Format_RGB888);

    Mat retimage;
    //高斯模糊
    GaussianBlur(srcimage, retimage, Size(3, 5), 0, 0);//高斯核的大小必须是奇数(size中两数的乘积必须为奇数)
    //GaussianBlur(retimage, retimage, Size(9, 9), 0, 0);
    After_processing = retimage;
    //Mat转QImage 像素  newlabel放置图像处理后图片
    QImage disimage2 = QImage(retimage.data, retimage.cols, retimage.rows, retimage.cols*retimage.channels(), QImage::Format_RGB888);
    disimage2 = disimage2.scaled(label2->width(), label2->height());
    label2->setPixmap(QPixmap::fromImage(disimage2));
}

//二值化
void interface_vs::ClickButton1() {
    //读取原始图片
    if (image_address == "") {
        QMessageBox::critical(NULL, "警告", "未打开任何图片", QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
        return;
    }
    Mat srcimage = imread(image_address.toStdString());//原始图片的路径来自于打开图片

    Mat originImg, binaryImage;
    cvtColor(srcimage, originImg, COLOR_BGR2GRAY);
    //imshow("src",originImg);
//       QImage orImg = QImage((const unsigned char*)(originImg.data),
//       originImg.cols, originImg.rows, QImage::Format_Grayscale8);
       //QImage orImg = QImage(originImg.data,originImg.cols,originImg.rows,originImg.cols*originImg.channels(),QImage::Format_RGB888);
    threshold(originImg, binaryImage, 80, 255.0, THRESH_BINARY);
    After_processing = binaryImage;
    QImage twoImage = QImage((const unsigned char*)(binaryImage.data), binaryImage.cols, binaryImage.rows, QImage::Format_Grayscale8);
    twoImage = twoImage.scaled(label2->width(), label2->height());
    label2->setPixmap(QPixmap::fromImage(twoImage));
    //               //存储二值化后的图像
    //                Mat binaryImage;
    //               //-------初始的二值化阈值为80
    //               threshold(binaryImage, srcimage, 80, 255.0, THRESH_BINARY);
    //               //QImage twoImage = QImage((const unsigned char*)(binaryImage.data),binaryImage.cols, binaryImage.rows, QImage::Format_Grayscale8);
    //               QImage twoImage = QImage(binaryImage.data,binaryImage.cols,binaryImage.rows,binaryImage.cols*binaryImage.channels(),QImage::Format_RGB888);
    //               label2->setPixmap(QPixmap::fromImage(twoImage));

}
//滑动条控制二值化
void interface_vs::SliderChangeImageshow(int a) {
    int thres = a;
    qDebug() << thres;
    if (image_address == "") {
        QMessageBox::critical(NULL, "警告", "未打开任何图片", QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
        return;
    }
    Mat srcimage = imread(image_address.toStdString());
    Mat binaryImage;
    cvtColor(srcimage, srcimage, COLOR_BGR2GRAY);
    threshold(srcimage, binaryImage, thres, 255.0, THRESH_BINARY);
    After_processing = binaryImage;
    QImage twoImage = QImage((const unsigned char*)(binaryImage.data), binaryImage.cols, binaryImage.rows, QImage::Format_Grayscale8);
    twoImage = twoImage.scaled(label2->width(), label2->height());
    label2->setPixmap(QPixmap::fromImage(twoImage));

}
//边缘检测
void interface_vs::ClickButton2() {
    if (image_address == "") {
        QMessageBox::critical(NULL, "警告", "未打开任何图片", QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
        return;
    }
    Mat srcimage = imread(image_address.toStdString());
    Mat edgeImg;
    Canny(srcimage, edgeImg, 30, 80);
    After_processing = edgeImg;
    QImage twoImage = QImage((const unsigned char*)(edgeImg.data), edgeImg.cols, edgeImg.rows, QImage::Format_Grayscale8);
    label2->setPixmap(QPixmap::fromImage(twoImage));
}

//使用opencv调用摄像头
void  interface_vs::OpenCamera() {
    Mat frame;
    VideoCapture cap(0);//摄像头调用

    int race = 0;
    while (cap.read(frame))
    {

        if (race == 1) {
            break;
        }
        imshow("frame", frame);
        race = 1;
        waitKey(1000);
    }


    namedWindow("Vidio", 1);
}

//显示处理后图片的像素
void interface_vs::ShowPoint() {
    if (After_processing.data == 0) {
        QMessageBox::critical(NULL, "警告", "没有未处理后的图片", QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
        return;
    }
    print_px_value(After_processing);
}

interface_vs::~interface_vs()
{}
 

newWindowClass.h:

#pragma once

#include <QWidget>
#include "ui_newWindowClass.h"

#include <QTableWidget>
#pragma execution_character_set("utf-8")
class newWindowClass : public QTableWidget
{
    Q_OBJECT

public:
    newWindowClass(QWidget *parent = nullptr);
    ~newWindowClass();
    QTableWidget *tableWidget;


    void setRowAndCol(int row, int col);

private:
    Ui::newWindowClassClass ui;
};
 

newWindowClass.cpp

#include "newWindowClass.h"

#include <QMessageBox>
#include <QHeaderView>
#include <QMouseEvent>
#include <QDebug>

newWindowClass::newWindowClass(QWidget *parent)
    : QTableWidget(parent)
{
    this->setFont(QFont("微软雅黑", 12));


    this->setShowGrid(false);    //不显示网格线
    this->setSelectionBehavior(QAbstractItemView::SelectRows);   //设置整行选择
    this->setMouseTracking(true);    //开启捕获鼠标功能
    this->setEditTriggers(QAbstractItemView::NoEditTriggers);    //禁止编辑表格
    this->verticalHeader()->setVisible(false);//纵向表头可视化
    this->horizontalHeader()->setStyleSheet("QHeaderView::section {""background-color:#383838;}");
    this->setStyleSheet("background-color:#1a1a1a;color:#fff;gridline-color: rgb(0, 0, 0)");//设置当前颜色
    this->horizontalHeader()->setDefaultSectionSize(120);  //设置默认宽度  不设置的话宽度也会平均分配 但不会按照窗口宽度分配
    this->verticalHeader()->setDefaultSectionSize(30);   //设置一行默认高度

//    this->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);//自适应所有列,让它布满空间。设置了就列就不能拉伸
//    this->horizontalHeader()->resizeSections(QHeaderView::Stretch);//列可以拉伸

    this->horizontalHeader()->setStretchLastSection(true);//最后一列铺满

    this->setAlternatingRowColors(true);// 设置隔行背景色
    this->setPalette(QPalette(QColor(70, 70, 70)));//参数还可写成QPalette(Qt::blue) QPalette(QColor(36,36,36))
    this->setStyleSheet("selection-background-color:#0e4b72");  //设置选中行颜色


//    this->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);//设置水平滚动条
//    this->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);//设置垂直滚动条

}

void newWindowClass::setRowAndCol(int row, int col) {
    this->setRowCount(row);   //设置行数为10
    this->setColumnCount(col); //设置列数为5
}

newWindowClass::~newWindowClass()
{}
 

效果展示:

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值