Qt相关知识

2 篇文章 0 订阅

组件

QPushButton

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QPushButton>
#include <QDebug>

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = 0);
    ~Widget();
private slots:
    void buttonClick();
private:
    QPushButton *btn;
};


#endif // WIDGET_H
#include "widget.h"


Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    this->setFixedSize(960,640);//设置固定大小

//    this->showFullScreen();//全屏显示

    this->setWindowTitle("应用程序");


    btn = new QPushButton("按钮",this);//构造按钮且指定父对象this

    btn->setParent(this);//设置父对象this

    btn->setText("点击");//设置按钮显示文本内容

    btn->setToolTip("按钮");//设置按钮的提示信息

    btn->setFixedSize(100,50);//设置大小

    btn->move((this->width()-btn->width())/2,(this->height()-btn->height())/2);//移动距离

    btn->setGeometry(480-50,320-25,100,50);//设置位置及大小

    /*
     * qt工程导入图片,作为资源图片
     * 将需要的图片拷贝到项目工程代码目录
     * 在IDE中选中项目分组名,右键选择“添加新文件”
     * 选择添加的新文件模板为qt-->qt source file
     * 在资源管理界面,点击 添加-->添加前缀,前缀默认为/prefix/改为/
     * 在资源管理界面点击 添加-->添加文件,选中图片
     * ctrl+s保存
     */

    //btn->setIcon(QIcon(":/img/1.png"));// :为资源文件 /代表前缀

    this->setWindowIcon(QIcon(":/img/1.png"));

    btn->setStyleSheet("border-image:url(:/img/1.png);");//设置样式表,用于美化界面

    btn->x();
    btn->y();
    btn->pos();



    QPushButton *btn1 = new QPushButton(QIcon(":/img/1.png"),"click",this);

    /*
     * qt内存回收机制:
     * 凡是从QObject派生的子类对象,其内存资源都由父对象管理
     * 因此构造控件时,不需要手动回收资源,当父对象声明周期结束,自动回收资源
     */

    /*
     * 将btn触发的click信号与this对象的buttonClick进行关联
     * 旧风格
    */
    connect(btn,SIGNAL(clicked(bool)),this,SLOT(buttonClick()) );//参数:发送者(事件触发对象首地址),信号类型,接收者(槽函数所属对象首地址),槽函数名,连接方式
    connect(btn1,SIGNAL(clicked(bool)),this,SLOT(buttonClick()) );

    /*
     *  一个控件的一个信号可以 关联多个槽函数
     * 槽函数的参数个数应该小于等于信号的参数个数
     * 槽函数的参数类型必须与信号的参数类型保持一致
    */
}


void Widget::buttonClick()
{
    qDebug() << "hello world";
}

Widget::~Widget()
{

}

QLabel

#ifndef WIDGET_H
#define WIDGET_H
#include <QPushButton>
#include <QLabel>
#include <QMovie>

#include <QWidget>

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = 0);
    ~Widget();
private slots:
    void btn_click();
private:
    QLabel *lab;
    QPushButton *btn;
};

#endif // WIDGET_H
#include "widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    this->setFixedSize(960,640);

    lab = new QLabel;
    btn = new QPushButton;

    this->lab->setParent(this);
    this->btn->setParent(this);

    this->lab->setFixedSize(950,500);
    this->btn->setFixedSize(100,50);

    this->btn->setText("点击");
    this->lab->setStyleSheet("background-color:green;");

    this->lab->setAlignment(Qt::AlignCenter|Qt::AlignHCenter);//设置文字对齐方式

    this->lab->move(5,5);
    this->btn->move((this->width()-this->btn->width())/2,this->lab->height()+50);

     //connect(btn,SIGNAL(clicked(bool)),this,SLOT(btn_click()));

    /*
     * 手动关联新式风格
     * 说明触发的信号来自于哪一个类,编译时会进行类型的安全性检查
    */
     connect(btn,&QPushButton::clicked,this,&Widget::btn_click);
}

void Widget::btn_click()
{
    this->lab->setText("hello world");

    this->lab->setPixmap(QPixmap("1.png").scaled(lab->width(),lab->height()));//构建目录//设置label的内容为pixmap绘图
    this->lab->setPixmap(QPixmap("1.png"));

//    QMovie *move = new QMovie("3.gif");
//    this->lab->setMovie(move);
//    move->start();

    QMovie *move = new QMovie();//动态图片
    move->setFileName("3.gif");
    lab->setMovie(move);
    move->start();
}

Widget::~Widget()
{

}

QLineEdit

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

private:
    Ui::Widget *ui;
private slots:
    void textChanged(QString text);
    void returnPressed();
};

