QT学习

本文详细介绍了QT基础,包括下载、安装、模块构成、pro文件、cpp文件注释、组件使用、对象树等,并深入探讨了信号槽机制、自定义类和组件、调试输出、组件布局与对话框。涵盖了自定义信号和槽、常用控件实例以及开发工具和实践项目如计算器和文件操作。
摘要由CSDN通过智能技术生成

1.study_01

1.1下载

下载地址
在这里插入图片描述

1.2安装时勾选事项

此选项为QT自带的编译器,采用utf-8
在这里插入图片描述在这里插入图片描述
在这里插入图片描述

1.3几种类之间的关系

在这里插入图片描述

在这里插入图片描述

1.4 QT模块组成

  • 在这里插入图片描述

1.5 pro文件内容相关注释

在这里插入图片描述

1.6 cpp文件注释

在这里插入图片描述

1.7 初步了解部分组件

#include "Widget.h"
#include"QPushButton"
Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    this->setWindowTitle("Hello QT");//设置窗口的标题
    this->resize(400,800);//设置窗口大小
    this->setFixedSize(400,200);//设置窗口固定大小 无法改变窗口大小

    //创建按钮
  QPushButton* btn=new QPushButton;
  btn->setParent(this);//设置父亲,表示在父亲面板里展示
  btn->setText("开始游戏");//设置文本
  QFont font("华文行楷",20,10,1);//创建字体对象(字体,大小哎,加粗,倾斜)
  btn->setFont(font);//设置字体
  btn->move(100,100);//组件距离坐标原点位置
  btn->show();//显示

  //hover:悬浮时显示的颜色   pressed:点击时显示的颜色 
  //rgba:a为1时显示

  btn->setStyleSheet("QPushButton{ background-color: red;}\
                      QPushButton:hover{background-color: green;}\
                      QPushButton:pressed{background-color:rgba(170,155,221,1);}");
}

Widget::~Widget()
{

}

代码运行结果
在这里插入图片描述

1.8 对象树

在这里插入图片描述

  • 当为子组件设置了父窗口后,将程序关闭会自动释放内存
    在这里插入图片描述
  • QT坐标轴位置分布
    在这里插入图片描述

1.9 自定义类如何继承QT已有的接口

在这里插入图片描述

  • 如何引用自定义类
    在这里插入图片描述

1.10 如何在控制台调试输出语句

在这里插入图片描述

1.11 帮助文档位置

在这里插入图片描述

2.study_02

信号和槽:是 QT框架引以为豪的东西。实际上就是 观察者模式 一种简易方式。
使用connect 函数可以为 信号 以及 槽 建立好连接 当信号 广播(触发)时 槽 做出相应的处理,
信号来自于 被观察者
 槽来自于 观察者

2.1 信号在帮助文档里的位置

在这里插入图片描述

2.2 具体实例理解

在这里插入图片描述

2.3 connect函数连接信号和槽

在这里插入图片描述

connect(被观察者,信号,观察者,槽); //用法一
connect(被观察者,信号,Lamda表达式匿名函数);//用法二
connect(被观察者,SIGNAL(信号函数),观察者,SLOT(槽函数));//老版本用法
  • 代码实例
#include "Mywidget.h"
#include <QPushButton>//按钮控件
#include <QDebug>
#include <QLabel>//文本控件
#include <QSlider>//滑动条控件
#include <QProgressBar>//进度条控件
#include <QTextEdit>//文本编辑框控件

MyWidget::MyWidget(QWidget *parent)
    : QWidget(parent)
{
    //最大化按钮 (被观察者)
    auto btnMax = new QPushButton("最大化",this);
    //this窗口   (观察者)
    //建立信号 和 槽连接
    connect(btnMax,&QPushButton::clicked,this,&QWidget::showMaximized);

    auto btnMin = new QPushButton("最小化",this);
    btnMin->move(100,0);
    connect(btnMin,&QPushButton::clicked,this,&QWidget::showMinimized);

    auto btnNormal = new QPushButton("正常",this);
    btnNormal->move(200,0);
    connect(btnNormal,&QPushButton::clicked,this,&QWidget::showNormal);
    }
   

2.4 c++11新特性

在这里插入图片描述

2.5 指针指向Lamda函数

//指针指向 Lamda函数*******************************
    int num = 1;
    void (*pFun)(int&) = [](int& n)->void{
        n = 250;
        qDebug() << n;
    };
    pFun(num);
    qDebug() << num ;
Lamda表达式定义函数语法:
[可访问外部变量](参数表)->返回值{ 函数体 }

[变量名1,变量2...](){}    指定部分变量访问
[=](){}                 值传递形式捕获所有外部变量  (内部无法改变实际变量)
[&](){}                 引用形式捕获所有外部变量    (可以改变实际变量)

在这里插入图片描述

2.6 设计一个鼠标按下松开事件

//设置一个按钮
    //鼠标按下  打印 被打了
    //鼠标抬起  打印 反抗了
    auto btn = new QPushButton("老鼠",this);
    btn->move(300,0);
    //当按钮点击时  调用Lamda表达式函数
    connect(btn,&QPushButton::pressed,[]()->void{
         qDebug() << "老鼠被打了";
    });
    connect(btn,&QPushButton::released,[]()->void{
         qDebug() << "老鼠反抗了";

    });

2.7 Lamda表达式传参

 int num = 1;
    void (*pFun)(int&) = [](int& n)->void{
        n = 250;
        qDebug() << n;
    };
    pFun(num);
    qDebug() << num ;

2.8 常用控件

需先引入头文件

#include "Mywidget.h"
#include <QPushButton>//按钮控件
#include <QDebug>
#include <QLabel>//文本控件
#include <QSlider>//滑动条控件
#include <QProgressBar>//进度条控件
#include <QTextEdit>//文本编辑框控件

  • 代码测试
 //---------------------简单的常用控件

    //********文字控件
    QLabel* label = new QLabel;
    label->setParent(this);
    label->move(0,100);
    label->setText("今天天气如何?");
    label->setFont(QFont("楷体",20,10,1));

    //********滑动条控件
    QSlider* slider = new QSlider;
    slider->setParent(this);
    slider->move(300,100);
    slider->setValue(0);//设置滑动条的值
    slider->setMaximum(100);//设置最大值
    //练习2:通过滑动 滑动条 改变字体大小  valueChanged函数有个参数int value(可进帮助文档查看)
    //value的值会赋给Lamda函数的_value
    connect(slider,&QSlider::valueChanged,[label](int _value){
        label->setFont(QFont(QFont("楷体",_value,10,1)));
        label->resize(500,_value+100);
    });

    //********进度条控件
    QProgressBar* proBar = new QProgressBar;
    proBar->setParent(this);
    proBar->move(0,200);
    proBar->resize(this->size().width(),20);
    proBar->setValue(0);
    //练习3:通过滑动 滑动条 改变进度条进度
    connect(slider,&QSlider::valueChanged,[proBar](int _value){
        proBar->setValue(_value);
    });

    //********文本编辑框
    QTextEdit* edit = new QTextEdit;
    edit->move(0,300);
    edit->resize(200,200);
    edit->setParent(this);
    edit->setFontUnderline(1);//设置文字下划线
    edit->setFontPointSize(50.5);//设置文字大小
    //先设置属性值再写文本,不然没有效果
    edit->setText("小妹妹今天有空么?一起吃饭啊?");
    //练习4: 通过编辑文本框  改变 label文本内容
    connect(edit,&QTextEdit::textChanged,[label,edit](){

        QString text = edit->toPlainText();//获取文本内容
        label->setText(text);
    });

