QT笔记

assistant 调出qt帮助手册
qmake  (qt构建器)
qmake	   -v 查看qt版本
qmake	  -project 生成.pro的项目描述文件
qmake	  根据.pro生成编译连接脚本makefile
desinger (qt设计师)
图形界面编辑器,用于设计界面,以.ui后缀保存
uic (转换工具)
将.ui转换成可执行的代码
moc (元对象编译器)
将qt中的拓展语法还原成标准的c++
rcc (资源管理工具)
将图片等素材加载到程序中
qtcreator(qt创造器)
qt的集成开发环境,包含以上所有的工具

帮助手册使用

1QAppliction
头文件 构建选项 继承关系
Public Functions (共有的成员函数)
Reimplementen Public Functions(共有的虚函数)
Public Slots (共有的槽函数)
Signals (信号函数)
static Public Menbers (静态成员)
Reimplemented Protected Functions (保护虚函数)
Macros (原对象、宏)
Detatiled Description (详细描述)

第一个QT程序

创建一个工程目录(必须放在一个单独目录中)
进入目录编写程序
构建工程生成.pro的工程文件
qmake -project 工程文件名和目录名相同(在其中添加构建选项QT += widgets)
qmake,生成Makefile
make 编译链接
#include <QApplication>
#include <QLabel>
int main(int argc,char **argv)
{
        //创建一个qt应用程序对象
        QApplication app(argc,argv);
        //创建一个标签对象
        QLabel label("hello world");
        //显示标签
        label.show();
        //进入事件循环
        return app.exec();

}

QT编码方式

qt内部都是以Unicode编码
如果不是需要以下方式编码转换

#include <QApplication>
#include <QPushButton>
#include <QTextCodec>
int main(int argc,char** argv)
{

        QApplication app(argc,argv);
        //获取编码对象
        QTextCodec* coder = QTextCodec::codecForName("UTF-8");
        //将要显示的中文字符转换为Unicode
        QPushButton button(coder->toUnicode("按钮"));

        button.show();

        return app.exec();
}

信号和槽机制

信号概念:信号和槽机制是qt自行定义的一种机制,实现对象之间的数据交换
	其本质就是函数调用,一个对象发出信号,连接到该型号对象化的槽函数将被执行。
	SIGNAL(信号函数)将信号函数转换成字符串
	SLOT(槽函数)将槽函数转换成字符串
QObject::connect
(
	 const QObject *sender,信号发送地址
	 const char *signal, 信号函数
	 const QObject *receiver, 想好接收对象指针
	 const char *method,槽函数
	 Qt::ConnectionType type = Qt::AutoConnection
  )
  SIGNAL(信号函数) :将信号函数转换成字符串
  SLOT(槽函数)	:将槽函数转换成字符串
#include <QApplication>
#include <QLabel>
#include <QPushButton>
int main(int argc,char** argv)
{
        QApplication app(argc,argv);
        QLabel label("hello qt");
        QPushButton button("关闭标签");
        label.show();
        button.show();
        //连接信号函数和朝函数
        QObject::connect(&button,SIGNAL(clicked()),&label,SLOT(close()));
        return app.exec();

}

滑块

QSlider(Qt::Orientation orientation, QWidget *parent = nullptr)
设置滑块垂直还是水平
void setRange(int min, int max)
设置滑动范围
void setValue(int)
改变滑块的位置
void valueChanged(int value)
滑动时改变信号
QSpinBox(QWidget *parent = nullptr)构造函数
void setRange(int minimum, int maximum)
设置选址范围
void setValue(int val)
设置选值框的值
void valueChanged(int i)
值改变信号
#include <QApplication>
#include <QSlider>
#include <QSpinBox>
int main(int argc,char** argv)
{
        QApplication app(argc,argv);
        //创建花块主见
        QSlider slider(Qt::Horizontal);
        slider.setRange(0,100);
        slider.show();
        //创建选址矿逐渐
        QSpinBox spin;
        spin.setRange(0,100);
        spin.show();
        //建立连接
        //花块->选址矿
        QObject::connect(&slider,SIGNAL(valueChanged(int)),&spin,SLOT(setValue(int)));
        //选址矿->花块
        QObject::connect(&spin,SIGNAL(valueChanged(int)),&slider,SLOT(setValue(int)));
        return app.exec();
}

容器窗口(父窗口)

常用的父窗口类
QWidget
resize(int x,int y)//调整大小
move(int x,int y)//调整位置相对屏幕的左上角 组件是相对父窗口的左上角
#include <QApplication>
#include <QLabel>
#include <QPushButton>
#include <QWidget>

int main(int argc,char** argv)
{
        QApplication app(argc,argv);
        //创建副窗口对象
        QWidget parent;
        parent.resize(200,200);
        parent.move(300,300);
        //创建主见制定副窗口
        QLabel label("hello qt",&parent);
        QPushButton button("关闭标签",&parent);
        label.move(0,100);
        button.move(100,100);
        parent.show();
        //连接信号函数和朝函数
        QObject::connect(&button,SIGNAL(clicked()),&label,SLOT(close()));
        return app.exec();

}

QMainWindow
QDialog
其他的只是在声明父窗口类的时候不同其他的都一样

加法计算器

cal.cpp
#include <QApplication>
#include "calcul.h"
int main(int argc,char** argv)
{
        QApplication app(argc,argv);
        CalculatorDialog calc;
        calc.show();
        return app.exec();
}

calcul.h

#ifndef __CALCUL_h__
#define __CALCUL_h__
#include <QDialog>      //副窗口
#include <QLineEdit>    //输入框
#include <QPushButton>  //  
#include <QLabel>       //
#include <QHBoxLayout>  //水平布局器
#include <QDoubleValidator>//验证其只能输入树枝
class CalculatorDialog:public QDialog
{
        /*MOC编译器,将QT扩展语法处理成符合标准的C++源码*/
        Q_OBJECT
        public:
                CalculatorDialog(void);
        private slots:
                void enableCalcButton(void);
                void calcClicked();
        private:
                QLineEdit* m_editX;     //左超卓数
                QLineEdit* m_editY;     //右操作数
                QPushButton* m_btnCalc; //等号
                QLineEdit* m_editZ;     //结果
};