#endif // WIDGET_H
#include "widget.h"
#include "ui_widget.h"
#include "widget.h"


Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    this->setFixedSize(640,480);

    ui->lineEdit->setFixedSize(200,40);

    ui->lineEdit_2->setFixedSize(ui->lineEdit->size());
    ui->lineEdit_2->move(ui->lineEdit->x(),ui->lineEdit->y()+ui->lineEdit->height()+10);

    ui->lineEdit_3->setFixedSize(ui->lineEdit->size());
    ui->lineEdit_3->move(ui->lineEdit->x(),ui->lineEdit_2->y()+ui->lineEdit_2->height()+10);

    //设置提示信息
    ui->lineEdit->setPlaceholderText("用户名");
    ui->lineEdit_2->setPlaceholderText("密码");
    ui->lineEdit_3->setPlaceholderText("验证码");

    ui->lineEdit->setAlignment(Qt::AlignRight);//向右对齐
    ui->lineEdit_2->setAlignment(Qt::AlignRight);//向右对齐
    ui->lineEdit_3->setAlignment(Qt::AlignRight);//向右对齐

    ui->lineEdit_2->setEchoMode(QLineEdit::Password);//设置显示模式 Password 密码模式
    ui->lineEdit_3->setEchoMode(QLineEdit::PasswordEchoOnEdit);//PasswordEchoOnEdit 当控件丢失焦点,控件由明文转为暗纹,且不可修改,修改会直接删除

    //由于QLineEdit::textChanged(Qstring)信号带了参数,信号触发时传递出文本数据
    //控件之间进行数据的传递,需要信号与槽来实现,不同类型的对象之间进行数据传递,也可使用信号与槽
    //当槽函数被重载后,关联信号会产生歧义
    connect(ui->lineEdit,&QLineEdit::textChanged,this,&Widget::textChanged);

    //connect(ui->lineEdit,&QLineEdit::textChanged,this,static_cast<void Widget::textChanged(QString)>&Widget::textChanged);

    connect(ui->lineEdit_2,&QLineEdit::returnPressed,this,&Widget::returnPressed);

    //信号与槽关联方式,lamda表达式,匿名函数
    //[]:代表函数名 ():代表参数列表 {}:代表函数体 &:引用匿名函数 =:将会拷贝当前类的所有数据
    connect(ui->lineEdit_3,&QLineEdit::selectionChanged,this,[&](){
        ui->label->setText(ui->lineEdit_3->selectedText());
    });
}

Widget::~Widget()
{
    delete ui;
}

void Widget::textChanged(QString text)
{
    ui->label->setText(text);
}

void Widget::returnPressed()
{
    ui->label->setText(ui->lineEdit_2->text());
}

QCheckBox

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

private:
    Ui::Widget *ui;
};

#endif // WIDGET_H
#include "widget.h"
#include "ui_widget.h"

#include <QDebug>
Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    //当用户勾选或取消时,触发stateChanged(int)信号
    connect(ui->checkBox,&QCheckBox::stateChanged,this,[&](int state){
       qDebug() << state;
//       if(state == Qt::Checked)
//       {
//           ui->lineEdit->setText("勾选");//state == 2
//       }
//       else if(state == Qt::Unchecked)
//       {
//           ui->lineEdit->setText("未勾选");//state == 0
//       }
    });

    connect(ui->pushButton,&QPushButton::clicked,this,[&](){
        if(ui->checkBox->isChecked())//判断复选框是否被选中,选中返回true
        {
            ui->label->setText(ui->lineEdit->text());
        }
        else
        {
            //ui->checkBox->setChecked(true);//设置为勾选,不更改内部状态
            ui->checkBox->setCheckState(Qt::Checked);//设置为勾选,更改内部状态
        }

    });
}

Widget::~Widget()
{
    delete ui;
}

QRadioButton

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QGroupBox>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

private slots:
    void on_pushButton_clicked();

private:
    Ui::Widget *ui;
};

#endif // WIDGET_H
#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
}

Widget::~Widget()
{
    delete ui;
}

void Widget::on_pushButton_clicked()
{
    if(ui->radioButton->isChecked())//isChecked判断单选按钮是否被选中
    {
        ui->label->setText("A");
    }
    if(ui->radioButton_2->isChecked())
    {
        ui->label->setText("B");
    }
    if(ui->radioButton_3->isChecked())
    {
        ui->label->setText("C");
    }
    if(ui->radioButton_4->isChecked())
    {
        ui->label->setText("D");
    }
    QGroupBox group;
}

其他

QLayout

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QPushButton>
#include <QTextEdit>
#include <QLayout>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

private:
    Ui::Widget *ui;
private:
    QPushButton *btn_1;
    QPushButton *btn_2;
    QPushButton *btn_3;
    QPushButton *btn_4;
    QPushButton *btn_5;

    QTextEdit *text;

    QHBoxLayout *hlayout;
    QVBoxLayout *vlayout;
    QGridLayout *glayout;
};

#endif // WIDGET_H
#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    btn_1 = new QPushButton("1",this);
    btn_2 = new QPushButton("2",this);
    btn_3 = new QPushButton("3",this);
    btn_4 = new QPushButton("4",this);
    btn_5 = new QPushButton("5",this);

    btn_1->setMaximumSize(QSize(260, 80));
    btn_2->setMaximumSize(QSize(260, 80));
    btn_3->setMaximumSize(QSize(260, 80));
    btn_4->setMaximumSize(QSize(260, 80));
    btn_5->setMaximumSize(QSize(260, 80));

    btn_1->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
    btn_2->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
    btn_3->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
    btn_4->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
    btn_5->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);


    text = new QTextEdit;

#if 1
    vlayout = new QVBoxLayout(this);//垂直布局管理器
    hlayout = new QHBoxLayout;//水平布局管理器

    hlayout->setSpacing(6);
    hlayout->addWidget(btn_1);
    hlayout->addWidget(btn_2);
    hlayout->addWidget(btn_3);
    hlayout->addWidget(btn_4);
    hlayout->addWidget(btn_5);

    vlayout->setSpacing(6);
    vlayout->setContentsMargins(11, 11, 11, 11);

    vlayout->addLayout(hlayout);
    vlayout->addWidget(text);