2.9全部代码

#include "Mywidget.h"
#include <QPushButton>//按钮控件
#include <QDebug>
#include <QLabel>//文本控件
#include <QSlider>//滑动条控件
#include <QProgressBar>//进度条控件
#include <QTextEdit>//文本编辑框控件

MyWidget::MyWidget(QWidget *parent)
    : QWidget(parent)
{
    //最大化按钮 (被观察者)
    auto btnMax = new QPushButton("最大化",this);
    //this窗口   (观察者)
    //建立信号 和 槽连接
    connect(btnMax,&QPushButton::clicked,this,&QWidget::showMaximized);

    auto btnMin = new QPushButton("最小化",this);
    btnMin->move(100,0);
    connect(btnMin,&QPushButton::clicked,this,&QWidget::showMinimized);

    auto btnNormal = new QPushButton("正常",this);
    btnNormal->move(200,0);
    connect(btnNormal,&QPushButton::clicked,this,&QWidget::showNormal);

    //设置一个按钮
    //鼠标按下  打印 被打了
    //鼠标抬起  打印 反抗了
    auto btn = new QPushButton("老鼠",this);
    btn->move(300,0);
    //当按钮点击时  调用Lamda表达式函数
    connect(btn,&QPushButton::pressed,[]()->void{
         qDebug() << "老鼠被打了";
    });
    connect(btn,&QPushButton::released,[]()->void{
         qDebug() << "老鼠反抗了";

    });

    //指针指向 Lamda函数*******************************
    int num = 1;
    void (*pFun)(int&) = [](int& n)->void{
        n = 250;
        qDebug() << n;
    };
    pFun(num);
    qDebug() << num ;


    //---------------------简单的常用控件

    //********文字控件
    QLabel* label = new QLabel;
    label->setParent(this);
    label->move(0,100);
    label->setText("今天天气如何?");
    label->setFont(QFont("楷体",20,10,1));

    //********滑动条控件
    QSlider* slider = new QSlider;
    slider->setParent(this);
    slider->move(300,100);
    slider->setValue(0);//设置滑动条的值
    slider->setMaximum(100);//设置最大值
    //练习2:通过滑动 滑动条 改变字体大小  valueChanged函数有个参数int value(可进帮助文档查看)
    //value的值会赋给Lamda函数的_value
    connect(slider,&QSlider::valueChanged,[label](int _value){
        label->setFont(QFont(QFont("楷体",_value,10,1)));
        label->resize(500,_value+100);
    });

    //********进度条控件
    QProgressBar* proBar = new QProgressBar;
    proBar->setParent(this);
    proBar->move(0,200);
    proBar->resize(this->size().width(),20);
    proBar->setValue(0);
    //练习3:通过滑动 滑动条 改变进度条进度
    connect(slider,&QSlider::valueChanged,[proBar](int _value){
        proBar->setValue(_value);
    });

    //********文本编辑框
    QTextEdit* edit = new QTextEdit;
    edit->move(0,300);
    edit->resize(200,200);
    edit->setParent(this);
    edit->setFontUnderline(1);//设置文字下划线
    edit->setFontPointSize(50.5);//设置文字大小
    //先设置属性值再写文本,不然没有效果
    edit->setText("小妹妹今天有空么?一起吃饭啊?");
    //练习4: 通过编辑文本框  改变 label文本内容
    connect(edit,&QTextEdit::textChanged,[label,edit](){

        QString text = edit->toPlainText();//获取文本内容
        label->setText(text);
    });

    //******************补充: 老版本QT4以前 信号和槽的绑定方式
    //点击按钮 最大化窗口
    auto btn10 = new QPushButton("老版本测试按钮",this);
    connect(btn10,SIGNAL(clicked()),this,SLOT(showMaximized()));









}

MyWidget::~MyWidget()
{

}

  • 程序运行结果
    在这里插入图片描述

3.study_03

3.1自定义信号和槽

  • 先自定义信号和槽
    在这里插入图片描述
    在这里插入图片描述
  • 内容总结
QT内置的大量信号和槽 还支持用户自定义信号 和 槽。

自定义槽:
    1.有函数声明且有实现
    2.返回值类型为 void
    3.槽函数 可以带参 可以重载  (槽函数实参 是从信号而来)
自定义信号:
    1.写在 Signal: 下
    2.只需声明 无需实现
    3.返回值为 void
    4.支持带参 且可重载
    5.emit 可触发信号

自定义信号和槽的特点:
    1. 一个信号 可以被 多个槽绑定
    2. 同一个槽函数 可以绑 多个信号
    3. 信号 和 槽的 函数参数表 需一 一对应
    4. 信号的参数表 可以 多余 槽函数的参数表
        反之  槽函数的参数表 不能多余 信号的参数表
    5.信号 可以 绑定信号