#endif

calcul.cpp

#include "calcul.h"
//构造函数,初始化
CalculatorDialog::CalculatorDialog(void)
{
        setWindowTitle("计算器");
        m_editX = new QLineEdit(this);
        m_editX->setAlignment(Qt::AlignRight);
        m_editX->setValidator(new QDoubleValidator(this));


        m_editY = new QLineEdit(this);
        m_editY->setAlignment(Qt::AlignRight);
        m_editY->setValidator(new QDoubleValidator(this));

        m_editZ = new QLineEdit(this);
        m_editZ->setAlignment(Qt::AlignRight);
        m_editZ->setReadOnly(true);

        m_btnCalc = new QPushButton("=",this);
        m_btnCalc->setEnabled(false);
        //创建布局器 
        QHBoxLayout* layout = new QHBoxLayout(this);
        layout->addWidget(m_editX);
        layout->addWidget(new QLabel("+"));
        layout->addWidget(m_editY);
        layout->addWidget(m_btnCalc);
        layout->addWidget(m_editZ);
        //设置布局期
        setLayout(layout);

        connect(m_editX,SIGNAL(textChanged(const QString)),this,SLOT(enableCalcButton()));

        connect(m_editY,SIGNAL(textChanged(const QString)),this,SLOT(enableCalcButton()));
        connect(m_btnCalc,SIGNAL(clicked()),this,SLOT(calcClicked()));
}

//使能等号按钮
void CalculatorDialog::enableCalcButton(void)
{
        bool bXOK;
        bool bYOK;
        m_editX->text().toDouble(&bXOK);
        m_editY->text().toDouble(&bYOK);
        m_btnCalc->setEnabled(bXOK&&bYOK);

}
//计算结果朝函数
void CalculatorDialog::calcClicked(void)
{
        double res = m_editX->text().toDouble() + m_editX->text().toDouble();
        QString str =QString::number(res,'g',20);
        m_editZ->setText(str);
}


获取系统时间显示

#ifndef MYTIME_CPP
#define MYTIME_CPP
#include <QDialog>          //父窗口
#include <QTime>            //时间
#include <QLabel>           //显示标签
#include <QPushButton>      //按钮头文件
#include <QVBoxLayout>      //垂直布局器
class TimeDialog:public QDialog
{
    Q_OBJECT        //因为自定义槽函数所以添加这个宏
public:
    TimeDialog(void);
private slots:      //自定义槽函数
    void TimeClicked(void);

private:
    QLabel *mylabe;
    QPushButton *mybutton;


};
#endif // TIME_CPP
#include "mytime.h"
TimeDialog::TimeDialog()
{
    /*设置标题*/
    setWindowTitle("时间");
    /*new出来一个边框指定父窗口为当前窗口*/
    mylabe = new QLabel(this);
    /*设置边框效果*/
    mylabe->setFrameStyle(QFrame::Panel|QFrame::Sunken);
    /*设置文本居中*/
    mylabe->setAlignment(Qt::AlignHCenter);
    /*new按钮父窗口为当前窗口*/
    mybutton =new QPushButton("获得时间",this);
    /*创建垂直布局器*/
    QVBoxLayout *mylayout = new QVBoxLayout(this);
    /*将其添加到布局器*/
    mylayout->addWidget(mylabe);
    mylayout->addWidget(mybutton);
    /*设置布局器*/
    setLayout(mylayout);
    /*信号槽函数建立连接这里面this指针是因为这个槽函数属于这个类中*/
    connect(mybutton,SIGNAL(clicked()),this,SLOT(TimeClicked()));
}
/*槽函数*/
void TimeDialog::TimeClicked(void)
{
    /*seText 显示字符串函数
     * currentTime获取当前是啊金对象
     * tostring将时间转换成字符串
     * “hh:mm:ss”显示时间格式
     */
    mylabe->setText(
    QTime::currentTime().toString("hh:mm:ss"));
}

#include "mytime.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    TimeDialog w;
    w.show();
    return a.exec();
}

加上自己添加的信号函数

#include "mytime.h"
TimeDialog::TimeDialog()
{
    /*设置标题*/
    setWindowTitle("时间");
    /*new出来一个边框指定父窗口为当前窗口*/
    mylabe = new QLabel(this);
    /*设置边框效果*/
    mylabe->setFrameStyle(QFrame::Panel|QFrame::Sunken);
    /*设置文本居中*/
    mylabe->setAlignment(Qt::AlignHCenter|Qt::AlignVCenter);
    /*new按钮父窗口为当前窗口*/
    mybutton =new QPushButton("获得时间",this);
    /*创建垂直布局器*/
    QVBoxLayout *mylayout = new QVBoxLayout(this);
    /*将其添加到布局器*/
    mylayout->addWidget(mylabe);
    mylayout->addWidget(mybutton);
    /*设置布局器*/
    setLayout(mylayout);
    /*信号槽函数建立连接这里面this指针是因为这个槽函数属于这个类中*/
    connect(mybutton,SIGNAL(clicked()),this,SLOT(TimeClicked()));
    connect(this,SIGNAL(sig_func(const QString&)),mylabe
            ,SLOT(setText(const QString&)));
}
/*槽函数*/
void TimeDialog::TimeClicked(void)
{

    /*seText 显示字符串函数
     * currentTime获取当前是啊金对象
     * tostring将时间转换成字符串
     * “hh:mm:ss”显示时间格式
     */
   // mylabe->setText(
 //   QTime::currentTime().toString("hh:mm:ss"));

    //emit 发射信号关键字
    emit sig_func(QTime::currentTime().toString("hh:mm:ss"));
}
#ifndef MYTIME_CPP
#define MYTIME_CPP
#include <QDialog>          //父窗口
#include <QTime>            //时间
#include <QLabel>           //显示标签
#include <QPushButton>      //按钮头文件
#include <QVBoxLayout>      //垂直布局器
#include <QString>
class TimeDialog:public QDialog
{
    Q_OBJECT        //因为自定义槽函数所以添加这个宏
public:
    TimeDialog(void);
private slots:      //自定义槽函数
    void TimeClicked(void);
signals:    //自定义信号函数
    //信号函数只需声明不可定义
    void sig_func(const QString&);
private:
    QLabel *mylabe;
    QPushButton *mybutton;


};
#endif // TIME_CPP