#else
	glayout = new QGridLayout(this);//网格布局管理器
    glayout->addWidget(btn_1,0,0,1,1);
    glayout->addWidget(btn_2,0,1,1,1);
    glayout->addWidget(btn_3,0,2,1,1);
    glayout->addWidget(btn_4,0,3,1,1);
    glayout->addWidget(btn_5,0,4,1,1);
    glayout->addWidget(text,1,0,6,5);

#endif
}

Widget::~Widget()
{
    delete ui;
}

QMainWindow

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

#include <QMenubar> //菜单栏管理类
#include <QMenu> //菜单管理类
#include <QAction> //菜单项
#include <QToolBar> //工具栏
#include <QStatusBar> //状态栏
#include <QDockWidget> //工作区


#include <QPushButton>
#include <QLabel>
#include <QLineEdit>
#include <QTextEdit>

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = 0);
    ~MainWindow();
private:
    QMenu *fileMenu;
    QAction *openAction,*newAction,*saveAction,*closeAction;
    QPushButton *btn;
    QLineEdit *line;
    QLabel *lab;
private:
    void btnClick();
};

#endif // MAINWINDOW_H
#include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    this->setMinimumSize(640,480);
/**************************************************************************************************************************/
    //1.添加菜单
    //menuBar获取菜单首地址,addMenu添加菜单(由于每个主窗口都拥有一个菜单栏,只需要获取菜单栏,添加菜单),并获取菜单的首地址
    fileMenu = menuBar()->addMenu("文件");


    QMenu *editMenu = new QMenu("编辑");//构造一个菜单
    menuBar()->addMenu(editMenu);

    menuBar()->addMenu("构建");


    //2.添加菜单项

    openAction =  fileMenu->addAction("打开");
    newAction =  fileMenu->addAction("新建");

    openAction->setStatusTip("open"); //设置状态栏提示,当鼠标放在菜单项上

    newAction->setShortcut(QKeySequence::New);
    openAction->setShortcut(QKeySequence("ctrl+o"));


    saveAction = new QAction("保存");
    saveAction->setShortcut(Qt::CTRL+Qt::Key_S);
    fileMenu->addAction(saveAction);


    closeAction =  fileMenu->addAction("关闭");


    //3. 添加子菜单

    QMenu *childMenu = fileMenu->addMenu("最近打开的文件或项目");
    childMenu->addAction("1");
    childMenu->addAction("2");
    childMenu->addAction("3");
    childMenu->addAction("4");
    childMenu->addAction("5");

/**************************************************************************************************************************/

    //1.添加工具栏
    QToolBar *tool1 = addToolBar("file");
    QAction *first =  tool1->addAction("1");
    first->setStatusTip("open"); //设置状态栏提示,当鼠标放在菜单项上
    tool1->addAction("1");
    tool1->addAction("1");
    tool1->addAction("1");
    tool1->setAllowedAreas(Qt::LeftToolBarArea | Qt::TopToolBarArea);//允许的拖放区域


    QToolBar *tool2 = addToolBar("edit");
    btn = new QPushButton("点击");
    line = new QLineEdit("无");
    lab = new QLabel;

    tool2->addWidget(lab);
    tool2->addWidget(btn);
    tool2->addWidget(line);

    connect(btn,&QPushButton::clicked,this,&MainWindow::btnClick);



/**************************************************************************************************************************/

    //1.添加工作区
    QDockWidget *dock = new QDockWidget("工作区1");
    dock->setAllowedAreas(Qt::LeftDockWidgetArea|Qt::RightDockWidgetArea);

    QTextEdit *text = new QTextEdit;
    dock->setWidget(text);//添加核心组件

    this->addDockWidget(Qt::LeftDockWidgetArea,dock);//将dock添加到this中



    QDockWidget *dock2 = new QDockWidget("工作区2");
    dock2->setAllowedAreas(Qt::LeftDockWidgetArea|Qt::RightDockWidgetArea);

    QTextEdit *text2 = new QTextEdit;
    dock2->setWidget(text2);//添加核心组件

    this->addDockWidget(Qt::LeftDockWidgetArea,dock2);//将dock添加到this中

/**************************************************************************************************************************/

    //添加状态栏
    //statusBar:获得状态栏首地址 showMessage:让状态栏在一定时间内显示
    statusBar()->showMessage(tr("Ready"),5000);


}

MainWindow::~MainWindow()
{

}

void MainWindow::btnClick()
{
    QString text = line->text();
    lab->setText(text);
}

QDialog

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

#include <QFileDialog>//文件对话框
#include <QInputDialog>//输入对话框
#include <QColorDialog>//颜色对话框
#include <QMessageBox>//消息对话框
#include <QFontDialog>//文字对话框


namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

private slots:
    void on_pushButton_5_clicked();

    void on_pushButton_2_clicked();

    void on_pushButton_clicked();

    void on_pushButton_3_clicked();

    void on_pushButton_4_clicked();

private:
    Ui::Widget *ui;
};

#endif // WIDGET_H
#include "widget.h"
#include "ui_widget.h"
#include <QDebug>

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
}

Widget::~Widget()
{
    delete ui;
}