//信号和槽 断开连接
disconnect 断开连接
connect 连接
  • 逻辑:点击按钮触发广播widget的广播函数,再用广播函数激活Boss死亡信号,再用Boss死亡信号触发Boss死亡槽函数,然后Role增加相应的经验
    • 目录结构
      在这里插入图片描述
    • Boss.h代码
    #ifndef BOSS_H
    #define BOSS_H
    
    #include <QWidget>
    
    class Boss : public QWidget
    {
        Q_OBJECT
    public:
        //explicit关键字  修饰函数参数 无法自动转换类型
        explicit Boss(QString _name,int _exp, QWidget *parent = nullptr);
    
        int exp;//经验值
        QString name;//名字
    
    
    signals://信号定义
        //自定义信号
        void DeadSignal();//定义死亡信号
        void DeadSignal(int _exp);//定义死亡信号 重载
    
    public slots://槽函数定义
        void BossDeadSlot();//boss 死亡槽函数
    };
    
    #endif // BOSS_H
    
    
    -Boss.cpp
    #include "Boss.h"
    #include <QtDebug>
    Boss::Boss(QString _name,int _exp,QWidget *parent) : QWidget(parent)
    {
        exp = _exp;
        name = _name;
    }
    
    void Boss::BossDeadSlot()
    {
        qDebug() << name <<" 被击杀! 掉落经验:" << exp ;
    }
    
    
    -Role.h
    #ifndef ROLE_H
    #define ROLE_H
    
    #include <QWidget>
    
    class Role : public QWidget
    {
        Q_OBJECT
    public:
        explicit Role(QWidget *parent = nullptr);
    
    signals:
    
    public slots:
        void GetExp();//获得经验槽函数
        void GetExp(int _exp);//获得经验槽函数 重载
    };
    
    #endif // ROLE_H
    
    
    -Role.cpp
    #include "Role.h"
    #include <QtDebug>
    Role::Role(QWidget *parent) : QWidget(parent)
    {
    
    }
    
    void Role::GetExp()
    {
        qDebug() << "角色获得经验";
    }
    
    void Role::GetExp(int _exp)
    {
        qDebug() << "角色获得"<< _exp << "点经验";
    }
    
    
    -Widget.h
    #ifndef WIDGET_H
    #define WIDGET_H
    
    #include <QWidget>
    #include "Boss.h"
    #include "Role.h"
    
    class Widget : public QWidget
    {
        Q_OBJECT
    
    public:
        Widget(QWidget *parent = 0);
        ~Widget();
    
        Boss* mBoss;//被观察者
        Role* mRole;//观察者
    
    public slots:
        //广播 boss死亡信号
        void BossDeadBroadcast();
    };
    
    #endif // WIDGET_H
    
    
    Widget.cpp
    	#include "Widget.h"
    #include "Boss.h"
    #include <QPushButton>
    #include <QDebug>
    #include "Role.h"
    
    Widget::Widget(QWidget *parent)
        : QWidget(parent)
    {
        mBoss = new Boss("美猴王",10000);
        mRole = new Role;
    
    
        //观察者  boss   槽函数 死亡打印
        //被观察者 按钮   信号  点击
        //按钮点击  处理boss 死亡
    //    auto btn = new QPushButton("击杀",this);//被观察者  (信号源)
    //    auto boss1 = new Boss("白蛇",2000);//观察者
    //    auto boss2 = new Boss("青蛇",1500);//观察者
    //boss1中的属性能被BossDeadSlot函数取到
    //    connect(btn,&QPushButton::clicked,boss1,&Boss::BossDeadSlot);//绑定信号
    
        //boss 死亡信号 广播后  触发 boss死亡槽函数
        //思路:点击按钮 触发死亡信号  死亡信号 对应boss死亡槽函数处理
        QPushButton* btn2 = new QPushButton("播放死亡信号",this);
        connect(btn2,&QPushButton::clicked,this,&Widget::BossDeadBroadcast);//点击触发 信号广播 广播boss死亡信号
    
        //-----------重载后无参 信号 和 槽 绑定
        //信号指针,由于指向信号地址,所以都加上Boss,最初定义为void(*deadSignal0)(参数)
        void(Boss::*deadSignal0)() = &Boss::DeadSignal;
        void(Boss::*bossDeadSlot0)() = &Boss::BossDeadSlot;//槽指针
        connect(mBoss,deadSignal0,mBoss,bossDeadSlot0);//死亡信号触发后  死亡槽函数处理打印
    
    
        //boss死亡信号触发后  角色获得经验处理
    //    connect(mBoss,&Boss::DeadSignal,mRole,&Role::GetExp);
    
        //-----------重载后 连接带参的信号和槽
        //信号的参数表 可以 多余 槽函数的参数表
        void(Boss::*deadSignal)(int) = &Boss::DeadSignal;//信号指针
        void(Role::*getExp)(int) = &Role::GetExp;//带参槽指针
        void(Role::*getExp0)() = &Role::GetExp;//无参槽函数指针
        connect(mBoss,deadSignal,mRole,getExp0);
    
    
        //信号 绑定 信号
        auto btn3 = new QPushButton("信号连接信号测试",this);
        btn3->move(100,0);
        connect(btn3,&QPushButton::clicked,mBoss,deadSignal0);//点击信号  绑定  死亡信号
    
    
        //断开信号 和 槽连接
        disconnect(btn3,&QPushButton::clicked,mBoss,deadSignal0);
    
    
    
    
    }
    
    Widget::~Widget()
    {
    
    }
    
    void Widget::BossDeadBroadcast()
    {
        //触发死亡信号逻辑
        qDebug() << "死亡信号广播!";
        emit mBoss->DeadSignal();//此处为触发信号  emit用于触发信号
        emit mBoss->DeadSignal(mBoss->exp);//触发带参信号
    
    
    }
    
    
    -效果图
    在这里插入图片描述

4.study_05

5.1 主窗口五大部件

在这里插入图片描述

  • 效果示意图
    在这里插入图片描述
  • 代码实现
#include "Mainwindow.h"
#include "ui_mainwindow.h"
#include <QPushButton>
#include <QLabel>
#include <QTextEdit>
#include <QDockWidget>//浮动窗口
#include <QDialog>//对话框
#include <QFileDialog>//文件对话框
#include <QColorDialog>//颜色对话框
#include <QFontDialog>//文字对话框
#include <QMessageBox>//消息对话框 (警告,普通,错误)
#include <QDebug>

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

    //-------------------菜单栏 在主窗口中只存在一个
    QMenuBar* menuBar = new QMenuBar;
    this->setMenuBar(menuBar);//设置菜单栏
    QMenu* menu = menuBar->addMenu("文件");
    menu->addAction("打开");
    menu->addSeparator();
    menu->addAction("新建");
    menuBar->addMenu("编辑");

    //-------------------工具栏  存在多个
    QToolBar* toolBar = new QToolBar;
    this->addToolBar(toolBar);//设置工具栏  (默认停靠范围 工具栏)
    toolBar->setAllowedAreas(Qt::LeftToolBarArea | Qt::RightToolBarArea);//设置允许停靠范围,没设置的话会可以随意拖拽
    toolBar->setMovable(true);//是否移动的
    toolBar->setFloatable(false);//是否可悬浮
    toolBar->addAction("编辑");
    toolBar->addSeparator();//添加分割线
    toolBar->addAction("打开");

    //-------------------状态栏
    QStatusBar* status = statusBar();
    status->addAction(new QAction("FPS:600"));
    status->addWidget(new QPushButton("FPS:600"));//添加按钮
    status->addWidget(new QLabel("PIN:20"));//添加文本
    status->addPermanentWidget(new QLabel("今天天气很好"));//在右边添加
    this->setStatusBar(status);

    //------------------中心部件
    this->setCentralWidget(new QTextEdit("请输入..."));

    //-------------------衔接部件 (浮动窗口)
    QDockWidget* dock = new QDockWidget("文本1");
    dock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);//设置允许停靠范围
    this->addDockWidget(Qt::LeftDockWidgetArea,dock);
    }