QT设计师

使用方法
	创建文件目录进入
	使用指令designer进入窗口界面选择窗口模板
	进行UI界面设计
	设计结束保存后缀为.ui的文件
	使用uic 命令生成.h文件
	例如 uic mywindow.ui -o ui_myweindow.h
/********************************************************************************
** Form generated from reading UI file 'mywindow.ui'
**
** Created by: Qt User Interface Compiler version 5.9.0
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/

#ifndef UI_MYWINDOW_H
#define UI_MYWINDOW_H

#include <QtCore/QVariant>
#include <QtWidgets/QAction>
#include <QtWidgets/QApplication>
#include <QtWidgets/QButtonGroup>
#include <QtWidgets/QDialog>
#include <QtWidgets/QHBoxLayout>
#include <QtWidgets/QHeaderView>
#include <QtWidgets/QLabel>
#include <QtWidgets/QLineEdit>
#include <QtWidgets/QPushButton>

QT_BEGIN_NAMESPACE

class Ui_mywindow
{
public:
    QHBoxLayout *horizontalLayout;
    QLineEdit *xline;
    QLabel *mylabel;
    QLineEdit *yline;
    QPushButton *mybutton;
    QLineEdit *zline;

    void setupUi(QDialog *mywindow)
    {
        if (mywindow->objectName().isEmpty())
            mywindow->setObjectName(QStringLiteral("mywindow"));
        mywindow->resize(825, 584);
        QFont font;
        font.setPointSize(20);
        font.setBold(true);
        font.setWeight(75);
        mywindow->setFont(font);
        horizontalLayout = new QHBoxLayout(mywindow);
        horizontalLayout->setObjectName(QStringLiteral("horizontalLayout"));
        xline = new QLineEdit(mywindow);
        xline->setObjectName(QStringLiteral("xline"));
        xline->setFont(font);
        xline->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);

        horizontalLayout->addWidget(xline);

        mylabel = new QLabel(mywindow);
        mylabel->setObjectName(QStringLiteral("mylabel"));
        mylabel->setFont(font);

        horizontalLayout->addWidget(mylabel);

        yline = new QLineEdit(mywindow);
        yline->setObjectName(QStringLiteral("yline"));
        yline->setFont(font);
        yline->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);

        horizontalLayout->addWidget(yline);

        mybutton = new QPushButton(mywindow);
        mybutton->setObjectName(QStringLiteral("mybutton"));
        mybutton->setEnabled(false);
        mybutton->setFont(font);

        horizontalLayout->addWidget(mybutton);

        zline = new QLineEdit(mywindow);
        zline->setObjectName(QStringLiteral("zline"));
        zline->setFont(font);
        zline->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
        zline->setReadOnly(true);

        horizontalLayout->addWidget(zline);


        retranslateUi(mywindow);

        QMetaObject::connectSlotsByName(mywindow);
    } // setupUi

    void retranslateUi(QDialog *mywindow)
    {
        mywindow->setWindowTitle(QApplication::translate("mywindow", "\350\256\241\347\256\227\345\231\250", Q_NULLPTR));
        mylabel->setText(QApplication::translate("mywindow", "+", Q_NULLPTR));
        mybutton->setText(QApplication::translate("mywindow", "=", Q_NULLPTR));
    } // retranslateUi

};

namespace Ui {
    class mywindow: public Ui_mywindow {};
} // namespace Ui

QT_END_NAMESPACE

#endif // UI_MYWINDOW_H

简要分析

setupUI(QDialog *mywindow)
{
//new出来图形组件
//设置图形组件属性	
}
namespace Ui {
class mywindow: public Ui_mywindow {};
} // namespace Ui防止类名冲突

使用方法自己定义一个类继承ui类
或者定义一个类在类中new一个ui类
使用设计师完成计算器

#ifndef  __NEW_MYWINDOW_H__
#define __NEW_MYWINDOW_H__
#include "ui_mywindow.h"
#include <QDoubleValidator>//验证其只能输入树枝
class CalculatorDialog:public QDialog,public Ui::mywindow
{
        /*MOC编译器,将QT扩展语法处理成符合标准的C++源码*/
        Q_OBJECT
        public:
                CalculatorDialog(void);
        private slots:
                void enableCalcButton(void);
                void calcClicked();
};

#endif
#include "new_window.h"
//构造函数,初始化
CalculatorDialog::CalculatorDialog(void)
{
        setupUi(this);
        xline->setValidator(new QDoubleValidator(this));
        yline->setValidator(new QDoubleValidator(this));
        connect(xline,SIGNAL(textChanged(const QString)),this,SLOT(enableCalcButton()));
        connect(yline,SIGNAL(textChanged(const QString)),this,SLOT(enableCalcButton()));
        connect(mybutton,SIGNAL(clicked()),this,SLOT(calcClicked()));
}

//使能等号按钮
void CalculatorDialog::enableCalcButton(void)
{
        bool bXOK;
        bool bYOK;
        xline->text().toDouble(&bXOK);
        yline->text().toDouble(&bYOK);
        mybutton->setEnabled(bXOK&&bYOK);

}
//计算结果朝函数
void CalculatorDialog::calcClicked(void)
{
        double res = xline->text().toDouble() + yline->text().toDouble();
        QString str =QString::number(res,'g',20);
        zline->setText(str);
}
#include <QApplication>
#include "new_window.h"
int main(int argc,char** argv)
{
        QApplication app(argc,argv);
        CalculatorDialog calc;
        calc.show();
        return app.exec();
}
frame组件用来显示图片的组件
-》垂直策略:expanding
-》frameshape:box
右键点击工程文件添加新闻奖添加Qt资源文件
添加前缀
添加文件
#include "dialog.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Dialog w;
    w.show();

    return a.exec();
}