void Widget::on_pushButton_5_clicked()
{
#if 0
    QString filename =  QFileDialog::getOpenFileName();//调用 QFileDialog静态方法,直接弹出对话框,getOpenFileName弹出默认文件对话框,返回选中打开的文件名路径
    ui->textEdit->append(filename);
#elif 0
    QString filename =  QFileDialog::getOpenFileName(this,"open","D:/"," all file(*);;c file(*.c);;cpp file(*.cpp)");//指定当前文件对话框 (父对象,标题,打开路径,过滤器)
    ui->textEdit->append(filename);
    //ui->textEdit->setPlaceholderText(filename);
#elif 1
    QStringList filenames  = QFileDialog::getOpenFileNames(this,"open files","D:/"," all file(*);;c(*.c);;cpp(*.cpp);;image(*jpg *.png)");
    for(int i=0;i<filenames.size();i++)
        ui->textEdit->append(filenames.at(i));
#endif
}

void Widget::on_pushButton_2_clicked()
{
#if 0
    QString msg = QInputDialog::getText(this,"输入","请输入信息");//弹出对话框,getText获得输入的文本数据
    ui->textEdit->append(msg);
#elif 1
    int num = QInputDialog::getInt(this,"input","please input int");
    ui->textEdit->append(QString("input %1").arg(num));
#endif
}

void Widget::on_pushButton_clicked()
{
#if 0
    QMessageBox::about(this,"version","5.11.1");
#elif 0
    int log =  QMessageBox::question(this,"????","5.11.1",QMessageBox::Yes,QMessageBox::No);//返回用户点击的按键数值
    qDebug() << "log:" <<log;
    if(log==QMessageBox::Yes)
    {
        ui->textEdit->append("is 5.11.1");
    }
    else
    {
        ui->textEdit->append("no 5.11.1");
    }
#elif 0
    //QMessageBox::warning(this,"warning","5.11.1");


    int log = QMessageBox::warning(this,"warning","5.11.1","in","out","mid");//返回按钮编号
     qDebug() << "log:" <<log;
    if(log==0)
    {
        ui->textEdit->append("in 5.11.1");
    }
    else if(log==2)
    {
        ui->textEdit->append("mid 5.11.1");
    }
    else
    {
        ui->textEdit->append("out 5.11.1");
    }
#elif 1
    QMessageBox::critical(this,"critical","5.11.1","i know");
#endif
}

void Widget::on_pushButton_3_clicked()
{
    QColor color = QColorDialog::getColor(Qt::red,this,"color");
    qDebug() << color;
}

void Widget::on_pushButton_4_clicked()
{
    bool ok;
    QFont font = QFontDialog::getFont(&ok, QFont("Times", 12), this);
    qDebug() << font;

}

QEvent

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QKeyEvent>//键盘事件头文件
#include <QTimerEvent>
#include <QEvent>
#include <QLabel>

/*
 * 事件处理流程
 * 事件产生后先调用基类的event函数进行初步处理
 * 基类event函数,调用特定的事件处理函数进行处理
 * 特定事件处理器,处理事件(处理方式:忽略、触发信号)
*/
namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

#if 1
    void keyPressEvent(QKeyEvent *event);//重写按下的事件处理器
    void mousePressEvent(QMouseEvent *event);//重写鼠标点击事件
    void mouseReleaseEvent(QMouseEvent *event);//重写鼠标释放事件
    void mouseMoveEvent(QMouseEvent *event);//重写鼠标移动事件
    void timerEvent(QTimerEvent *event);//重写定时器处理事件

    bool event(QEvent *event);//重写所有事件处理的顶级函数
#endif
    bool eventFilter(QObject *watched, QEvent *event);//重写事件过滤器,筛选出用户关注的控件上的关注的事件
private:
    Ui::Widget *ui;
    QLabel *lbl;
    int timeId;
};

#endif // WIDGET_H
#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    lbl = new QLabel("OOOOOOOO",this);
    this->setMouseTracking(true);//设置鼠标跟随(无需按下就可触发mouseMove事件)

    ui->label_2->installEventFilter(this);//eventFilter函数重写在哪个对象中,那么就是eventFilter的参数
    ui->label_3->installEventFilter(this);//注册对象控件
}

Widget::~Widget()
{
    delete ui;
}

#include <QDebug>
#if 1
void Widget::keyPressEvent(QKeyEvent *event)
{
    qDebug() << "-----------" << event->text();//获取按下按键的文本编码
    qDebug() << "+++++++++++" << event->key();//获取按下按键的字母的大写ascii码
    if(event->text()=="w")
    {
        lbl->move(lbl->x(),lbl->y()-10);
    }
    if(event->text()=="s")
    {
        lbl->move(lbl->x(),lbl->y()+10);
    }
    if(event->text()=="a")
    {
        lbl->move(lbl->x()-10,lbl->y());
    }
    if(event->text()=="d")
    {
        lbl->move(lbl->x()+10,lbl->y());
    }
}

void Widget::mousePressEvent(QMouseEvent *event)
{
    qDebug() << "------mouse press----------";
    if(event->button() == Qt::LeftButton)
    {
        ui->label->setText("left");
        //timeId = startTimer(500);//启动定时器
    }

    if(event->button() == Qt::RightButton)
    {
        ui->label->setText("right");
        //killTimer(timeId);
    }

}

void Widget::mouseReleaseEvent(QMouseEvent *event)
{
    qDebug() << "------mouse release----------";
    ui->label->setText("none");
}

void Widget::mouseMoveEvent(QMouseEvent *event)
{
    qDebug() << "---------mouse move-----------";
    ui->label->move(event->x() - ui->label->width()/2,event->y() - ui->label->height()/2);
}

void Widget::timerEvent(QTimerEvent *event)
{
    lbl->move(lbl->x()+10,lbl->y()+10);
}