MainWindow::~MainWindow()
{
    delete ui;
}
  • 使用ui设计组件不能使用中文设计名字,因为它的实质为一个对象,所以只能在写代码中进行名字的修改或者选中该组件在右边进行可视化编辑
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

5.2对话框

//----------------对话框  QT中内置了大量的对话框 供开发者使用   
//自定义对话框  :                                  
//     a.模态对话框: 阻塞式创建对话框 无法对其他对话框做操作         
//     b.非模态对话框: 非阻塞式 激活时可以对其他窗口做操作      

 QT内置对话框(标准对话框):                               
     1.文件对话框  QFileDialog::getOpenFileName     
     2.颜色对话框  QColorDialog::getColor           
     3.文字对话框  QFontDialog::getFont             
     4.消息对话框  (1:父亲 2:标题 3:内容 4:按钮 5:回车时默认选择)  
                 QMessageBox::critical 危险的     
                 QMessageBox::warning 警告       
                 QMessageBox::information 消息       
  • 效果图
    • 文件对话框
      在这里插入图片描述

    • 颜色对话框
      在这里插入图片描述

    • 文字对话框
      在这里插入图片描述

    • 消息对话框
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述

5.3总结

  • 总效果图
    在这里插入图片描述- 代码
#include "Mainwindow.h"
#include "ui_mainwindow.h"
#include <QPushButton>
#include <QLabel>
#include <QTextEdit>
#include <QDockWidget>//浮动窗口
#include <QDialog>//对话框
#include <QFileDialog>//文件对话框
#include <QColorDialog>//颜色对话框
#include <QFontDialog>//文字对话框
#include <QMessageBox>//消息对话框 (警告,普通,错误)
#include <QDebug>

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

//    //-------------------菜单栏 在主窗口中只存在一个
//    QMenuBar* menuBar = new QMenuBar;
//    this->setMenuBar(menuBar);//设置菜单栏
//    QMenu* menu = menuBar->addMenu("文件");
//    menu->addAction("打开");
//    menu->addSeparator();
//    menu->addAction("新建");
//    menuBar->addMenu("编辑");

//    //-------------------工具栏  存在多个
//    QToolBar* toolBar = new QToolBar;
//    this->addToolBar(toolBar);//设置工具栏  (默认停靠范围 工具栏)
//    toolBar->setAllowedAreas(Qt::LeftToolBarArea | Qt::RightToolBarArea);//设置允许停靠范围,没设置的话会可以随意拖拽
//    toolBar->setMovable(true);//是否移动的
//    toolBar->setFloatable(false);//是否可悬浮
//    toolBar->addAction("编辑");
//    toolBar->addSeparator();//添加分割线
//    toolBar->addAction("打开");

//    //-------------------状态栏
//    QStatusBar* status = statusBar();
//    status->addAction(new QAction("FPS:600"));
//    status->addWidget(new QPushButton("FPS:600"));//添加按钮
//    status->addWidget(new QLabel("PIN:20"));//添加文本
//    status->addPermanentWidget(new QLabel("今天天气很好"));//在右边添加
//    this->setStatusBar(status);

//    //------------------中心部件
//    this->setCentralWidget(new QTextEdit("请输入..."));

//    //-------------------衔接部件 (浮动窗口)
//    QDockWidget* dock = new QDockWidget("文本1");
//    dock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);//设置允许停靠范围
//    this->addDockWidget(Qt::LeftDockWidgetArea,dock);



    //----------------访问ui中的对象
//    ui->menunum1->setTitle("开始执行不调试");
//    connect(ui->horSliderBar,&QSlider::valueChanged,ui->progressBar,&QProgressBar::setValue);


    //----------------对话框  QT中内置了大量的对话框 供开发者使用
    //自定义对话框  :
    //     a.模态对话框: 阻塞式创建对话框 无法对其他对话框做操作
    //     b.非模态对话框: 非阻塞式 激活时可以对其他窗口做操作

    //模态对话框创建
    connect(ui->btn1,&QPushButton::clicked,this,[this](){
        //创建窗口
        QDialog dialog(this);   //使用局部变量,如果用new,在程序结束之后才会释放,如果创建多了对话框就会占内存
        dialog.resize(200,200);

        dialog.exec();//进入消息捕捉循环
    });

    //非模态
    connect(ui->btn2,&QPushButton::clicked,[this](){
        QDialog dialog(this);
        dialog.resize(200,200);
        dialog.show();
        dialog.exec();//进入消息捕捉循环

        //方式二
        QDialog* dialogP =new QDialog(this);
        dialogP->show();
        dialogP->setAttribute(Qt::WA_DeleteOnClose);//关闭时释放对话框

    });

    /*
    QT内置对话框(标准对话框):
        1.文件对话框  QFileDialog::getOpenFileName
        2.颜色对话框  QColorDialog::getColor
        3.文字对话框  QFontDialog::getFont
        4.消息对话框  (1:父亲 2:标题 3:内容 4:按钮 5:回车时默认选择)
                    QMessageBox::critical 危险的
                    QMessageBox::warning 警告
                    QMessageBox::information 消息

    */
    connect(ui->FileBtn,&QPushButton::clicked,[this](){
        //(参数1:父亲 ,参数2:标题, 参数3:默认打开路径 ,参数4:过滤文件类型)
       QString fileName = QFileDialog::getOpenFileName(this,"打开文本文件","C:/Users/hz/Desktop","*.txt");
       qDebug() << fileName;

      //(默认颜色,父亲,标题)
      auto color= QColorDialog::getColor(Qt::blue,this,"文字颜色");
      ui->textEdit->setTextColor(color);
      ui->textEdit->setText("jjjj");

      //文字对话框
      bool bl = true;//是否使用 用户选择的字体
      QFont font =  QFontDialog::getFont(&bl);
      ui->label->setFont(font);
      ui->label->setText("你好");
      qDebug() << bl;

    //消息对话框
      QMessageBox::critical(this,"错误","你错了",QMessageBox::Close);
      QMessageBox::warning(this,"警告","你错了");
      QMessageBox::information(this,"提示","你错了");

       auto btn = QMessageBox::question(this,"问题","你爱我么?",QMessageBox::Yes|QMessageBox::No,QMessageBox::Yes);
       if(btn == QMessageBox::Yes)
       {
           QMessageBox::information(this,"","我也爱你!");
       }
       else
       {
           QMessageBox::critical(this,"错误","系统错误!");
       }




  });










}

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

5.study_06_计算器的制作

5.1快速布局