#include "dialog.h"
#include "ui_dialog.h"

Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
{
    ui->setupUi(this);
    m_idexImage = 1;
}

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

void Dialog::on_btn_Prev_clicked()
{
    if(++m_idexImage>5)
    {
        m_idexImage=1;
    }
    update();   //触发重绘
}

void Dialog::on_btn_Close_clicked()
{
    close();    //关闭
}

void Dialog::on_btn_Next_clicked()
{
    if(--m_idexImage<1)
    {
        m_idexImage=5;
    }
     update();   //触发重绘
}
void Dialog::paintEvent(QPaintEvent *)
{
    //创建画家对象,参数是绘制设备
    QPainter painter(this);
    //获取frame组件矩形区域
    QRect rcImage = ui->frame->frameRect();
    //坐标器偏移
    rcImage.translate(ui->frame->pos());
    //使用资源图片构造图像
    QImage image(":/res/"
                 +QString::number(m_idexImage)+".jpg");     //++做字符转拼接通过静态函数转换成字符串
    //绘图
    painter.drawImage(rcImage,image);
}


#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>
#include <QPainter> //  画家类(二维图形引擎)
namespace Ui {
class Dialog;
}

class Dialog : public QDialog
{
    Q_OBJECT

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

private slots:
    void on_btn_Prev_clicked();

    void on_btn_Close_clicked();

    void on_btn_Next_clicked();
private:
    void paintEvent(QPaintEvent *event);    //绘制事件虚函数
private:
    Ui::Dialog *ui;
private:
    int m_idexImage;    //图片索引
};

#endif // DIALOG_H

定时器

Qt中提供两种定时器功能
定时器事件,由QObject提供
定时器信号,由QTtimer提供
int QObject::startTimer(int interval);
启动定时器每隔interval毫秒触发定时器事件
如果interval为0只要没有其他事件就触发定时器
如果成功返回定时器id失败返回0
void QObject::timerEvent(QTimerEvent* e)[virtual];
定时器事件处理函数QTimerEvent的成员函数
返回值为触发此次事件定时器id
void QObject::killTimer(int id);
销毁定时器

label组件

	frameshape边框效果
	frameshadow下沉效果
	autofillbackground:是否可以添加颜色
	palette调色板

frame(显示图片)

frameshape:显示效果
垂直策略:垂直扩展
#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>
#include <QVector>  //容器类
#include <QPair>    //类似map存放两个数据
#include <QDir>     //目录类
#include <QTime>    //时间类
#include <QPainter> //画家类
#include <QDebug>
namespace Ui {
class Dialog;
}

class Dialog : public QDialog
{
    Q_OBJECT

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

private:
    Ui::Dialog *ui;
private:
    QVector < QPair<QString,QImage> > m_vecPhotos;  //定义一个容器里面存放的是QPair
    int m_indexPhoto;   //图片索引
    int m_secClock;     //摇奖剩余时间
    int m_idtPhoto;     //更换图片
    int m_idtclok;      //更新剩余时间
    int m_idtstop;      //停止时间
private:
    void paintEvent(QPaintEvent*);      //绘制事件
    void timerEvent(QTimerEvent*);      //定时器事件
    void updateName(int indexPhoto)const;   //更新人名const表示内部不可以修改变量值
    void updateClock(int secClock)const;    //更新时间
    void loadPhotos(const QString& path);   //加载path目录下图片到容器内
private slots:
    void on_btnStart_clicked();             //按键槽函数
};

#endif // DIALOG_H


#include "dialog.h"
#include "ui_dialog.h"

Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
{
    ui->setupUi(this);
    loadPhotos("../untitled/res");
    //判断容器是否为空
    if(!m_vecPhotos.empty())
    {
        //设置随机种子
        qsrand(QTime::currentTime().msec());
        //初始化界面
        m_indexPhoto = qrand()%m_vecPhotos.size();
        updateClock(m_secClock = 0);
        updateName(m_indexPhoto);
        ui->btnStart->setEnabled(true);
    }
}

Dialog::~Dialog()
{
    delete ui;
}
void Dialog::paintEvent(QPaintEvent*)      //绘制事件
{
    //第一次进来判断容器内是否有东西
    if(!m_vecPhotos.empty())
    {
        //定义画家对象
        QPainter painter(this);
        //获取fram画图区域大小
        QRect rcPhoto = ui->frame->frameRect();
        //相对窗口对图片进行偏移
        rcPhoto.translate(ui->frame->pos());
        //开始绘图
        painter.drawImage(rcPhoto,m_vecPhotos[m_indexPhoto].second);
    }
}

void Dialog::timerEvent(QTimerEvent* event)      //定时器事件
{
    //获取传进来的定时器id判断是哪个定时器
    if(event->timerId() == m_idtPhoto)
    {
        /*从容器中随机哪一个图片
         *qrand()   qt中生成随机数函数
         * m_vecPhotos.size();获取容器大小
         */
        m_indexPhoto = qrand()%m_vecPhotos.size();
        //更新人名和图片
        updateName(m_indexPhoto);
        //触发重绘
        update();
    }else
    if(event->timerId() == m_idtclok)
    {
        updateClock(--m_secClock);
    }else
    if(event->timerId() == m_idtstop)
    {
        killTimer(m_idtclok);
        killTimer(m_idtPhoto);
        killTimer(m_idtstop);
        ui->btnStart->setEnabled(true);
    }

}
void Dialog::updateName(int indexPhoto)const   //更新人名const表示内部不可以修改变量值
{
    ui->label_name->setText(m_vecPhotos[indexPhoto].first);

}
void Dialog::updateClock(int secClock)const    //更新时间
{
    //构建时间对象
    ui->label_timer->setText(
        QTime(0,0,secClock).toString("hh:mm:ss"));
}
void Dialog::on_btnStart_clicked()
{
    //禁止使能
    ui->btnStart->setEnabled(false);
    //设置时间
    m_secClock = 5;
    //更新摇奖时间
    updateClock(m_secClock);
    //开启定时器
    m_idtPhoto = startTimer(50);    //50ms更新一次
    m_idtclok = startTimer(1000);   //1s更新一次
    m_idtstop = startTimer(5000+200);   //5s一次

}