bool Widget::event(QEvent *event)
{
    qDebug() << "0000000000000000000";
    if(event->type() == QEvent::KeyPress)
    {
        keyPressEvent((QKeyEvent *)event);
        return true;
    }
    return QWidget::event(event);//其他事件都交给基类处理
}

#endif
//要筛选的控件对象要提前注册到过滤器中
bool Widget::eventFilter(QObject *watched, QEvent *event)
{
    qDebug() << "1111111111111111111";
    if(watched == ui->label_2)//判断是否为关注的对象
    {
        if(event->type() == QEvent::MouseButtonPress)//判断是否为关注的事件
        {
            timeId = startTimer(100);
            return true;
        }
    }

    if(watched == ui->label_3)//判断是否为关注的对象
    {
        if(event->type() == QEvent::MouseButtonPress)//判断是否为关注的事件
        {
            killTimer(timeId);
            return true;
        }
    }
    return QWidget::eventFilter(watched,event);//不关注的对象的事件交给基类处理
}

QPainter

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QPainter>
#include <QPen>
#include <QBrush>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

    void paintEvent(QPaintEvent *event);//重写绘图事件处理器

private:
    Ui::Widget *ui;
};

#endif // WIDGET_H
#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    this->setMinimumSize(1920,1080);
}

Widget::~Widget()
{
    delete ui;
}

void Widget::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);//定义对象提供绘图的方法
    QPen pen;
    pen.setStyle(Qt::DashDotDotLine);
    pen.setColor(QColor("green"));
    pen.setWidth(5);
    painter.setPen(pen);
    painter.drawLine(QPoint(0,0),QPoint(200,200));//画直线


    QBrush brush;
    brush.setColor(QColor("black"));
    brush.setStyle(Qt::Dense4Pattern);
    painter.setBrush(brush);
    painter.drawEllipse(QPoint(300,300),100,100);//画圆

    painter.translate(200,200);//将画家的坐标系偏移
    painter.drawRect(400,400,100,200);//画矩形

    painter.rotate(-45);//旋转画家坐标系
    pen.setStyle(Qt::DashDotDotLine);
    pen.setColor(QColor("red"));
    pen.setWidth(5);
    painter.setPen(pen);
    painter.drawRect(400,400,100,200);//画矩形
}

进线程

QThread

//mythread.h
#ifndef MYTHREAD_H
#define MYTHREAD_H

#include <QObject>
#include <QThread>
#include <QDebug>

class MyThread : public QThread//定义一个类继承于 QThread
{
    Q_OBJECT
public:
    MyThread();
    void run();//重写run作为线程的执行函数
signals:
    void valueChange(int);
public slots:
    void quitThread();
    void exitThread();
private:
    int value;
    bool flag;
};

#endif // MYTHREAD_H
//widget.h
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QThread>
#include "mythread.h"

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

private slots:
    void on_pushButton_clicked();

    void on_pushButton_2_clicked();

    void on_pushButton_3_clicked();

signals:
    void quitThread();
    void exitThread();
private:
    Ui::Widget *ui;
    MyThread *thread;
};

#endif // WIDGET_H
//mythread.cpp
#include "mythread.h"

MyThread::MyThread()
{
    value = 0;
    flag = false;
}

void MyThread::run()
{
    while(1)
    {
        if(flag)
        {
            break;
        }
        value++;
        if(value>100)
        {
            value = 0;
        }
        qDebug() << value;
        emit valueChange(value);
        msleep(100);
    }
}

void MyThread::quitThread()
{
    flag = true;
    quit();
}

void MyThread::exitThread()
{
    exit();
}

//widget.cpp
#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

}

Widget::~Widget()
{
    delete ui;
}

void Widget::on_pushButton_clicked()
{
    thread = new MyThread;//构造线程对象,在UI界面的主线程中,不能直接调用子线程的成员,必须通过信号与槽机制进行控制
    connect(thread,&MyThread::valueChange,ui->progressBar,&QProgressBar::setValue);//关联线程类的槽函数,控制progressBar
    connect(thread,&MyThread::finished,thread,&MyThread::deleteLater);//线程结束触发finishd信号,回收资源
    connect(this,&Widget::quitThread,thread,&MyThread::quitThread);
    connect(this,&Widget::exitThread,thread,&MyThread::exitThread);

    thread->start();//启动线程
}

void Widget::on_pushButton_2_clicked()
{
    //线程无法暂停
}

void Widget::on_pushButton_3_clicked()
{
//    thread->quit();//退出线程
//    thread->wait(1000);//阻塞回收资源


//    thread->terminate();//杀死线程,finish状态
    emit quitThread();
    emit exitThread();
}

QMutex

//mythread1.cpp
#include "mythread1.h"
#include <QDebug>


Mythread1::Mythread1(int *buf, int num, QMutex &mutex) : buf(buf),num(num),mutex(mutex)
{

}


void Mythread1::run()
{
    mutex.lock();
    for(int i=0;i<num;i++)
    {
        buf[i]*=2;
    }
    for(int i=0;i<num;i++)
    {
        printf("%d ",buf[i]);
    }
    printf("\n");
    mutex.unlock();
}
//mythread1.cpp
#include "mythread2.h"


Mythread2::Mythread2(int *buf, int num, QMutex &mutex) : buf(buf),num(num),mutex(mutex)
{

}

