DAY1

04 创建第一个QT程序

  • QWidget是QMainWindow和QDialog的父类,其中QMainWindow多菜单栏,QDialog是一个对话框

  • .pro文件是“工程”文件

  • main.cpp初始文件解释

    #include "mywidget.h"
    ​
    #include <QApplication>//包含一个应用程序类的头文件
    ​
    //main程序入口 argc是命令行变量的数量 argv是命令行变量的数组
    int main(int argc, char *argv[])
    {
        //a是应用程序对象,在Qt中,应用程序对象有且只有一个
        QApplication a(argc, argv);
        //窗口对象 myWidget父类 ->QWidget
        myWidget w;
        //窗口对象 默认不会显示,必须要调用show方法显示窗口
        w.show();
        //让应用程序对象进入消息循环机制
        return a.exec();
    }
    
  • .pro文件的解释:

    QT       += core gui //Qt包含的模块
    ​
    greaterThan(QT_MAJOR_VERSION, 4): QT += widgets  //大于4版本以上包含widget模块
    ​
    CONFIG += c++11
    ​
    DEFINES += QT_DEPRECATED_WARNINGS
    ​
    SOURCES += \      //源文件
        main.cpp \
        mywidget.cpp
    ​
    HEADERS += \      //头文件
        mywidget.h
    ​
    qnx: target.path = /tmp/$${TARGET}/bin
    else: unix:!android: target.path = /opt/$${TARGET}/bin
    !isEmpty(target.path): INSTALLS += target
    ​
    

05命名规范以及快捷键

  • myWidget.h文件的解释

    #ifndef MYWIDGET_H
    #define MYWIDGET_H
    ​
    #include <QWidget>//包含头文件 QWidget窗口类
    ​
    class myWidget : public QWidget
    {
        Q_OBJECT// Q_OBJECT宏,允许类中使用信号和槽机制
    ​
    public:
        myWidget(QWidget *parent = nullptr);//构造函数
        ~myWidget();//虚构函数
    };
    #endif // MYWIDGET_H
    命名规范及快捷键
    
  • myWidget.cpp文件解释

    #include "mywidget.h"
    #include <QPushButton>//按钮控件的头文件
    //命名规范
    //类名 首字母大写,单词与单词之间首字母大写
    //函数名 变量名称 首字母小写,单词和单词之间首字母大写
    ​
    //快捷键
    //注释 ctrl+/
    //运行 ctrl+r
    //编译 ctrl+b
    //字体缩放 ctrl+鼠标滚轮
    //查找 ctrl+f
    //整行移动 ctrl+shift+↑或者↓
    //帮助文档 F1
    //自动对齐 ctrl+i
    //同名之间的.h和.cpp切换 F4
    ​
    //帮助文档:
    //第一种方式 F1
    //第二种方式 左侧按钮
    //第三种方式 D:\QT_installer\install_data\5.14.2\mingw73_64\bin
    ​
    myWidget::myWidget(QWidget *parent)
        : QWidget(parent)
    {
        //创建第一个按钮
            QPushButton *btn=new QPushButton;
            //让btn对象依赖在myWidget窗口中
            btn->setParent(this);
            //显示文本
            btn->setText("the first button");
    ​
    ​
        //创建第二个按钮
            QPushButton* btn2 =new QPushButton("the second button",this);
            //移动btn2按钮
            btn2->move(100,100);
    ​
            //重置窗口大小
            resize(600,400);
    ​
            //设置固定的窗口大小
            setFixedSize(600,400);
    ​
            //设置窗口标题
            setWindowTitle("the firt window");
    ​
    }
    ​
    myWidget::~myWidget()
    {
    }
    ​
    ​
    