void Dialog::loadPhotos(const QString& path)   //加载path目录下图片到容器内
{
    //创建目录对象
    QDir dir(path);
    /*遍历目录
     * entryList返回QString类型的容器保存的是当前目录下的文件
     */
    foreach(QString file,dir.entryList(QDir::Files))
    {

        QString name =file;
        /*
         * 去掉字符串后缀
         * resize重置字符串长度
         * lastIndexOf寻找字符串中元素
        */
        name.resize(name.lastIndexOf('.'));
        //构造图片对象
        QImage image(path+"/"+file);
        //构造Qpair对象插入容器中
        m_vecPhotos << qMakePair(name,image);
    }
    //处理子目录去掉. ..目录
    foreach(QString subDir,dir.entryList(QDir::Dirs|QDir::NoDotAndDotDot))
    {
        loadPhotos(path+"/"+subDir);
    }
}


#include "dialog.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Dialog w;
    w.show();

    return a.exec();
}

鼠标事件

鼠标按下事件
virtual void mousePressEvent(QMouseEvent *e);
鼠标抬起事件
virtual void mouseReleaseEvent(QMouseEvent *e);
鼠标双击事件
virtual void mouseDoubleClickEvent(QMouseEvent *e);
鼠标移动事件
virtual void mouseMoveEvent(QMouseEvent *e);
获取引发事件的鼠标按键
Qt::MouseButton button() const
获取其他鼠标按键状态
Qt::MouseButtons buttons() const
获取窗口鼠标位置
QPoint pos() const
获取屏幕鼠标位置
QPoint globalPos() const
#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>
#include <QMouseEvent>  //鼠标处理事件

namespace Ui {
class Dialog;
}

class Dialog : public QDialog
{
    Q_OBJECT

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

private:
    Ui::Dialog *ui;
private:
    virtual void mousePressEvent(QMouseEvent *e);
    virtual void mouseReleaseEvent(QMouseEvent *e);
  //  virtual void mouseDoubleClickEvent(QMouseEvent *e);
    virtual void mouseMoveEvent(QMouseEvent *e);
private:
    bool m_bDrag;
    QPoint m_ptPos;     //记录鼠标位置
};

#endif // DIALOG_H


#include "dialog.h"
#include "ui_dialog.h"

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

Dialog::~Dialog()
{
    delete ui;
}
void Dialog::mousePressEvent(QMouseEvent *e)
{
 //判断是否左键按下
    if(e->button() == Qt::LeftButton)
    {
        //获取label矩形区域
        QRect rcBlock = ui->label->frameRect();
        //转换成相对窗口位置
        rcBlock.translate(ui->label->pos());
        //判断是否在矩形区域内
        if(rcBlock.contains(e->pos())==true)
        {
            m_bDrag =true;
            //记录鼠标点击位置和label左上角相对位置
            m_ptPos = ui->label->pos() - e->pos();
        }
    }
}
void Dialog::mouseReleaseEvent(QMouseEvent *e)
{
    if(e->button() == Qt::LeftButton)
    {
        m_bDrag =false;
    }
}
void Dialog::mouseMoveEvent(QMouseEvent *e)
{
    if(m_bDrag)
    {
        QPoint ptPos = e->pos() + m_ptPos;
        //移动label
        ui->label->move(ptPos);
    }
}

键盘

键盘按下事件处理函数
virtual void keyPressEvent(QKeyEvent* e);
键盘抬起事件处理函数
virtual void keyReleaseEvent(QKeyEvent* e);
自动重复
bool isAutoRepeat() const;
按键代码键值
int key() const;
按键组合
Qt::KeyboardModifiers modifiers() const;
扫描键码与硬件驱动相关
quint32 nativeScanCode() const;
虚拟键码
quint32 nativeVirtualKey() const;
按键文本
QString text() const;
#include "key.h"
#include "ui_key.h"

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

key::~key()
{
    delete ui;
}
void key::keyPressEvent(QKeyEvent *event)
{
    printKey("按下",event);
}
void key::keyReleaseEvent(QKeyEvent *event)
{
    printKey("抬起",event);
}
void key::printKey(const QString& str,QKeyEvent* event)
{
    qDebug() <<str;
    qDebug("按键代码:%d",event->key());
    qDebug() <<event->text();   //按键文本
    qDebug("扫描键码:%d",event->nativeScanCode());
    qDebug("虚拟键码:",event->nativeVirtualKey());
    qDebug("组合按键");
    Qt::KeyboardModifiers mod = event->modifiers();
    if(mod & Qt::ShiftModifier)
    {
        qDebug("含有shift");
    }
}

#ifndef KEY_H
#define KEY_H

#include <QDialog>
#include <QKeyEvent>    //按键事件头文件
#include <QDebug>
namespace Ui {
class key;
}

class key : public QDialog
{
    Q_OBJECT

public:
    explicit key(QWidget *parent = 0);
    ~key();
    void keyPressEvent(QKeyEvent *);    //按键按下虚函数
    void keyReleaseEvent(QKeyEvent *event);     //按键抬起虚函数
    //打印按键信息
    void printKey(const QString& str,QKeyEvent* event);
private:
    Ui::key *ui;
};

#endif // KEY_H

Qt数据库(Sqlite)

简介:指以一定方式存储在一起,能为多个用户共享具有尽可能小的冗余特点,是与应用程序彼此独立的集合。
常用术语
	DB		数据库
	DBMS	数据库管理系统
	DBA		数据库管理员
	RDB		关系型数据库
	RDBMS	关系型数据库管理系统
常见分类
	层次式数据库
	网络式数据库
	关系型数据库(常用)
常见数据库
	甲骨文:Oracle
	IBM:DB2
	微软:sqlserver
	sun:mysql
	SQLite轻量级嵌入式数据库
数据库操作语言(SQL)

数据库安装
	sudo apt-get install sqlite3
测试
sqlite3指令

此处缺少视频

多线程