void Mythread2::run()
{
    mutex.lock();
    for(int i=0;i<num;i++)
    {
        buf[i]*=3;
    }
    for(int i=0;i<num;i++)
    {
        printf("%d ",buf[i]);
    }
    printf("\n");
    mutex.unlock();
}
//main.cpp
#include <QCoreApplication>
#include "mythread1.h"
#include "mythread2.h"
#include <QMutex>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    int buf[5]={1,2,3,4,5};

    QMutex mutex;

    Mythread1 *t1 = new Mythread1(buf,5,mutex);
    Mythread2 *t2 = new Mythread2(buf,5,mutex);

    t1->start();
    t2->start();

    QObject::connect(t1,&Mythread1::finished,t1,&Mythread1::deleteLater);
    QObject::connect(t2,&Mythread2::finished,t2,&Mythread2::deleteLater);


    return a.exec();
}

QProcess

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QProcess>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

private slots:
    void on_pushButton_clicked();

private:
    Ui::Widget *ui;
    QProcess *process;
};

#endif // WIDGET_H
#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    process = new QProcess(this);
}

Widget::~Widget()
{
    delete ui;
}

void Widget::on_pushButton_clicked()
{
    process->start("D:\\tools\\拆分\\分拆器\\PngSplit.exe");
}

网络

QTcpSocket(客户端)

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QTcpSocket>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

private slots:
    void on_pushButton_clicked();
    void netConnected();
    void showError(QAbstractSocket::SocketError);

    void on_pushButton_2_clicked();
    void netDisConnected();
    void on_pushButton_3_clicked();
    void recv();
private:
    Ui::Widget *ui;

    QTcpSocket *tcpSocket;

};

#endif // WIDGET_H
#include "widget.h"
#include "ui_widget.h"
#include <QMessageBox>

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
}

Widget::~Widget()
{
    delete ui;
}


void Widget::on_pushButton_clicked()
{
    if(ui->lineEdit->text().isEmpty()||ui->lineEdit_2->text().isEmpty())
    {
        QMessageBox::warning(this,"warning","please input");
        return;
    }
    tcpSocket = new QTcpSocket(this);//构造tcp套接字,提供客户端编程的方法
    connect(tcpSocket,&QTcpSocket::connected,this,&Widget::netConnected);//当调用connectToHost触发

    //connect(tcpSocket,&QTcpSocket::error,this,&Widget::showError);
    connect(tcpSocket,SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(showError(QAbstractSocket::SocketError)));//出错时调用

    connect(tcpSocket,&QTcpSocket::disconnected,this,&Widget::netDisConnected);//断开时调用

    connect(tcpSocket,&QTcpSocket::readyRead,this,&Widget::recv);//缓冲区接收到数据时调用

    tcpSocket->connectToHost(ui->lineEdit->text(),ui->lineEdit_2->text().toInt());//连接
#if 0
    if(tcpSocket->waitForConnected(5*1000))//阻塞等待连接,成功为true,失败false
    {
        ui->textEdit->append("connect success");
    }
    else
    {
        ui->textEdit->append(QString("connect fail:%1").arg(tcpSocket->errorString()));//打印错误信息
    }
#endif
}

void Widget::netConnected()
{
    qDebug() << "connect";
    ui->textEdit->append("connect success");

}

void Widget::showError(QAbstractSocket::SocketError error)
{
    qDebug() << "error";
    ui->textEdit->append(QString("connect fail:%1,%2").arg(error).arg(tcpSocket->errorString()));
}

void Widget::on_pushButton_2_clicked()
{
    if(tcpSocket->isValid())//判断socket是否有效
    {
        tcpSocket->disconnectFromHost();//断开链接
        tcpSocket->close();//关闭套接字
    }
}

void Widget::netDisConnected()
{
    qDebug() << "disconnected";
    ui->textEdit->append("disconnected");
}

void Widget::on_pushButton_3_clicked()
{
    if(tcpSocket->isValid())
    {
        tcpSocket->write(ui->textEdit_2->toPlainText().toLatin1());//获取内容,并转换类型
    }
}

void Widget::recv()
{
    qDebug() << tcpSocket->bytesAvailable();//返回读缓冲区有效的字节数
    //QByteArray data =  tcpSocket->readAll();//读取所有数据

    QByteArray data = tcpSocket->read(tcpSocket->bytesAvailable());//指定读取的大小,解决网络粘包问题

    ui->textEdit->append("Server:"+data);
}

QTcpServer(服务器)

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QTcpServer>
#include <QTcpSocket>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

private slots:
    void on_pushButton_clicked();
    void newConnection();
    void on_pushButton_2_clicked();

    void recv();
    void errorShow();
    void netDisConnect();
private:
    Ui::Widget *ui;
    QTcpServer *server;
    QTcpSocket *socket;
};

#endif // WIDGET_H
#include "widget.h"
#include "ui_widget.h"
#include <QMessageBox>
#include <QDebug>

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    server = new QTcpServer(this);

    socket = new QTcpSocket(this);

    connect(server,&QTcpServer::newConnection,this,&Widget::newConnection);//客户端发起连接请求时触发

    ui->pushButton_2->setDisabled(true);//设置为无效
}

Widget::~Widget()
{
    delete ui;
}

void Widget::on_pushButton_clicked()
{
    if(ui->lineEdit->text().isEmpty())
    {
        QMessageBox::warning(this,"warning","port is empty");
        return;
    }
    if(!server->listen(QHostAddress::Any,ui->lineEdit->text().toInt()))//监听,也就是启动
    {
        ui->textEdit->append("launch fail");
    }
    else
    {
        ui->textEdit->append("launch success");
    }
}