在这里插入图片描述
选中所有按钮后再点击这个栅格布局,就能完成快速布局
在这里插入图片描述
在这里插入图片描述

-调节宽度和高度消除按钮间隔
在这里插入图片描述

  • 文本对齐方式
    在这里插入图片描述

5.2代码逻辑

字符串转double,数字转为字符串+尾部删除字符

double num1 = mNum1.toDouble();//将字符串转换为 小数
 double num2 = mNum2.toDouble();//将字符串转换为 小数
 ui->lineEdit->setText(QString::number(result));//QString::number  数字转换为字符串QString
  mNum2.chop(1);//chop 尾部删除字符串 指定个数字符
  • 界面美化
    方法一:
    在这里插入图片描述
    在这里插入图片描述

方法二:

ui->Equal->setStyleSheet("QPushButton::hover {background-color: rgb(85,85,255)}");
}
  • 项目结构
    在这里插入图片描述
  • Widget.h代码
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

enum BtnType//按钮类型
{
    Num,//数字
    Op,//运算符
    Dot,//点
    Equal,//等于
    Clear,//清除
    Back //退格
};

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

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

private:
    Ui::Widget *ui;

    QString mNum1;//操作数1
    QString mNum2;//操作数2
    QString mOp;//运算符

public slots:
    void OnClicked(BtnType _type,QString _btn);


};

#endif // WIDGET_H

  • Widget.cpp代码
#include "Widget.h"
#include "ui_widget.h"

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

    //数字按钮绑定
    connect(ui->Num0,&QPushButton::clicked,[this](){ OnClicked(Num,"0");});
    connect(ui->Num1,&QPushButton::clicked,[this](){ OnClicked(Num,"1");});
    connect(ui->Num2,&QPushButton::clicked,[this](){ OnClicked(Num,"2");});
    connect(ui->Num3,&QPushButton::clicked,[this](){ OnClicked(Num,"3");});
    connect(ui->Num4,&QPushButton::clicked,[this](){ OnClicked(Num,"4");});
    connect(ui->Num5,&QPushButton::clicked,[this](){ OnClicked(Num,"5");});
    connect(ui->Num6,&QPushButton::clicked,[this](){ OnClicked(Num,"6");});
    connect(ui->Num7,&QPushButton::clicked,[this](){ OnClicked(Num,"7");});
    connect(ui->Num8,&QPushButton::clicked,[this](){ OnClicked(Num,"8");});
    connect(ui->Num9,&QPushButton::clicked,[this](){ OnClicked(Num,"9");});

    //运算符按钮绑定
    connect(ui->Sum,&QPushButton::clicked,[this](){ OnClicked(Op,"+");});
    connect(ui->Sub,&QPushButton::clicked,[this](){ OnClicked(Op,"-");});
    connect(ui->Mul,&QPushButton::clicked,[this](){ OnClicked(Op,"*");});
    connect(ui->Div,&QPushButton::clicked,[this](){ OnClicked(Op,"/");});

    //其他按钮绑定
    connect(ui->Back,&QPushButton::clicked,[this](){ OnClicked(Back,"Back");});
    connect(ui->Clear,&QPushButton::clicked,[this](){ OnClicked(Clear,"Clear");});
    connect(ui->Dot,&QPushButton::clicked,[this](){ OnClicked(Dot,".");});
    connect(ui->Equal,&QPushButton::clicked,[this](){ OnClicked(Equal,"=");});

    //ui->Equal->setStyleSheet("QPushButton::hover {background-color: rgb(85,85,255)}");
}

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


void Widget::OnClicked(BtnType _type,QString _btn)
{
    switch (_type) //按钮类型
    {
        case Num://数字
        {
            if(mOp.isEmpty())//如果运算符为空 说明输入的是操作数一
            {
                mNum1 += _btn;
            }
            else//非空  则输入的是操作数二
            {
                mNum2 += _btn;
            }
            break;
        }
        case Op://运算符
        {
            if(!mNum1.isEmpty() && !mNum2.isEmpty())
            {
                double num1 = mNum1.toDouble();//将字符串转换为 小数
                double num2 = mNum2.toDouble();//将字符串转换为 小数
                double result = 0.0;//运算结果
                if(mOp == "+")
                    result = num1 +num2;
                else if(mOp == "-")
                    result = num1-num2;
                else if(mOp == "*")
                    result = num1*num2;
                else if(mOp == "/")
                {
                    if(num2 == 0.0)
                    {
                        ui->lineEdit->setText("除数不能为0!");
                        return;
                    }
                    else
                    {
                        result = num1 / num2;
                    }
                }

                //显示运算结果
                ui->lineEdit->setText(QString::number(result));//QString::number  数字转换为字符串QString
                mNum1 = QString::number(result);
                mNum2.clear();
            }

            mOp = _btn;
            break;
        }
        case Dot://{
            if(mOp.isEmpty())
            {
                //操作数一 的小数点
                if(!mNum1.isEmpty() && !mNum1.contains("."))//操作数1没有点 且不空
                {
                    mNum1 += _btn;
                }
            }
            else
            {
                //操作数二 的点
                if(!mNum2.isEmpty() && !mNum2.contains("."))//操作数2没有点 且不空
                {
                    mNum2 += _btn;
                }
            }
            break;
        }
        case Back://退格
        {
            if(!mNum1.isEmpty() && !mNum2.isEmpty() && !mOp.isEmpty())//删除操作数二
            {
                mNum2.chop(1);//chop 尾部删除字符串 指定个数字符
            }
            else if(!mNum1.isEmpty() && !mOp.isEmpty())//删除运算符
            {
                mOp.chop(1);
            }
            else if(!mNum1.isEmpty())
            {
                mNum1.chop(1);
            }
            break;
        }
        case Clear://清除
        {
            mNum1.clear();
            mNum2.clear();
            mOp.clear();
            break;
        }

        case Equal://等于
        {
            if(mNum1.isEmpty() || mNum2.isEmpty() || mOp.isEmpty())
                return;

            double num1 = mNum1.toDouble();//将字符串转换为 小数
            double num2 = mNum2.toDouble();//将字符串转换为 小数
            double result = 0.0;//运算结果
            if(mOp == "+")
                result = num1 +num2;
            else if(mOp == "-")
                result = num1-num2;
            else if(mOp == "*")
                result = num1*num2;
            else if(mOp == "/")
            {
                if(num2 == 0.0)
                {
                    ui->lineEdit->setText("除数不能为0!");
                    return;  //防止再调用下面的显示功能
                }
                else
                {
                    result = num1 / num2;
                }
            }

            //显示运算结果
            ui->lineEdit->setText(QString::number(result));//QString::number  数字转换为字符串QString
            mNum1.clear();
            mNum2.clear();
            mOp.clear();
            return;
        }

    }

    //显示运算
    ui->lineEdit->setText(mNum1 + mOp + mNum2);
}

  • 效果图
    在这里插入图片描述