头文件#include <QThread>
常用函数
线程阻塞等待线程是否结束bool wait(unsigned long time = ULONG_MAX)参数等待时间
槽函数线程终断[slot] void QThread::terminate()线程终断可以出发wait函数
开启线程void start(Priority priority = InheritPriority)参数线程优先级默认不设置
获取线程句柄Qt::HANDLE currentThreadId()返回值线程句柄
#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>
#include "workthreab.h"
namespace Ui {
class Dialog;
}

class Dialog : public QDialog
{
    Q_OBJECT

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

private slots:
    void on_start_btn_clicked();

    void on_stop_btn_clicked();

private:
    Ui::Dialog *ui;
    workThreab *threadA;
    workThreab *threadB;
};

#endif // DIALOG_H


#include "dialog.h"
#include "ui_dialog.h"

Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
{
    ui->setupUi(this);
    threadA = new workThreab;
    threadB = new workThreab;
}

Dialog::~Dialog()
{
    delete ui;
    delete threadA;
    delete threadB;
}

void Dialog::on_start_btn_clicked()
{
    //开始线程
    threadA->start();
    threadB->start();
    ui->start_btn->setEnabled(false);
    ui->stop_btn->setEnabled(true);
}

void Dialog::on_stop_btn_clicked()
{
    //终止线程
    threadA->terminate();
    //等待线程资源回收
    threadA->wait();
    //终止线程
    threadB->terminate();
    //等待线程资源回收
    threadB->wait();
    ui->start_btn->setEnabled(true);
    ui->stop_btn->setEnabled(false);
}


#ifndef WORKTHREAB_H
#define WORKTHREAB_H
#include <QThread>
#include <QDebug>

class workThreab:public QThread
{
public:
    workThreab();
    ~workThreab();
    //重写线程入口函数
    void run();
};

#endif // WORKTHREAB_H


#include "workthreab.h"
workThreab::workThreab()
{

}
workThreab::~workThreab()
{

}
void workThreab::run()
{
    //获取线程id
    unsigned long m_ID =(unsigned long)currentThreadId();
    while (1)
    {
      for(int i = 0;i < 100;i++)
      {
        qDebug("%lu---%d",m_ID,i);
        msleep(20);
      }
    }
}

线程同步

互斥量(QMutex)
读写锁(QReadWriteLock)
信号量(QSemaphore)
	PV操作
	P获取一个信号量如果小于等于0进入阻塞
	V释放信号量如果信号量小于等于0唤醒阻塞线程
#include <QCoreApplication>
#include <QThread>
#include <QSemaphore>
const int datasize = 20;
const int buffsize = 5;
int table[5];
QSemaphore freeSpace(buffsize);
QSemaphore usedSpace(0);
class threadProducer:public QThread
{
public:
    void run(void)
    {
        for(int i =  0;i < 20;i++)
        {
            freeSpace.acquire();    //P获取信号量
            table[i%buffsize] = i+1;
            qDebug("touch%d",table[i%buffsize]);
            usedSpace.release();    //V归还信号量
        }
    }
};
class threadConsumer:public QThread
{
public:
   void run(void)
   {
       for(int i = 0;i < 20;i++)
       {
           usedSpace.acquire(); //P获取信号量
           qDebug("used%d",table[i%buffsize]);
           freeSpace.release(); //V归还信号量
       }
   }
};
int main(int argc, char *argv[])
{
    QCoreApplication app(argc,argv);
    threadConsumer consumer;
    threadProducer producer;
    consumer.start();
    producer.start();
    consumer.wait();
    producer.wait();
    return app.exec();
}

条件等待(QwaitCondition)
条件等待在进入等待是会解开互斥锁
进入阻塞在阻塞结束在将互斥锁上锁
#include <QCoreApplication>
#include <QWaitCondition>
#include <QMutex>
#include <QThread>

const int Data = 20;
const int buff = 5;
int table[buff];


//生产条件
QWaitCondition buff_not;
//消费条件
QWaitCondition buff_yse;

QMutex mutex;

int num = 0;
class Thread_a:public QThread
{
public:
    void run(void)
    {
        for(int i=0;i<Data;i++)
        {
            //由于条件等待不具有原子操作所以要配合互斥量使用
            mutex.lock();
            while(num == buff)
            {
                //wait函数会揭开互斥锁
                buff_not.wait(&mutex);
            }
            table[i%buff] = i+1;
            qDebug("生产%d",table[i%buff]);
            num++;
            //唤醒消费者
            buff_yse.wakeAll();
            mutex.unlock();
        }
    }
};
class Thread_b:public QThread
{
public:
    void run(void)
    {
        for(int i=0;i<Data;i++)
        {
            mutex.lock();
            while(num==0)
            {
                buff_yse.wait(&mutex);
            }
            qDebug("生产%d",table[i%buff]);
            num--;
            buff_not.wakeAll();
            mutex.unlock();
        }
    }
};
int main(int argc ,char **argv)
{
    QCoreApplication app(argc,argv);
    Thread_a A;
    Thread_b B;
    A.start();
    B.start();
    A.wait();
    B.wait();

    return app.exec();
}

网络编程在这里插入图片描述
获取电脑地址信息

#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>

#include <QHostInfo>
#include <QHostAddress>
#include <QNetworkInterface>
#include <QMessageBox>


namespace Ui {
class Dialog;
}

class Dialog : public QDialog
{
    Q_OBJECT

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

private slots:
    void on_pushButton_clicked();

private:
    Ui::Dialog *ui;
private:
    void getcomputer(void);
};

#endif // DIALOG_H


#include "dialog.h"
#include "ui_dialog.h"

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

Dialog::~Dialog()
{
    delete ui;
}
void Dialog::getcomputer(void)
{
 //获取主机名
   QString housname =  QHostInfo::localHostName();
   //显示主机名到ui
   ui->computer_l->setText(housname);
   //根据主机名获取主机地址
   QHostInfo info = QHostInfo::fromName(housname);
   if(info.addresses().isEmpty())
   {
       QHostAddress address = info.addresses().first();
       ui->ip_l->setText(address.toString());
   }
}