void Widget::newConnection()
{
    if(server->hasPendingConnections())//判断队列中是否有连接请求
    {
        socket = server->nextPendingConnection();//取出请求,建立连接,保存客户端套接字
        if(!socket->isValid())
        {
            ui->textEdit->append(QString("error,%1").arg(server->errorString()));
            return;
        }
        ui->textEdit->append(QString("client: %1 , %2").arg(socket->peerAddress().toString()).arg(socket->peerPort()));//打印IP地址和port
        ui->pushButton_2->setDisabled(false);

        connect(socket,&QTcpSocket::readyRead,this,&Widget::recv);
        connect(socket,SIGNAL(error(QAbstractSocket::SocketError)) ,this,SLOT(netDisConnect()));
        connect(socket,&QTcpSocket::disconnected,this,&Widget::netDisConnect);
    }
}

void Widget::on_pushButton_2_clicked()
{
    socket->write(ui->textEdit_2->toPlainText().toLatin1());

}

void Widget::recv()
{
    ui->textEdit->append(QString("client: %1").arg(QString(socket->readAll())));
}

void Widget::errorShow()
{
    ui->textEdit->append(QString("error: %1").arg(socket->errorString()));
}

void Widget::netDisConnect()
{
    ui->pushButton_2->setDisabled(true);

    disconnect(socket,&QTcpSocket::readyRead,this,&Widget::recv);//断开关联
    disconnect(socket,SIGNAL(error(QAbstractSocket::SocketError)) ,this,SLOT(netDisConnect()));
    disconnect(socket,&QTcpSocket::disconnected,this,&Widget::netDisConnect);

    socket->close();
    ui->textEdit->append("disconneted");
}

QUdpSocket(主)

#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QUdpSocket>
namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT
public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();
private slots:
    void on_pushButton_clicked();
    void recvData();
    void on_pushButton_2_clicked();
private:
    Ui::Widget *ui;
    QUdpSocket *socket;
    QHostAddress addr;
    quint16 port;
};
#endif // WIDGET_H
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    //构造udp套接字
    socket = new QUdpSocket;
    //当socket读缓存有数据,会立即触发readyRead
    connect(socket, &QUdpSocket::readyRead, this, &Widget::recvData);

}
Widget::~Widget()
{
    delete ui;
}
void Widget::on_pushButton_clicked()
{
    // 绑定,就是将ip和port共享到网络
    //socket->bind(ui->lineEdit->text().toInt());
    if(socket->bind(QHostAddress::Any, ui->lineEdit->text().toInt()))
        ui->pushButton->setDisabled(true);
}
void Widget::recvData()
{
    char buf[32] = {0};
    //readDatagram:udp的接收数据
    //参数1:保存读取的数据的首地址   参数2:要读取的字节数
    //参数3:保存数据来源的主机ip的首地址   参数4:保存数据来源的主机port的首地址
    socket->readDatagram(buf, sizeof(buf), &addr, &port);
    ui->textEdit->insertPlainText(addr.toString() + ":" + QString(buf) + "\n");
}
#include <QDebug>
void Widget::on_pushButton_2_clicked()
{
    // writeDatagram: 发送数据到另外一端
    // 参数1:发送的数据   参数2:数据接收端的ip地址   参数3:数据接收端的端口号
    qDebug() << socket->writeDatagram(ui->textEdit_2->toPlainText().toLatin1(),
                          addr, port);
    qDebug() << "size: " << ui->textEdit_2->toPlainText().size();
}

QUdpSocket(副)

#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QUdpSocket>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
    Q_OBJECT
public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();
private slots:
    void on_pushButton_clicked();
    void recvData();
private:
    Ui::Widget *ui;
    QUdpSocket *socket;
};

#endif // WIDGET_H
#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    socket = new QUdpSocket;
    connect(socket, &QUdpSocket::readyRead, this, &Widget::recvData);
}

Widget::~Widget()
{
    delete ui;
}

void Widget::on_pushButton_clicked()
{
    socket->writeDatagram(ui->textEdit_2->toPlainText().toLatin1(),QHostAddress(ui->lineEdit->text()),ui->lineEdit_2->text().toUInt());
}
#include <QDebug>
void Widget::recvData()
{
    char buf[32] = {0};
    socket->readDatagram(buf, sizeof(buf));
    ui->textEdit->insertPlainText(QString(buf) + "\n");
}

IO操作

#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QFile>
#include <QFileDialog>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT
public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();
private slots:
    void on_pushButton_clicked();
    void on_pushButton_2_clicked();
private:
    Ui::Widget *ui;
    QFile file;
};
#endif // WIDGET_H
#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
}

Widget::~Widget()
{
    delete ui;
}
#include <QDebug>
void Widget::on_pushButton_clicked()
{
    QString fileName = QFileDialog::getOpenFileName();
    if(fileName.isEmpty())
        return ;
    // 设置要操作的文件名
    file.setFileName(fileName);
    // 打开文件
    if( !file.open(QFile::ReadWrite | QFile::Text)){
        // errorString():返回错误码对应的错误信息
        qDebug() << "文件打开失败" << file.errorString();
        return;
    }
    // 读取文件内容
//    QByteArray data = file.read(file.size());
    QByteArray data = file.readAll();
    qDebug() << "len: " << data.length();
    ui->textEdit->setText(data);
}