5.3项目发布

  • 1.修改发布路径
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

  • 2.如何发布出用户可以执行的.exe文件
    在这里插入图片描述1.打开控制台程序
    在这里插入图片描述
    2.输入windeployqt+执行文件绝对路径

在这里插入图片描述
3.然后将运行后的文件夹发给别人就能运行了
在这里插入图片描述

  • 3.开发者环境配置
    在这里插入图片描述
    配置好环境后能使用bin文件夹里面的库(.dll文件)里面的函数
    在这里插入图片描述
    在这里插入图片描述

6.study_07

6.1资源文件加载及使用

  • 新建资源文件夹
    在这里插入图片描述
    -添加文件进去
    在这里插入图片描述
  • 再次打开资源的方式改变
    在这里插入图片描述
  • 复制资源路径
    在这里插入图片描述
  • 代码实现
 /*
    资源文件加载方式:
        1.右键项目 添加新文件(add new)
        2.选择QT模版 选择qt resource file
        3.命名资源文件名
        4.添加资源前缀 添加文件

    使用资源文件路径格式: ": + 前缀 + 资源路径"
    */
    ui->actionopen->setIcon(QIcon(":/icon/iconImg/boss004.png"));
    ui->actionedit->setIcon(QIcon(":/test/iconImg/boss005.png"));
    
  • 效果图
    在这里插入图片描述
    -tool button适合做图片按钮
    在这里插入图片描述
  • tool button和push button区别
    在这里插入图片描述
  • tool button如何既显示文本又显示图片

在这里插入图片描述

6.2树形窗口部件

  • 效果图
    在这里插入图片描述
  • 代码
#include "mainwindow.h"
#include "ui_mainwindow.h"

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

    //树形窗口
    //方法一
//    QStringList strLi;
//    strLi.append("类型");
//    strLi.append("详细介绍");
//    ui->treeWidget->setHeaderLabels(strLi);
    //方法二
    //设置标头
    ui->treeWidget->setHeaderLabels(QStringList()<<"名称"<<"类型" <<"详细介绍");

    //添加列表项
    QTreeWidgetItem* chunyang = new QTreeWidgetItem(QStringList()<<"纯阳"<<"根骨" <<"法术攻击,远程爆发职业,控制力强.");
    QTreeWidgetItem* tiance = new QTreeWidgetItem(QStringList()<<"天策"<<"力量" <<"天策府,大唐守卫者.");
    ui->treeWidget->addTopLevelItem(chunyang);
     ui->treeWidget->addTopLevelItem(tiance);

    //为列表添加子项
    QStringList li;
    li << "紫气" << "根骨" << "远程爆发";
    QTreeWidgetItem* test = new QTreeWidgetItem(li);
//    test->setIcon(QIcon(":/")) //设置图标
    chunyang->addChild(test);




}

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

  • 登录界面布局
从第2331分钟开始看
//如果你设置好界面后,固定窗口大小
setFixedSize(377,307);
  • 密码框
    在这里插入图片描述

7.study_08

8.1文件数据写入和保存文件

-可视化自动绑定槽
在这里插入图片描述
在这里插入图片描述
然后它就会自动生成槽,而且是隐式绑定该按钮和槽,无需用connect函数连接了,不过该函数的内在逻辑还是要自己写

  • 效果图
    在这里插入图片描述
  • 代码
#include "MainWindow.h"
#include "ui_mainwindow.h"
#include <QFileDialog>
#include <QDebug>
#include <QSettings> //设置

class Student
{
public:
    QString name;
    int id;
    bool sex;

    //重载 <<  >> 运算符
    friend QDataStream& operator<<(QDataStream& stream,Student& stu);
    friend QDataStream& operator>>(QDataStream& stream,Student& stu);

};

QDataStream& operator<<(QDataStream& stream,Student& stu)
{
    stream << stu.name << stu.id << stu.sex;
    return stream;
}
QDataStream& operator>>(QDataStream& stream,Student& stu)
{
    stream >> stu.name >> stu.id >> stu.sex;
    return stream;
}


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

    ui->verticalSlider->setMaximum(100);

    //读取配置文件音量
    QSettings setting("config.ini");
    ui->verticalSlider->setValue(  setting.value("volume").toInt() );




}

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

//------------------文件读取
void MainWindow::on_FileBtn_clicked()
{
    QString fileName = QFileDialog::getOpenFileName(this,"选择文件","C:/");
    ui->lineEdit->setText(fileName);

    QFile file(fileName);//构建文件对象 对文件做相关操作
    if(!file.open(QIODevice::ReadOnly))//打开文件用于读  判断是否正常打开
        return;

    QByteArray arr;//子节数组
    while (!file.atEnd())//判断文件结尾
    {
        arr += file.readLine();
    }
    ui->textEdit->setText(arr);


    file.close();//文件关闭
}

//---------------------------文件写入 (另存为)
void MainWindow::on_SaveAsBtn_clicked()
{
    QString filename = QFileDialog::getSaveFileName(this,"另存为","C:/未命名.docx","*.docx");

    QFile file(filename);//创建文件对象
    if(!file.open(QIODevice::WriteOnly))//打开文件用于写
        return;

    QString text = ui->textEdit->toPlainText();//文本框内容
    file.write(text.toUtf8());//text.toUtf8() 转换为 QByteArray 字节数组

    file.close();

}

//课堂练习1:点击按钮 打开一个文件 读取内容到 文本框  点击保存按钮 将新的内容存为新的 .txt文件


//-----------------------保存为 二进制文件
void MainWindow::on_SaveAsBinBtn_clicked()
{
    QString fileName = QFileDialog::getSaveFileName(this,"保存为二进制","C:/未命名.bin","*.bin");

//    QString text = ui->textEdit->toPlainText();//获取文本框内容

    //创建文件对象
    QFile file(fileName);
    if(!file.open(QIODevice::WriteOnly))
        return;

    //创建数据流对象 数据流对象是专门用来读取二进制文件的
    QDataStream fout(&file);//传指入文件对象针
    QString str = "袁力在睡觉?";
    Student stu{"袁力",10086,true};

    fout << 12345;
    fout << str;
    fout << stu;

    file.close();

}

//-----------------------读取二进制文件
void MainWindow::on_OpenBinBtn_clicked()
{
    QString fileName = QFileDialog::getOpenFileName(this,"选择二进制文件","C:/","*.bin *.txt");

    //文件对象
    QFile file(fileName);
    if(!file.open(QIODevice::ReadOnly))
        return;

    //创建数据流对象
    QDataStream fin(&file);
    int num;
    QString str;
    Student stu;

    fin >> num;
    fin >> str;
    fin >> stu;

    QString info = "Name:" + stu.name + " id:" + QString::number(stu.id) + " sex:";
    info +=  (stu.sex ? "男" : "女");
    ui->textEdit->setText(info);

    file.close();

}