06QPushButton创建

  • 创建QPushButton* btn=new QPushButton

  • 设置父亲 setParent(this)

  • 设置文本 setText(“文字")

  • 设置位置 move(宽,高)

  • 重新指定窗口大小 resize

  • 设置窗口标题 setWindowTitle

  • 设置窗口固定大小 setFixSize

//按钮控件
    QPushButton * btn=new QPushButton;
  //  btn->show();//顶层方式显示
 
    //如果想显示时在当前窗口显示,需要设置父窗口
    btn->setParent(this);
 
    //设置文本
    btn->setText("你好");
 
    //创建第二个按钮
     QPushButton * btn2 =new QPushButton("hello",this);
    //按钮也可以重置尺寸
     btn2->resize(100,100);
     //移动位置
     btn2->move(100,300);
 
     //设置窗口尺寸
    // this->resize(100,200);
 
     //设置固定窗口尺寸
     this->setFixedSize(900,400);
 
     //设置窗口标题
     this->setWindowTitle("显示子女");
 
     //自定义自己的按钮,捕获析构函数
     MyPushButton *mybtn = new MyPushButton;
     mybtn->setParent(this);
     mybtn->move(200,300);
     mybtn->setText("我的按钮");
​

07对象树

  • 当创建的对象在堆区的时候,如果指定的父亲是QObject派生下来的类或者QObject子类派生下来的类,可以不用管理释放的操作,将对象会放入对象树中。

  • 一定程度上简化了回收机制

08Qt中的坐标系

  • 坐标体系:以左上角为原点,X轴向右增加,Y向下增加

09信号和槽-点击按钮关闭窗口

  • 连接函数 connect

  • 参数:

    • 参数1 信号的发送者

    • 参数2 发送的信号(函数的地址)

    • 参数3 信号的接受者

    • 参数4 处理的槽函数

  • 松散耦合

  • 实现点击按钮 关闭窗口的案例

    ​
            //需求:点击我的按钮 关闭窗口
            //参数1 信号的发送者 参数2 发送的信号(函数的地址) 参数3 信号的接受者 参数4 处理的槽函数
            connect(myBtn,&QPushButton::clicked,this,&myWidget::close);
    

10自定义的信号和槽

  • 自定义信号

    • 写到signals下

    • 返回值是void

    • 需要声明,不需要实现

    • 可以有参数,可以重载

  • 自定义槽函数

    • 写到public slot下,或者public或者全局函数

    • 返回值是void

    • 需要声明,需要实现

    • 可以有参数,可以重载

  • 触发自定义的信号

    • emit 自定义的信号
  • 案例:下课后,老师出发饿了信号,学生响应信号,请客吃饭(见文件the_second_day_learning)

11&12自定义的信号和槽发生重载的解决&信号连接信号

  • 需要利用函数指针,明确指向函数的地址

  • void (Teacher::*teacherSignal)(QString)=&Teacher::hungry;

  • QString转成char*

    • .ToUtf8()转为QByteArray

    • .Data()转为char *

  • 信号可以连接信号

  • 断开信号:disconnect

  • 拓展

    • 1、信号是可以连接

    • 2、一个信号可以连接多个槽函数

    • 3、多个信号可以连接同一个槽函数

    • 4、信号和槽函数的参数必须类型一一对应

    • 5、信号和槽的参数个数不需要一致,信号的参数个数可以多于槽函数的参数个数

13 Qt4版本信号槽连接

  • connect(信号的发送者,发送的信号 SIGNAL(信号),信号接受者,槽函数 SLOT(槽函数))

  • 优点 参数直观

  • 缺点 编译器不会检测参数类型

14 Lambda表达式

  • []标识符 匿名函数

    • =值传递

    • &引用传递

  • ()参数

  • {}实现体

  • mutable 修饰值传递变量,可以修改拷贝出的数据,改变不了本体

  • 返回值 [] ()->int{}

DAY2

02 Qmainwindow_菜单栏和工具栏

  • QMainWindow

    • 菜单栏 最多有一个

           //菜单栏创建
           //菜单栏只有一个
           QMenuBar* bar=menuBar();
           //将菜单栏放入窗口中
           setMenuBar(bar);
       
           //创建菜单
           //bar->addMenu("文件");
           QMenu *fileMenu=bar->addMenu("文件");
           QMenu *editMenu=bar->addMenu("编辑");
       
           //创建菜单项
           //fileMenu->addAction("新建");
           QAction *newAction= fileMenu->addAction("新建");
       
           //添加分隔符
           fileMenu->addSeparator();
           //fileMenu->addAction("打开");
           QAction *openAction= fileMenu->addAction("打开");
      
    • 工具栏 可以有多个

      	//工具栏 可以有多个
          QToolBar* toolBar=new QToolBar(this);
          //addToolBar(toolBar);
          addToolBar(Qt::BottomToolBarArea,toolBar);//第一个内容参考帮助文档
      
          //后期设置 只允许 左右停靠
          toolBar->setAllowedAreas(Qt::LeftToolBarArea|Qt::RightToolBarArea);
      
          //设置浮动
          toolBar->setMovable(true);
      
          //设置移动(总开关)
          toolBar->setMovable(false);
      
          //工具栏中可以设置内容
          toolBar->addAction(newAction);
          //添加分割线
          toolBar->addSeparator();
          toolBar->addAction(openAction);
          //工具栏中添加控件
          QPushButton *btn=new QPushButton("aa",this);
          toolBar->addWidget(btn);
      

03 QMainWindow_状态栏、铆接部件、核心部件

    //状态栏 最多有一个
    QStatusBar* stBar=statusBar();
    //设置到窗口中
    setStatusBar(stBar);
    //放标签控件
    QLabel* label1=new QLabel("左侧提示信息",this);
    stBar->addWidget(label1);

    QLabel* label2=new QLabel("右侧提示信息",this);
    stBar->addPermanentWidget(label2);

    //铆接部件(浮动窗口) 可以有多个
    QDockWidget *dockWidget=new QDockWidget("浮动",this);
    addDockWidget(Qt::BottomDockWidgetArea,dockWidget);
    //设置后期停靠区域,只允许上下,只允许上下
    dockWidget->setAllowedAreas(Qt::TopDockWidgetArea);


    //设置中心部件 只能有一个
    QTextEdit* edit=new QTextEdit(this);
    setCentralWidget(edit);

04 资源文件添加

  • 将图片文件拷贝到项目文件下

  • 创建 右键项目->添加新文件->Qt->Qt resource File ->给资源文件起名字

  • res生成res.qrc

  • open in editor 编辑资源

  • 添加前缀 添加文件

  • 使用 “:+前缀名+文件名”

05 模态和非模态对话框创建

对话框分类

  • 模态对话框(不可以对其他窗口进行操作)

  • 非模态对话框(可以对其他窗口进行操作)

  • ui->setupUi(this);
    this->resize(1200,1400);
    //点击新建按钮 弹出一个对话框
    connect(ui->actionnew,&QAction::triggered,={
    //对话框 分类
    //模态对话框(不可以对其他窗口进行操作) 非模态对话框(可以对其他窗口进行操作)
    //模态创建
    QDialog dlg(this);
    dlg.resize(800,1000);
    dlg.exec();
    qDebug()<<“out”<<endl;

    //非模态创建
    QDialog* dlg2=new QDialog(this);
    dlg2->resize(800,600);
    dlg2->show();
    dlg2->setAttribute(Qt::WA_DeleteOnClose);//55号 属性
    qDebug()<<“out”<<endl;

    });

06 消息对话框

  • 标准对话框-消息对话框

    • QMessageBox 静态成员函数 创建对话框

    • 错误、信息、提问、警告

    • 参数1 父亲 参数2 标题 参数3 显示内容 参数4 按键类型 参数5 默认关联回车

    • 返回值也是StandardButton类型,利用返回值来判断用户的输入

connect(ui->actionnew,&QAction::triggered,[=](){
            //QMessageBox 消息对话框
            //错误提示 浮窗口 标题 文本
            QMessageBox::critical(this,"critical","错误!");
            //信息提示
            QMessageBox::information(this,"info","信息提示");
            //询问提示 参数1:父窗口 参数2:标题 参数3:中间显示文本 参数4:按键类型 参数5:关联回车按键
            QMessageBox::question(this,"question","提问",QMessageBox::Save | QMessageBox::Cancel,QMessageBox::Cancel);
            if (QMessageBox::Save== QMessageBox::question(this,"question","提问",QMessageBox::Save | QMessageBox::Cancel,QMessageBox::Cancel))
            {
                qDebug()<<"选择的是保存";
            }
            else  qDebug()<<"选择的是取消";
            
            //警告提示
            QMessageBox::warning(this,"warning","警告!");
         
         
         });

07 其他标准对话框

  • 颜色对话框 QColorDialog::getColor

  • 文件对话框 QFileDialog::getOpenFileName(父亲,标题,默认路径,过滤文件)

  • 字体对话框 QFontDialog::getFont

//颜色对话框 没有加QColor函数默认是白色
    QColor color = QColorDialog::getColor(QColor(255,0,0));
    qDebug()<<color.red()<<color.blue()<<color.green();

    //字体对话框
    bool ok;
    QFont font=QFontDialog::getFont(&ok,QFont("华文彩云",10));
    qDebug()<<"字体"<<font.family()<<"字号"<<font.pointSize()<<"加粗"<<font.bold()<<"倾斜"<<font.italic();

    //文件对话框
    QString str= QFileDialog::getOpenFileName(this,"打开文件","C:\\Users\\23861\\Desktop","(*.txt *.docx)");
    qDebug()<<str;

08 登陆窗口布局

  • 界面布局

    • 实现登陆窗口

    • 利用布局方式 给窗口进行美化

    • 选取widget进行布局,水平布局,垂直布局,栅格布局

    • 给用户名、密码、登陆、退出按钮进行布局

    • 默认窗口和控件之间有9间隙,可以调整 layoutLeftMargin

    • 利用弹簧进行布局

09 控件

  • 按钮组

    • QPushButton 常用按钮

    • QToolButton 工具按钮 用于显示图片 如果想显示文字,修改风格:toolButtonStyle

    • radioButton 单选按钮,设置默认:ui->rBtnMan->setChecked(true);

    • checkBox 多选按钮,监听状态:2是选中 1是半选中 0是未选中

10 QListWidget控件

  • QListWidget列表容器

    • QListWidgetitem 一行内容

    • ui->listWidget->additem(item);

    • 设置居中方式item->setTextAlignment(Qt::AlignHCenter);

11 QTreeWidget树控件

  • 设置头

    • ui->treeWidget->setHeaderLabels(QStringList()<<“英雄”<<“英雄介绍”);
  • 创建根节点

    • QTreeWidgetItem* liItem =new QTreeWidgetItem(QStringList()<<“力量”);
      QTreeWidgetItem* minItem =new QTreeWidgetItem(QStringList()<<“敏捷”);
      QTreeWidgetItem* zhiItem =new QTreeWidgetItem(QStringList()<<“智力”);
  • 添加根节点到树控件上

    • //加载顶层的节点
      ui->treeWidget->addTopLevelItem(liItem);
      ui->treeWidget->addTopLevelItem(minItem);
      ui->treeWidget->addTopLevelItem(zhiItem);
  • 添加子节点

    • //追加子节点
      QStringList heroL1;
      heroL1 << “刚被猪” << “前排坦克,能在吸收伤害的同时造成可观的范围输出”;
      QTreeWidgetItem* l1 =new QTreeWidgetItem(heroL1);
      liItem->addChild(l1);

12 QTableWidget控件

  • 设置列数

    • //TableWidget控件
      //设置列数
      ui->tableWidget->setColumnCount(3);
  • 设置水平表头

    • //设置水平表头
      ui->tableWidget->setHorizontalHeaderLabels(QStringList()<<“姓名”<<“性别”<<“年龄”);
  • 设置行数

    • //设置 行数
      ui->tableWidget->setRowCount(5);
  • 设置正文

    • // //设置正文
      // ui->tableWidget->setItem(0,0,new QTableWidgetItem(“亚瑟”));

      QStringList nameList;
      nameList<<“亚瑟”<<“赵云”<<“张飞”<<“关羽”<<“花木兰”;
      QList sexList;
      sexList<<“男”<<“男”<<“男”<<“男”<<“女”;
      for(int i=0;i<5;i++)
      {
      int col=0;
      ui->tableWidget->setItem(i,col++,new QTableWidgetItem(nameList[i]));
      ui->tableWidget->setItem(i,col++,new QTableWidgetItem(sexList.at(i)));
      // ui->tableWidget->setItem(i,col++,new QTableWidgetItem(“18”));
      //int 转QString
      ui->tableWidget->setItem(i,col++,new QTableWidgetItem(QString::number(i+18)));

      }

13 其它常用控件介绍

  • stackedWidget控件:

    • ui->stackedWidget->setCurrentIndex(1);
  • 下拉框

    • ui->comboBox->addItem(“奔驰”);
  • QLabel 显示图片

  • QLabel 显示动图

    • 设置后要加movie->start();

DAY3

02 自定义控件封装

  • 自定义控件封装

    • 添加新文件 Qt-设计师界面类(.h .cpp .ui)

    • .ui中 设计 QSpringBox 和QSlider 两个控件

    • Widget中使用自定义控件,拖拽一个Widget,点击提升为,点击添加,点击提升

    • 实现功能,改变数字,滑动条跟着移动,信号槽监听

    • 提供getNum和setNum对外接口

    • 测试接口

03 Qt中的鼠标事件

  • 鼠标事件

  • 鼠标进入事件 enterEvent

  • 鼠标离开事件 leaveEvent

  • 鼠标按下 mousePressEvent(QMouseEvent *ev)

  • 鼠标释放 mouseReleaseEvent(QMouseEvent *ev)

  • 鼠标移动 mouseMoveEvent(QMouseEvent *ev)

  • ev->x() x坐标 ev->y() y坐标

  • ev->button() 可以判断所有按键 Qt::LeftButton Qt::RightButton

  • ev->buttons()判断组合按键 判断move时候的左右键 结合&操作符

  • 格式化字符串 QString("%1 %2").arg(111).arg(222)

myWidget::myWidget(QWidget *parent) : QLabel(parent)
{
    //设置鼠标的追踪状态
    setMouseTracking(true);
}


void myWidget::enterEvent(QEvent *event)
{
    qDebug()<<"enter";
}

void myWidget::leaveEvent(QEvent *event)
{
    qDebug()<<"leave";
}

void myWidget::mouseMoveEvent(QMouseEvent *ev)
{
    //鼠标左键按下,提示信息
//    if(ev->buttons()&Qt::LeftButton)
//    {
        QString str=QString("move x=%1 y=%2").arg(ev->x()).arg(ev->y());
        qDebug()<<str;
//    }
}

void myWidget::mousePressEvent(QMouseEvent *ev)
{
    //鼠标左键按下,提示信息
    if(ev->button()==Qt::LeftButton)
    {
        QString str=QString("press x=%1 y=%2").arg(ev->x()).arg(ev->y());
        qDebug()<<str;
    }
}

void myWidget::mouseReleaseEvent(QMouseEvent *ev)
{
    qDebug()<<"release";
}

04 定时器1

  • 利用时间 void timerEvent(QTimerEvent*ev);

  • 启动定时器 startTimer(1000) 毫秒单位

  • timerEvent的返回值是定时器的唯一表示 可以和ev->timerId作比较

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

    //启动定时器
    id1=startTimer(1000);//参数1 间隔 单位 毫秒
    id2=startTimer(2000);


}

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