void Dialog::on_pushButton_clicked()
{
    QString str;
    //获取当前主机网络接口对象
    QList<QNetworkInterface> list =
    QNetworkInterface::allInterfaces();
    //获取容器中每块网卡的信息
    for(int i = 0;i<list.count();i++)
    {
        QNetworkInterface interface = list.at(i);
        //获取设备名称
        str += "设备名字" + interface.name()+"\n";
        //获取地址信息
        str += "硬件信息" + interface.hardwareAddress() + "\n";
        //获取ipv4地址 获取广播地址获取子网掩码
        QList<QNetworkAddressEntry> enlist =
                interface.addressEntries();
        QNetworkAddressEntry entry = enlist.at(0);
        str += "IPV4地址"+entry.ip().toString() +"\n";
        str += "子网掩码"+entry.netmask().toString() +"\n";
        str += "广播地址"+entry.broadcast().toString() +"\n";
    }
    //弹个窗
    QMessageBox::information(this,"详细信息",str);
}

UDP通讯
发送端

#ifndef SENDER_H
#define SENDER_H

#include <QDialog>
#include <QTimer>//定时器
#include <QUdpSocket>   //udp
#include <QHostAddress> //网络地址

namespace Ui {
class sender;
}

class sender : public QDialog
{
    Q_OBJECT

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

private slots:
    void on_m_pushButton_clicked();
    void sendMessge(void);


private:
    Ui::sender *ui;
    bool flag;
    QUdpSocket* m_udp;
    QTimer* m_timer;
};


#endif // SENDER_H
#include "sender.h"
#include "ui_sender.h"

sender::sender(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::sender)
{
    ui->setupUi(this);
    m_udp = new QUdpSocket(this);
    m_timer = new QTimer(this);
    flag = false;
    connect(m_timer,SIGNAL(timeout()),this,SLOT(sendMessge()));
}

sender::~sender()
{
    delete ui;
}
void sender::sendMessge(void)
{
    //获取端口号
    quint16 port = ui->m2_Edit->text().toShort();
    //获取消息
    QString msg = ui->m1_Edit->text();
    //开始广播toLocal8Bit()将QString转换成QByteArray()
    //将QString转化为字节列格式否则接收端汉字乱码
    //关键的转换步骤,在Qt5.4中转化成utf8可以实现汉字正确显示
    QByteArray datagram = msg.toUtf8().data();
    m_udp->writeDatagram(datagram.data(),QHostAddress::Broadcast,port);
}

void sender::on_m_pushButton_clicked()
{
    if(flag==false)
    {
        ui->m_pushButton->setText("停止");
        ui->m1_Edit->setEnabled(false);
        ui->m2_Edit->setEnabled(false);
        //开启定时器1s
        m_timer->start(1000);
        flag = true;
    }else
    {
        ui->m_pushButton->setText("开始");
        ui->m1_Edit->setEnabled(true);
        ui->m2_Edit->setEnabled(true);
        //关闭定时器1s
        m_timer->stop();
         flag =false;
    }
}

接收端

#ifndef REC_H
#define REC_H

#include <QDialog>
#include <QUdpSocket>   //udp
#include <QHostAddress> //网络地址
#include <QMessageBox>//弹窗类
namespace Ui {
class rec;
}

class rec : public QDialog
{
    Q_OBJECT

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

private slots:
    void on_m_pushButton_clicked();
    void recmes();
private:
    Ui::rec *ui;
    bool flag;
    QUdpSocket* m_udp;
    quint16 prot;
};

#endif // REC_H

#include "rec.h"
#include "ui_rec.h"

rec::rec(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::rec)
{
    ui->setupUi(this);
    m_udp = new QUdpSocket(this);
    flag = false;
}

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

void rec::on_m_pushButton_clicked()
{
    if(flag == false)
    {
        flag = true;
        //开始接收获取端口号
        prot = ui->m_Edit->text().toShort();
        //绑定端口号
        bool res = m_udp->bind(prot);
        if(res == false)
        {
            QMessageBox::information(this,"error","绑定失败");
            return;
        }
        ui->m_Edit->setEnabled(false);
        ui->m_pushButton->setText("停止");
        //当有信息传进来会产生信号
        connect(m_udp,SIGNAL(readyRead()),this,SLOT(recmes()));

    }else
    {
        flag = false;
        //关闭套接字
        m_udp->close();
        ui->m_Edit->setEnabled(true);
        ui->m_pushButton->setText("开始");
    }
}
void rec::recmes()
{
    //判断套接字是否有有效的数据到来
    if(m_udp->hasPendingDatagrams())
    {
        QByteArray m_data;

        //获取当前数据大小
        m_data.resize(m_udp->pendingDatagramSize());
        //接收数据
        m_udp->readDatagram(m_data.data(),m_data.size());
        //显示数据
         //将utf8格式转换回字符串类型
       QString str = QString::fromUtf8(m_data.data());
        ui->m_listWidget->addItem(str);

    }
}

TCP聊天室服务器

#ifndef SERVERDLG_H
#define SERVERDLG_H

#include <QDialog>
#include <QTcpServer>   //tcp服务器类
#include <QTcpSocket>   //套接字类
namespace Ui {
class serverdlg;
}

class serverdlg : public QDialog
{
    Q_OBJECT

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

private slots:
    void on_m_btn_clicked();
    void onNewConnection();
    void onmessageReceived();

private:
    void sendMessage(const QByteArray& message);
    Ui::serverdlg *ui;
    QTcpServer m_server;
    quint16 port;
    QList<QTcpSocket*> m_socket;

};

#endif // SERVERDLG_H


#include "serverdlg.h"
#include "ui_serverdlg.h"

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

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