void MainWindow::on_verticalSlider_valueChanged(int value)
{
    ui->label->setText("当前音量:" + QString::number(value) + "%");

    //创建一个配置文件对象
    QSettings settingsFile("config.ini");

    //保存音量到配置文件
    settingsFile.setValue("volume",value);



}

8.study_09

8.1鼠标、键盘事件介绍

-事件在帮助文档里面的位置
在这里插入图片描述

-鼠标位置
、

  • Widget.h
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

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


    //键盘事件******************************
    virtual void keyPressEvent(QKeyEvent *event);//按下

    virtual void
    keyReleaseEvent(QKeyEvent *event);//抬起


    //鼠标事件**********************************
    virtual void
    leaveEvent(QEvent *event);//鼠标离开


    virtual void
    enterEvent(QEvent *event);//鼠标进入


    virtual void
    mouseDoubleClickEvent(QMouseEvent *event);//双击

    virtual void
    mouseMoveEvent(QMouseEvent *event);//鼠标移动   默认一直按住移动才相应

    virtual void
    mousePressEvent(QMouseEvent *event);//鼠标按下

    virtual void
    mouseReleaseEvent(QMouseEvent *event);//鼠标抬起


    virtual void
    wheelEvent(QWheelEvent *event);//鼠标滚轮



private:
    Ui::Widget *ui;
};

#endif // WIDGET_H

  • Widget.cpp
#include "Widget.h"
#include "ui_widget.h"
#include <QtDebug>
#include <QKeyEvent>
#include <QMouseEvent>

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

    //激活鼠标移动检测 (默认false 表示按下鼠标左键检测  true 实时检测鼠标移动)
    this->setMouseTracking(false);
}

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


void Widget::keyPressEvent(QKeyEvent *event)//按下
{

    switch (event->key())
    {
        case Qt::Key_W: qDebug() << "前进";break;
        case Qt::Key_S: qDebug() << "后退";break;
        case Qt::Key_A: qDebug() << "左行";break;
        case Qt::Key_D: qDebug() << "右行";break;
    }

}

void Widget::keyReleaseEvent(QKeyEvent *event)//抬起
{
    switch (event->key())
    {
        case Qt::Key_Up: qDebug() << "前进";break;
        case Qt::Key_Down: qDebug() << "后退";break;
        case Qt::Key_Left: qDebug() << "左行";break;
        case Qt::Key_Right: qDebug() << "右行";break;
    }
}

void
Widget::leaveEvent(QEvent *event)
{
    qDebug() << "你离开了";
}


void
Widget::enterEvent(QEvent *event)
{
    qDebug() << "你进来了";
}

void
Widget::mouseDoubleClickEvent(QMouseEvent *event)
{
    if(event->button() == Qt::LeftButton)
    {
        qDebug() << "双击左键";
    }
    else if(event->button() == Qt::RightButton)
    {
        qDebug() << "双击右键";
    }

}

//鼠标移动
void Widget::mouseMoveEvent(QMouseEvent *event)
{
    qDebug() << "移动了";
}

//鼠标按下
void Widget::mousePressEvent(QMouseEvent *event)
{

}

//鼠标抬起
void Widget::mouseReleaseEvent(QMouseEvent *event)
{

}

8.2控件拖拽移动

  • 图解控件拖拽移动
    在这里插入图片描述

  • 由于本次课堂讲解的例子是toolbutton控件的拖拽移动,我们先自定义类继承toolbutton
    在这里插入图片描述

  • 写完代码后,记得将控件提升为自己自定义的类
    在这里插入图片描述在这里插入图片描述

  • 让Button的边框消失
    在这里插入图片描述
    在这里插入图片描述

  • 成员函数的快速重构
    在这里插入图片描述

  • 向量的数乘、点乘、叉乘
    在这里插入图片描述

  • 代码目录结构
    在这里插入图片描述

  • mybutton.h

#ifndef MYBUTTON_H
#define MYBUTTON_H

#include <QToolButton>

class MyButton : public QToolButton
{
    Q_OBJECT
public:
    explicit MyButton(QWidget *parent = nullptr);

    void mouseMoveEvent(QMouseEvent* event);
    void mousePressEvent(QMouseEvent* event);

    void keyPressEvent(QKeyEvent* event);

private:
    QPoint mousePressPos;//鼠标点击位置
    int mSpeed;
signals:

public slots:
};

#endif // MYBUTTON_H

  • mybutton.cpp
#include "mybutton.h"
#include <QMouseEvent>
#include <QtDebug>


MyButton::MyButton(QWidget *parent)
    : QToolButton(parent)
{
    this->setAutoRaise(true);
    mSpeed = 5;
}

void MyButton::mouseMoveEvent(QMouseEvent *event)
{
    //求鼠标移动量  =  鼠标新位置 - 鼠标点击时位置
    QPoint deltaMove = event->pos() - mousePressPos;
    //求窗口新位置 = 窗口位置 + 鼠标移动量

    this->move(this->pos() + deltaMove);

}

void MyButton::mousePressEvent(QMouseEvent *event)
{
    mousePressPos = event->pos();//获取鼠标点击位置
    qDebug() << "获取鼠标点击" << mousePressPos ;
}

void MyButton::keyPressEvent(QKeyEvent *event)
{
    switch (event->key())
    {

    case Qt::Key_A:
    {
        QPoint pos = this->pos() + QPoint(-1,0)*mSpeed;
        this->move(pos);
        break;
    }
    case Qt::Key_D:
    {
        QPoint pos = this->pos() + QPoint(1,0)*mSpeed;
        this->move(pos);
        break;
    }
    case Qt::Key_W:
    {
        QPoint pos = this->pos() + QPoint(0,-1)*mSpeed;
        this->move(pos);
        break;
    }

    case Qt::Key_S:
    {
        QPoint pos = this->pos() + QPoint(0,1)*mSpeed;
        this->move(pos);
        break;
    }
    }
}

  • widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
#include "mybutton.h"

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

//    QPoint a(0,3);
//    QPoint b(3,0);
//    qDebug() << a + b ;

    QPixmap img(":/icon/hdImage/02.png");
    qDebug() << img.width() << "x" << img.height();
    QIcon icon(img);

    ui->MyImg->setIcon(icon);
    ui->MyImg->setIconSize(img.size());


}

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

8.3拖拽实现图片位置交换

请添加图片描述

  • 项目结构
    在这里插入图片描述
  • Hero.h
#ifndef HERO_H
#define HERO_H

#include <QToolButton>