void Widget::timerEvent(QTimerEvent* ev)
{
    if(ev->timerId()==id1)
    {
        //label2 每隔1秒+1
        static int num=1;
        ui->label_2->setText(QString::number(num++));
    }

    if(ev->timerId()==id2)
    {
        //label3 每隔2秒+1
        static int num2=1;
        ui->label_3->setText(QString::number(num2+=1));
    }


}

05 定时器2

  • 利用定时器类Qtimer

  • 创建定时器对象 QTimer *timer=new QTimer(this)

  • 启动定时器 timer->start(毫秒)

  • 每隔一定毫秒 发送信号timeout 进行监听

  • 暂停timer->stop

//定时器第二种方式
    QTimer * timer = new QTimer(this);
    //启动定时器
    timer->start(500);

    connect(timer,&QTimer::timeout,[=](){
        static int num = 1;
        //label4 每隔0.5秒+1
        ui->label_4->setText(QString::number(num++));
    });

06 event事件分发器

  • 用途:用于事件的分发

  • 也可以做拦截操作,不建议

  • bool event(QEvent* e)

  • 返回值 如果是true 代表用户处理这个事件,不向下分发了

  • e->type()==鼠标按下

07 事件过滤器

  • 在程序将事件分发到事件分发器前,可以利用过滤器做拦截

  • 步骤

    • 给控件安装事件过滤器

    • 重写eventFilter(obj,e)函数