void serverdlg::on_m_btn_clicked()
{
    //创建服务器
    //获取端口号
    port = ui->m_edt->text().toShort();
    //开启服务器
    if(m_server.listen(QHostAddress::Any,port))
    {
        qDebug("创建成功");
    }else
    {
        qDebug("创建失败");
    }
    //有人三次握手成功后转到槽函数
    connect(&m_server,SIGNAL(newConnection()),this,SLOT(onNewConnection()));
    ui->m_edt->setEnabled(false);
    ui->m_btn->setEnabled(false);
}
void serverdlg::onNewConnection()
{
    //获取套接字
     QTcpSocket* temp_tcp =  m_server.nextPendingConnection();
     m_socket.append(temp_tcp);
     //建立槽函数接收数据
     connect(temp_tcp,SIGNAL(readyRead()),this,SLOT(onmessageReceived()));
}

void serverdlg::onmessageReceived()
{
    //遍历套接字
    for(int i = 0;i < m_socket.count();i++)
    {
        //判断是否有数据到来
        if(m_socket.at(i)->bytesAvailable())
        {
            QByteArray readbuf = m_socket.at(i)->readAll();
            //显示数据
             QString str = QString::fromUtf8(readbuf.data());
            ui->listview->addItem(str);
            //转发数据到客户端
            sendMessage(readbuf);
        }
    }
}

void serverdlg::sendMessage(const QByteArray& message)
{
    for(int i = 0;i < m_socket.count();i++)
    {
        //发送数据
        m_socket.at(i)->write(message);
    }
}

TCP聊天室客户端

#ifndef CLIENTDLG_H
#define CLIENTDLG_H

#include <QDialog>
#include <QHostAddress> //网络地址
#include <QTcpSocket>
#include <QTcpServer>
#include <QMessageBox>
namespace Ui {
class clientdlg;
}

class clientdlg : public QDialog
{
    Q_OBJECT

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

private slots:
    void on_send_btn_clicked();

    void on_ok_btn_clicked();
    //和服务器连接
    void onConnected();
    //断开连接
    void onDisconnected();
    //接收消息
    void receivedMessage();
    //网络异常
    void onSockerror(QAbstractSocket::SocketError);

private:
    Ui::clientdlg *ui;
    bool flag;
    QHostAddress serverip;
    quint16 serverport;
    QString name;
    QTcpSocket tcpsocket;

};

#endif // CLIENTDLG_H

#include "clientdlg.h"
#include "ui_clientdlg.h"

clientdlg::clientdlg(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::clientdlg)
{
    ui->setupUi(this);
    flag = false;
    //建立连接
    connect(&tcpsocket,SIGNAL(connected()),this,SLOT(onConnected()));
    //断开连接
    connect(&tcpsocket,SIGNAL(disconnected()),this,SLOT(onDisconnected()));
    //接收数据
    connect(&tcpsocket,SIGNAL(readyRead()),this,SLOT(receivedMessage()));
    //网络异常
    connect(&tcpsocket,SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(onSockerror(QAbstractSocket::SocketError)));

}

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

void clientdlg::on_send_btn_clicked()
{
    if(ui->msg_egt->text()=="")
        return ;
    QString msg = name +":"+ui->msg_egt->text();
    //发送信息
    QByteArray datagram = msg.toUtf8().data();
    tcpsocket.write(datagram.data());
    //清空
    ui->msg_egt->clear();

}

void clientdlg::on_ok_btn_clicked()
{
    if(flag == false)
    {
        //获取ip
        QString ip = ui->ip_egt->text();
        if(serverip.setAddress(ip) == false)
        {
            QMessageBox::information(this,"ip错误","输入有效ip");
            return;
        }
        //获取端口
        serverport = ui->d_edt->text().toShort();
        if(serverport == 0)
        {
            QMessageBox::information(this,"端口错误","输入有效端口");
            return;
        }
        //获取昵称
        name = ui->name_egt->text();
        if(name=="")
        {
            QMessageBox::information(this,"不可为空昵称","输入有效昵称");
            return;
        }
        //服务器建立连接
        tcpsocket.connectToHost(serverip,serverport);
        flag =true;
    }else
    {
        //断开连接
        //发送下线消息
        QString msg = name + "离开聊天室";
        QByteArray datagram = msg.toUtf8().data();
        tcpsocket.write(datagram.data());
        //关闭服务器
        tcpsocket.disconnectFromHost();
        flag = false;

    }
}
//和服务器连接
void clientdlg::onConnected()
{
    //初始化界面使能发送按钮
    ui->send_btn->setEnabled(true);
    //修改按钮文本
    ui->ok_btn->setText("断开连接");
    //禁用端口号等输入
    ui->ip_egt->setEnabled(false);
    ui->name_egt->setEnabled(false);
    ui->d_edt->setEnabled(false);
    //向服务器发送进入信息
    QString msg = name+"进入聊天室";
    QByteArray datagram = msg.toUtf8().data();
    tcpsocket.write(datagram.data());
}

//断开连接
void clientdlg::onDisconnected()
{
    //失能发送按钮
    ui->send_btn->setEnabled(false);
    //修改按钮文本
    ui->ok_btn->setText("建立连接");
    //开启端口号等输入
    ui->ip_egt->setEnabled(true);
    ui->name_egt->setEnabled(true);
    ui->d_edt->setEnabled(true);
}

//接收消息
void clientdlg::receivedMessage()
{
    //判断数据是否到来
    if(tcpsocket.bytesAvailable())
    {
        QByteArray buf;
        buf.resize(tcpsocket.bytesAvailable());
        tcpsocket.read(buf.data(),buf.size());
        QString str = QString::fromUtf8(buf.data());
        ui->m_list->addItem(str);
    }
}

//网络异常
void clientdlg::onSockerror(QAbstractSocket::SocketError)
{
    QMessageBox::critical(this,"网络异常",tcpsocket.errorString());
}

HTTP

超文本传输协议所有www文件必须遵守的协议,是客户端和服务器端请求应答标准
请求格式
-》请求行 说明请求类型 访问资源 http版本
GET /web/login_new.html HTTP/1.1
-》请求头
	说明服务器使用的附加信息
-》空行	“/r/n”
-》课选消息体
	可以是任意数据
响应格式
-》状态行
	HTTP版本 状态码(404) 状态码描述短语
—》响应头域
	给客户端一些附加信息,主要描述服务器信息
-》空行“/r/n”
—》消息体
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值