class Hero : public QToolButton
{
    Q_OBJECT
public:
    explicit Hero(QWidget *parent = nullptr);

protected:
    QPoint mPressPos;//鼠标按下位置
    QPoint mPos;//保存图片位置

    virtual void
    mouseMoveEvent(QMouseEvent *event);
    virtual void
    mousePressEvent(QMouseEvent *event);
    virtual void
    mouseReleaseEvent(QMouseEvent *event);


signals:

public slots:
};

#endif // HERO_H

  • hero.cpp
#include "Hero.h"
#include <QMouseEvent>
#include "Widget.h"
#include <QDebug>

Hero::Hero(QWidget *parent) : QToolButton(parent)
{

}


void
Hero::mouseMoveEvent(QMouseEvent *event)
{
    //计算鼠标偏移量
    QPoint delta = event->pos() - mPressPos;
    this->move( this->pos() + delta);//图片移动对应偏移量

}
void
Hero::mousePressEvent(QMouseEvent *event)
{
    mPressPos = event->pos();//获取鼠标按下位置
    mPos = this->pos();//获取当前图片位置

}
void
Hero::mouseReleaseEvent(QMouseEvent *event)
{
    for (int i = 0;i < Widget::mVecIcon.size();i++)
    {
        //this->pos() + event->pos() 鼠标的全局位置
        if(Widget::mVecIcon[i]->geometry().contains(this->pos() + event->pos()) && this != Widget::mVecIcon[i])
        {
            //交换图片
            QIcon icon = this->icon();
            this->setIcon(Widget::mVecIcon[i]->icon());//当前图片改为 交换的图片
            Widget::mVecIcon[i]->setIcon(icon);
        }


    }
    this->move(mPos);//鼠标松开 位置还原

}



  • widget.h
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QVector> //顺序表容器
#include <QToolButton>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

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

    static QVector<QToolButton*> mVecIcon;//用于存储 5个图片按钮

private:
    Ui::Widget *ui;
};

#endif // WIDGET_H

  • widget.cpp
#include "Widget.h"
#include "ui_widget.h"

QVector<QToolButton*> Widget::mVecIcon;//静态变量初始化

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


    mVecIcon.push_back(ui->toolButton);
    mVecIcon.push_back(ui->toolButton_2);
    mVecIcon.push_back(ui->toolButton_3);
    mVecIcon.push_back(ui->toolButton_4);
    mVecIcon.push_back(ui->toolButton_5);
}

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

9.study_11

9.1基本图形绘制

  • 要先设置画布
 mPainter->begin(this);//设置画图设备 (画布)
    //------------------------------------------画家准备工作

    QPen pen(mPenColor);//创建画笔
    pen.setWidth(5);
    mPainter->setPen(pen); //设置画笔

//    //---画线条
    mPainter->drawLine(0,0,100,100);
    mPainter->drawLine(QPoint(10,10),QPoint(10,100));
//--------------------------------要加个end,不然程序会异常结束
    mPainter->end();//结束

  • Fireworks截取图片的部分区域的数值
    在这里插入图片描述

  • 由于没创建资源文件夹,程序能正确运行的位置
    在这里插入图片描述

  • 程序效果图
    在这里插入图片描述

  • widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QTimer>
#include <QPainter>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

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

protected:
    virtual void timerEvent(QTimerEvent* event);//定时器更新函数
    int mTimerID1;
    int mTimerID2;

    //定时器对象
    QTimer* mTimer;

    //画家对象
    QPainter* mPainter;
    QColor mPenColor;

    virtual void
    paintEvent(QPaintEvent *event);//画图事件更新函数



private:
    Ui::Widget *ui;
};

#endif // WIDGET_H

  • widget.cpp
#include "Widget.h"
#include "ui_widget.h"
#include <QTimer> //定时器头文件
#include <QColorDialog>
#include <QtDebug>

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    mPainter = new QPainter(this);//定义画家对象
    mPenColor = QColorDialog::getColor();





    //-------老式定时器写法(了解)
    mTimerID1 = this->startTimer(1000);//开启一个定时器  更新怪物移动
    mTimerID2 = this->startTimer(200);//开启一个定时器  更新子弹移动


    //--------定时器写法二
    mTimer = new QTimer(this);//定时器对象
    mTimer->start(1000);//定时器对象  开始定时器
    connect(mTimer,&QTimer::timeout,[this](){
        static int num = 0;
        ui->lcdNumber->display(++num);

        //停止定时器
        if(ui->lcdNumber->intValue() == 10)
        {
            mTimer->stop();//停止定时器
        }
    });


}

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


void Widget::timerEvent(QTimerEvent* event)
{
    if(mTimerID1 == event->timerId())//定时器1 判断
    {
//        static int num = 0;
//        ui->lcdNumber->display(++num);

    }
    if(mTimerID2 == event->timerId())
    {
//        static int num = 0;
//        ui->lcdNumber->display(++num);

//          int value = ui->lcdNumber_2->value();
//          ui->lcdNumber_2->display(value+1);
    }
}

void Widget::paintEvent(QPaintEvent *event)
{
    mPainter->begin(this);//设置画图设备 (画布)
    //------------------------------------------画家准备工作

    QPen pen(mPenColor);//创建画笔
    pen.setWidth(5);
    mPainter->setPen(pen); //设置画笔

//    //---画线条
//    mPainter->drawLine(0,0,100,100);
//    mPainter->drawLine(QPoint(10,10),QPoint(10,100));

//    //画矩形
//    mPainter->drawRect(100,100,100,200);
//    mPainter->drawRect(QRect(QPoint(30,30),QPoint(130,130)));

//    //画圆
//    mPainter->drawEllipse(QRect(QPoint(30,30),QPoint(130,130)));

    //多边形
    QPoint pointArr[5] = {QPoint(100,100),QPoint(100,200),QPoint(200,100),QPoint(200,0),QPoint(0,0)};
//    mPainter->drawPolygon(pointArr,5);

    //图片
    QImage img("./resource/Rammus.png");
    mPainter->translate(QPoint(100,100));//画家平移
//    mPainter->rotate(90);
    mPainter->drawImage(QRect(0,0,120,120),img);

    QImage img2("./resource/img_plane_boss.png");
    mPainter->translate(QPoint(200,200));//画家平移
    mPainter->drawImage(QRect(0,0,400,298),img2,QRect(508,0,400,298));

    //画文字
    mPainter->drawText(QPoint(0,0),"飞机大战");

    //画路线
    QPainterPath path;
    path.moveTo(pointArr[0]);
    for(int i = 0;i < 5;i++)
    {
        path.lineTo(pointArr[i]);
    }
    mPainter->drawPath(path);


    //-----------------------------------------
    mPainter->end();//结束


}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值