08 QPainter 绘图

  • 绘图事件 void Widget::paintEvent(QPaintEvent*)

  • 声明一个画家对象 QPainter painter(this);

  • 画线,画圆,画矩形,画文字

  • 设置画笔 QPen 设置画笔宽度 风格

  • 设置画刷 QBrush 设置画刷 风格

  • 如果要刷新,那么用update()函数或者repaint()函数

void Widget::paintEvent(QPaintEvent*)
{
    //实例化画家对象 this 指定的是绘图的设备
    QPainter painter(this);

    //设置画笔
    QPen pen(QColor(255,0,0));

    //设置画笔宽度
    pen.setWidth(1);

    //设置画笔风格
    pen.setStyle(Qt::DotLine);

    //让画家使用这个画笔
    painter.setPen(pen);

    //设置画刷
//    QBrush brush(QColor(0,255,0));
    QBrush brush(Qt::cyan);
    painter.setBrush(brush);

    //画线
    painter.drawLine(QPoint(0,0),QPoint(100,100));

    //画圆
    painter.drawEllipse(QPoint(100,100),50,50);

    //画矩形
    painter.drawRect(QRect(20,20,50,50));

    //画文字
    painter.drawText(QRect(10,200,100,50),"好好学习,天天向上");
}

09 QPainter高级设置

  • 抗锯齿 效率低

    painter.setRenderHint(QPainter::Antialiasing);
    
  • 对画家进行移动

    painter.translate(100,0);
    
  • 保存状态 save

  • 还原状态 restore

  • 如果想手动调用绘图时间 利用update

  • 利用画家画图片 painter.drawPixmap(x,y,QPixmap"");