void Widget::on_pushButton_2_clicked()
{
    //获取数据
    QString data = ui->textEdit->toPlainText();
    // 判断文件是否被打开
    if( !file.isOpen()){
        QString fileName = QFileDialog::getSaveFileName();
        if(fileName.isEmpty()){
            qDebug() << "未选择保存的文件名";
            return;
        }
        file.setFileName(fileName);
        if( !file.open(QFile::WriteOnly | QFile::Text)){
            qDebug() << "文件打开失败" << file.errorString();
            return;
        }
    }
    qDebug() << "size: " << file.size();

    // 文件指针偏移到某个位置, 参数是位置编号
    file.seek(0);
    qDebug() << "写入文件:" << file.write(data.toLatin1());
    // flush() : 手动刷新缓冲区
    file.flush();
    // 关闭文件,自动刷新缓冲区
    file.close();
}

数据库

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

#include <QSqlDatabase>         //数据库连接的管理类
#include <QSqlQuery>            //sql指令执行的类
#include <QSqlRecord>           //管理查询结果记录的类
#include <QSqlError>            //管理数据库错误信息的类

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT
public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();
private slots:
    void on_btnAdd_clicked();
    void on_btnSelect_clicked();
private:
    Ui::Widget *ui;
    QSqlDatabase db;        //定义数据库句柄对象
    int row = 0;
};
#endif // WIDGET_H
#include "widget.h"
#include "ui_widget.h"

#include <QDebug>
#include <QMessageBox>
Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    //判断句柄中是否包含本地数据库文件连接   "qt_sql_default_connnection": qt中默认的数据库连接
    if(!db.contains("qt_sql_default_connnection")){
        qDebug() << "句柄不包含 qt_sql_default_connnection 连接";
        //创建添加 数据库 连接,将连接保存到 句柄db中
        db = QSqlDatabase::addDatabase("QSQLITE");
        //设置数据库文件名
        db.setDatabaseName("my.db");
    } else {
        qDebug() << "本地存在 my.db";
        // 获得本地数据库连接
        db = QSqlDatabase::database("qt_sql_default_connnection");
    }
    //判断数据库是否被打开
    if( !db.isOpen() ){
        qDebug() << "数据库未打开";
        if( !db.open() ){
            QMessageBox::warning(this, "警告", "数据打开失败");
            return;
        }
    }
    //创建数据库表
    QString sql = "create table if not exists user("
                  "id integer primary key autoincrement, "
                  "name varchar(12), "
                  "age int, "
                  "sex varchar(4));";

    //定义执行sql指令的对象
    QSqlQuery query;
    //管理将要执行的sql指令
    query.prepare(sql);
    // exec():执行sql执行
    if( !query.exec() ){
        // lastError(): 返回 最新的错误
        qDebug() << "错误:" << query.lastError().text();
        QMessageBox::warning(this, "警告", query.lastError().text());
    }
    qDebug() << "数据库表创建成功";
}

Widget::~Widget()
{
    delete ui;
}

void Widget::on_btnAdd_clicked()
{
    if(ui->edtName->text().isEmpty() || ui->edtAge->text().isEmpty() ||
            ui->edtSex->text().isEmpty()){
        QMessageBox::warning(this, "警告", "插入的数据不完整");
        return;
    }
    QString sql = QString("insert into user values(NULL, '%1', '%2', '%3');")
            .arg(ui->edtName->text())
            .arg(ui->edtAge->text().toInt())
            .arg(ui->edtSex->text());
    // 构造 sql语句执行的类对象,将sql指令传递进行初始化
//    QSqlQuery query(sql);         //此方法执行插入指令时会插入两条相同的记录
    QSqlQuery query;
    if(!query.exec(sql)){
        QMessageBox::warning(this, "错误", query.lastError().text());
        return;
    }
    QMessageBox::information(this, "提示", "数据增加成功");
}

void Widget::on_btnSelect_clicked()
{
    row = 0;
    // clear(): 清除表格内容和 表头数据
    ui->tableWidget->clear();
    // setHorizontalHeader(): 设置表格的水平表头
    // ui->tableWidget->setHorizontalHeader();
    QStringList list;
    list << "编号" << "姓名" << "年龄" << "性别";
    ui->tableWidget->setHorizontalHeaderLabels(list);

    QString sql;
    QString name = ui->edtName->text();
    if(name.isEmpty()){
        sql = "select * from user;";
    } else {
        sql = QString("select * from user where name = '%1';").arg(name);
    }

    QSqlQuery query;
    if(!query.exec(sql)){
        QMessageBox::warning(this, "错误", query.lastError().text());
        return;
    }
    // record():返回查询的所有记录  count():返回每条记录字段数
    qDebug() << query.record().count();
    // 判断下一条记录是否有效
    while(query.next()){
        // value(key): 取出某条记录中 字段名为 key的数据
        qDebug() << query.value("id").toString() << query.value("name").toString();
        ui->tableWidget->setRowCount(row+1);//添加行数
#if 0
        ui->tableWidget->setItem(row, 0, new QTableWidgetItem(query.value("id").toString() ));
        ui->tableWidget->setItem(row, 1, new QTableWidgetItem(query.value("name").toString() ));
        ui->tableWidget->setItem(row, 2, new QTableWidgetItem(query.value("age").toString() ));
        ui->tableWidget->setItem(row, 3, new QTableWidgetItem(query.value("sex").toString() ));
#else
        for(int i = 0; i < query.record().count(); i++){
            ui->tableWidget->setItem(row, i, new QTableWidgetItem(query.value(i).toString() ));
        }
#endif
        row++;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值