11 绘图设备

  • QPixmap QImage QBitmap(黑白色) QPicture QWidget

  • QPixmap对不同平台做了显示的优化

    • QPixmap pix(300,300);

    • pix.fill(颜色)

    • 利用画家 往pix上画画

    • 保存 pix.save(“路径”)

  • QImage 可以对像素进行访问

    • 使用和QPixmap差不多QImage img(300,300,QImage::Format_RGB32);

    • 其他流程一样

    • 可以对像素进行修改 img.setPixel(i,j,value);

  • QPicture 记录和重现 绘图的指令

    • QPicture pic

    • painter.begin(&pic)

    • 保存 pic.save(任意后缀名)

    • 重现 利用画家可以重现 painter.drawPicture(0,0,pic);

12 QFile对文件进行读写操作

  • QFile进行读写操作

  • QFile file(path 文件路径)

  • file.open(打开方式)

    • 全部读取 file.readAll()

    • 按行读 file.readLine()

    • atend()判断是否读到文件尾

    • 利用编码格式

    • file.open()

    • file.write()

13QFileInfo 读取文件信息

    //QFileInfo 文件信息类
    QFileInfo info(path);

    qDebug()<<"大小 :"<<info.size()<<"后缀名: "<<info.suffix()<<" 文件名称: "<<info.fileName()<<"文件路径: "<<info.path();

    qDebug()<<"创建日期: "<<info.created().toString("yy/MM/dd hh:mm:ss");

    qDebug()<<"修改日期: "<<info.lastModified().toString("yy MM dd hh:mm:ss");

补充

QRect rect(10 * i + 100, 10 * j + 100, 10, 10); // 定义每个格子的位置和大小
                QBrush brush(Qt::red);  // 创建红色画刷

                // 使用红色画刷填充矩形
                painter.fillRect(rect, brush);

                // 如果需要绘制边框,可以取消注释以下行
                painter.setPen(Qt::black); // 设置边框颜色
                painter.drawRect(rect); // 绘制边框
    filename= QFileDialog::getOpenFileName(this,"打开文件","C:\\Users\\23861\\Desktop","(*.txt *.docx)");
    qDebug()<<filename;
    QFile file(filename);
    file.open(QIODevice::ReadOnly);
    QString firstline=file.readLine();
    qDebug()<<firstline;