QT笔记

//.pro文件内容解析

QT       += core gui //Qt所包含的模块
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets //大于4版本 包含widget模块

TARGET = qt_01 //目标 生成的.exe可执行文件的名称
TEMPLATE = app //模板  应用程序

DEFINES += QT_DEPRECATED_WARNINGS

SOURCES += main.cpp\  //源文件
        mywidget.cpp

HEADERS  += mywidget.h  //头文件

Qt命名规范和快捷键

//命名规范 以及 快捷键
//类名 首字母大写 单词与单词之间首字母大写
//函数、变量 首字母小写 单词与单词之间 首字母大写

//快捷键
//运行 ctrl + R
//编译 ctrl + B
//查找 ctrl + F
//帮助文档 F1 第二种 左侧按钮 第三种 目录下bin下assistant.exe
//字体缩放 ctrl + 鼠标滚轮
//自动对齐 ctrl + i
//整行移动 ctrl + shift + ↑ 或者 ↓
//同名之间的.h和.cpp切换 F4
//注释 ctrl + /

不使用界面的按钮操作

main.cpp

#include "mywidget.h"
#include <QApplication> //包含头文件 应用程序

//程序入口 argc命令行变量数量 argv命令行变量数组
int main(int argc, char *argv[])
{
    //应用程序对象 a, Qt中 有且仅有一个 应用程序对象
    QApplication a(argc, argv);
    // 创建 MyWidget对象w  MyWidget基类 QWidget
    MyWidget w;
    //窗口默认是不会弹出的 如果想弹出 调用show方法
    w.show();
    //a.exec()进入消息循环机制 pause
    return a.exec();
}

mywidget.cpp

#include "mywidget.h"
#include <QPushButton>
//命名规范 以及 快捷键
//类名 首字母大写 单词与单词之间首字母大写
//函数、变量 首字母小写 单词与单词之间 首字母大写

//快捷键
//运行 ctrl + R
//编译 ctrl + B
//查找 ctrl + F
//帮助文档 F1  第二种 左侧按钮  第三种 目录下bin下assistant.exe
//字体缩放 ctrl + 鼠标滚轮
//自动对齐 ctrl + i
//整行移动 ctrl + shift + ↑ 或者 ↓
//同名之间的.h和.cpp切换 F4


MyWidget::MyWidget(QWidget *parent)
    : QWidget(parent)  //初始化列表
{
    //按钮
    QPushButton *btn = new QPushButton;
    btn->show(); //show用顶层方式弹出 如果想在MyWidget窗口中显示,就需要依赖MyWidget窗口
    //设置父亲
    btn->setParent(this);
    //设置文字
    btn->setText("德玛西亚"); //将char* 隐式转化为QString


    //创建按钮的第二种方式 窗口会 按照btn2大小进行显示
    QPushButton * btn2 = new QPushButton("第二按钮",this);
    //重置窗口大小
    this->resize(600,400);

    //移动第二个按钮
    btn2->move(100,100);

    //按钮重置大小
    btn2->resize(50,50);

    //重置窗口标题
    setWindowTitle("Qt的第一个窗口");
    
    //设置固定窗口大小
    setFixedSize(600,400);

}

MyWidget::~MyWidget()
{

}

对象树

所有new出来的对象,不用管释放
原因是children表中的对象会在窗口关闭之后进行自动释放
在这里插入图片描述构造由上至下,析构反过来。

//一定程度下 简化了内存回收机制
//创建自己的按钮
MyButton * myBtn = new MyButton;
myBtn->setText("我的按钮");
myBtn->move(200,200);
myBtn->setParent(this);

//Qt坐标系
//x为右侧正向 y以下侧为正向
connect:connect(信号发送者,发送的信号(信号函数的地址),信号接收者,处理槽函数(函数的地址))
松散 耦合 把不相关的两个东西通过connect关键字连接(信号与槽)

Qt中的自定义信号与槽

自定义信号
1.返回值为void
2.需要声明 不需要实现
3.可以有参数
自定义槽函数
1.返回值void
2.需要声明 需要实现
3.可以有参数
触发自定义的信号
emit指令 //emit zt->Hungry();
当自定义信号和槽 出现重载时 原先写法失效,因为执行的函数地址不明确
解决方法 利用函数指针 来明确指向哪个函数的地址

    //连接 老师和学生(无参数的)
    //connect(zt,&Teacher::Hungry,st,&Student::treat);


    //有参数的 信号与槽连接
    //函数指针 指向函数地址
    void(Teacher:: *teacherSignal)(QString ) = &Teacher::Hungry;
    void(Student:: *stSlot)(QString) = &Student::treat;

    connect(zt,teacherSignal,st,stSlot);


    //下课
    ClassIsOver();

/**************发送信号****************/
    //触发老师饿了的信号
    //老师饿了的信号属于自定义信号,触发自定义信号关键字 emit
    emit zt->Hungry();
    emit zt->Hungry("rice");

QString转char toUtf8 转 QByteArray类型 再利用data 转成char **

信号和槽的拓展

    //QString 转 char* 先转QByteArray类型 再转char *
    qDebug()<<"请老师吃"<<foodName.toUtf8().data();
    //点击按钮 才下课
    QPushButton * btn = new QPushButton("下课",this);
    //触发无参 信号与槽

    void(Teacher::*noTeacherSignal)(void) = &Teacher::Hungry;
    void(Student::*noStSlot)(void) = &Student::treat;
    //信号连接信号
    connect(btn,&QPushButton::clicked,zt,noTeacherSignal);
    //信号连接槽
    connect(zt,noTeacherSignal,st,noStSlot);

    //断开信号与槽
    disconnect(zt,noTeacherSignal,st,noStSlot);

    //信号和槽的拓展
    //1. 信号可以连接信号
    //2. 信号和槽可以断开 disconnect
    //3. 一个信号可以触发多个槽函数
    //connect(btn,&QPushButton::clicked,this,&Widget::close);
    //4. 多个信号可以连接同一个槽函数
    //5. 信号和槽的参数必须一一对应 (有参,无参),参数个数不一定一一对应
        //信号的参数个数 可以多于 槽函数的参数个数 ,反之不可以 但是必须类型一一对应
        //信号里面可以有多个参数 槽函数必须不多于信号的函数 不然无法处理。

Qt4 版本信号与槽的写法(不推荐)

connect(zt,SIGNAL(Hungry(QString)),st,SLOT(treat(QString)));

不推荐的原因是 即使参数不匹配还是可以运行。
不检测的原因:SIGNAL和SLOT下 会把里面代码作为字符串处理
相当于

SIGNAL("Hungry(QString)") SLOT("treat(QString)")

优点:参数类型比较直观 发送重载也不需要写函数指针

Lambda表达式(C++11)

[]内部 = 值传递 推荐 & 引用传递 不推荐
()参数
{}函数实现体
mutable 改变值传递的内部变量
返回值 ->type{ };

capturemutable->return-type
{
statement;
}

Qt里需要在.pro文件中加上(低版本)
CONFIG += c++11

插入一首歌 Life In A Northern Town - The Dream Academy

    //mutable关键字 用于修改值得传递的 变量 进行修改
    QPushButton *MyBtn = new QPushButton (this);
    QPushButton *MyBtn2 = new QPushButton (this);
    MyBtn2->move(100,100);
    int m = 10;
    
    connect(MyBtn,&QPushButton::clicked,this,[m]()mutable{m = 100 + 10;qDebug<<m;}});
    connect(MyBtn2,&QPushButton::clicked,this,[=](){qDebug<<m;}});

    //返回值
    int ret = []()->int{return 10000;}();
    //用到最频繁的 [=](){}
    QPushButton * btn3 = new QPushButton("btn3",this);
    btn3->move(200,0);
    //做信号槽连接 默认内部变量会进行锁状态 只读状态 如果要进行操作 就会挂掉
    connect(btn3,&QPushButton::clicked,this,[=](){
        btn3->setText("DDDDD");
    })
    
    //无参按钮调用 有参  请客吃饭
    connect(btn3,&QPushButton::clicked,this,[=](){
        zt->Hungry("宫保鸡丁");
    })
    //点击按钮 关闭窗口
    connect(btn3,&QPushButton::clicked,this,[=](){
        this->close();
    })
 /*
    菜单栏
            1.只能有一个
            2.menuBar()返回一个QMenuBar *bar;
            3.将bar放入到窗口中setMenuBar(bar)
            4.添加菜单addMenu("文件")
            5.添加菜单项addAction("新建")
            6.分割线 addSeparator()


    工具栏
            1. 可以多个
            2. QToolBar
            3. addToolBar(停靠位置,toolbar)
            4. 设置 停靠 浮动 移动
            5.工具栏中可以添加 菜单项

    状态栏
            1. 只能有一个
            2. statusBar() 返回 QStatus *sBar
            3. addStatusBar(sBar)
            4. 添加内容 addWidget(QLabel)
            5. 添加右侧信息

     铆接部件
            1. 可有多个
            2. QDockWidget
            3. addDockWidget(停靠位置,...)
            4. 后期设置停靠
     核心部件
            1.只能有一个
            2.setCentralWidget()

    记是只能一个还是可以有多个小技巧 如果方法名是setXXX就只能一个 如果是addXXX就可以有多个


    */
 resize(600,400);
    //包含菜单栏 只能有一个
    QMenuBar *bar =  menuBar();
    //将菜单栏放入到窗口中
    this->setMenuBar(bar);

    //创建文件菜单
    QMenu *fileMenu = bar->addMenu("文件");
    QMenu *editMenu = bar->addMenu("编辑");

    //添加菜单项
    QAction *newAction = fileMenu->addAction("新建");
    //添加分割线
    fileMenu->addSeparator();
    QAction *openAction = fileMenu->addAction("打开");

    //工具栏 可以有多个
    QToolBar *toolBar = new QToolBar(this);
    //默认停靠范围
    addToolBar(Qt::LeftToolBarArea,toolBar);
    //只运行左右侧停靠
    toolBar->setAllowedAreas(Qt::LeftToolBarArea | Qt::RightToolBarArea);
    //设置浮动
    toolBar->setFloatable(false);
    //设置移动(总开关)
    toolBar->setMovable(false);

    //工具栏添加菜单项
    toolBar->addAction(newAction);
    //添加 分割线
    toolBar->addSeparator();
    toolBar->addAction(openAction);
    //状态栏 只能有一个
    QStatusBar *stBar = statusBar();
    setStatusBar(stBar);
    QLabel *label = new QLabel("提示信息",this);
    stBar->addWidget(label); //添加提示信息到左侧

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

    //铆接部件  浮动窗口
    QDockWidget *dock = new QDockWidget;
    //添加铆接部件到 窗口中
    addDockWidget(Qt::BottomDockWidgetArea,dock);
    //设置停靠范围
    dock->setAllowedAreas(Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea);


    //核心部件 只能一个
    QTextEdit *edit = new QTextEdit;
    setCentralWidget(edit);

添加资源文件
资源文件
1. 将使用的图片资源 放入到项目中
2. 右键项目-添加新文件 Qt-QtResourceFile
3. 起名称 res 生成 res.qrc
4. 右键res.qrc open in editor
5. 添加前缀 添加文件
6. 使用: + 前缀名 + 文件名

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

    //通过ui寻找控件
    //ui->actionnew->setIcon(QIcon("E:/Photo/xx.png"));

    //使用资源文件 ": + 前缀名 + 文件名 "
    ui->actionnew->setIcon(QIcon(":/jacintosh.png"));
}

对话框

模态对话框
exec 阻塞
非模态对话框
1.show 在栈上 会一闪而过
2.所以使用new 在堆区创建
3.设置属性 dlg2->setAttribute(Qt::Qt::WA_DeleteOnClose); 55号

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

    //点击新建菜单项 弹出对话框
    connect(ui->actionnew,&QAction::triggered,this,[=](){
        //对话框有两种 1.模态对话框(不可以对其他窗口进行操作)  2.非模态对话框(还能点别的地方)
//        QDialog dlg;
//        dlg.exec(); //阻塞

        //2. 非模态对话框
        //QDialog dlg2(this); 创建到了栈上 一闪而过

        QDialog *dlg2 = new QDialog(this);
        dlg2->resize(200,100);
        dlg2->show();
        
        //需要设置属性 dlg2 关闭时释放内存
        dlg2->setAttribute(Qt::WA_DeleteOnClose); //55号
    });
}

系统标准对话框 QMessageBox

1.静态成员函数
2.QMessageBox:: 警告 信息 错误 问题
3.五个参数 父亲 标题 提示内容 按键类型 关联回车按键

        //使用标准对话框 头文件 QMessageBox
        //错误对话框
        //QMessageBox::critical(this,"错误","critical");
        //信息对话框
       // QMessageBox::information(this,"信息","info");
        //询问对话框
        //参数 1. 父亲 2. 标题 3.提示内容 4.按键类型 5.关联回车按键
//        if(QMessageBox::Save == QMessageBox::question(this,"问题","question",QMessageBox::Save | QMessageBox::Cancel,QMessageBox::Cancel))
//        {
//            qDebug()<<"点击的是保存";
//        }
//        else
//        {
//            qDebug()<<"点击的是取消";
//        }
        
        //警告对话框
        QMessageBox::warning(this,"警告","warning");

标准颜色对话框
1.QColorDialog
2.getColor 返回 QColor

标准文件对话框
1.QFileDialog
2.getOpenFileName(父亲,标题,默认路径,过滤文件格式)
3.返回值是选取文件的路径

登录窗口布局
1.利用Widget做容器,容器内部 进行水平、垂直布局
2.灵活运用弹簧
3.设置属性 间隙 默认为 9 9 9 9
4.垂直策略

控件
按钮组
1.PushButton 按钮
2.ToolButton 工具按钮 多用于显示图片 ToolButtonStyle 修改风格 autoRaise 透明风格
3.RadioButton 单选 setChecked(true)
4.CheckButton 多选 statechange 独特的信号 0 未选中 1半选中 2 选中
在这里插入图片描述

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

    //单选按钮 默认选中 男
    ui->radioButtonMan->setChecked(true);

    //点击女的 就打印选中了
    connect(ui->radioButton_2Woman,&QRadioButton::clicked,[=](){
        qDebug()<<"选中女的了";
    });

    //多选框 选中后打印内容
    //选中是2 未选中是 0 半选中为1
    connect(ui->checkBox,&QCheckBox::stateChanged,[=](int state){
        qDebug()<<state;
    });
}

ListWidget控件
1.QListWidgetItem 每一个项目
2. item 可以设置对齐方式 setTextAlignment(xxx);
3. 一次性的将所有内容添加 addItems(QStringList)

//    //利用listWidget 写诗
//    QListWidgetItem *item = new QListWidgetItem("锄禾日当午");
//    //设置对齐方式
//    item->setTextAlignment(Qt::AlignCenter);
//    QListWidgetItem *item2 = new QListWidgetItem("汗滴禾下土");
//    item2->setTextAlignment(Qt::AlignCenter);
//    ui->listWidget->addItem(item);
//    ui->listWidget->addItem(item2);

    //QStringList QList<String>   缺点 无法设置对齐方式
    QStringList list;
    list<<"锄禾日当午"<<"汗滴禾下土"<<"谁知盘中餐"<<"粒粒皆辛苦";
    ui->listWidget->addItems(list);
    //通过匿名对象 可也以直接写入
    //ui->listWidget->addItems(QStringList() <<"锄禾日当午"<<"汗滴禾下土"<<"谁知盘中餐"<<"粒粒皆辛苦" );

QTreeWidget
1.设置头 setHeaderLabels(QStringList()<<“英雄…”);
2.每个项目 QTreeWidgetItem
3.添加顶层项目 addTopLeaveItem
4.添加子项目 addChild()

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

    //treeWidget控件使用
    //添加头

    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);

    //追加子项目 子项也是 QTreeWidgetItem
    QStringList heroL1;
    QStringList heroL2;
    QStringList heroM1;
    QStringList heroM2;
    QStringList heroZ1;
    QStringList heroZ2;

    heroL1<<"刚被猪"<<"前排坦克";
    heroL2<<"船长"<<"能肉能输出";

    heroM1<<"乐器室"<<"中排输出";
    heroM2<<"小鱼人"<<"前排战士";

    heroZ1<<"死灵法师"<<"前排法师坦克";
    heroZ2<<"巫医"<<"后排辅助法师";

    QTreeWidgetItem *li1 = new QTreeWidgetItem(heroL1);
    liItem->addChild(li1);
    QTreeWidgetItem *li2 = new QTreeWidgetItem(heroL2);
    liItem->addChild(li2);
    QTreeWidgetItem *min1 = new QTreeWidgetItem(heroM1);
    minItem->addChild(min1);
    QTreeWidgetItem *min2 = new QTreeWidgetItem(heroM2);
    minItem->addChild(min2);
    QTreeWidgetItem *zhi1 = new QTreeWidgetItem(heroZ1);
    zhiItem->addChild(zhi1);
    QTreeWidgetItem *zhi2 = new QTreeWidgetItem(heroZ2);
    zhiItem->addChild(zhi2);
}

在这里插入图片描述

QTableWidget控件
1.设置列数 setColumnCount
2.设置水平头 setHorizontalHeaderLabel
3.设置行数 setRowCount
4.添加正文 setItem (行数,列数,具体内容)
5.添加赵云
6.删除赵云

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

    //QTableWidget 空间使用
    //先告诉空间 一共有多少列
    QStringList list;
    list <<"姓名"<<"性别"<<"年龄";
    ui->tableWidget->setColumnCount(list.size());
    //设置水平头
    ui->tableWidget->setHorizontalHeaderLabels(list);

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

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

    QStringList nameList;
    nameList << "亚瑟"<<"妲己"<<"安其拉"<<"东皇太一"<<"李白";
    QList<QString> 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)));
        // int 转 QString
        ui->tableWidget->setItem(i,col++,new QTableWidgetItem(QString::number(i+18)));

    }

    //点击按钮 添加赵云
    connect(ui->pushButton,&QPushButton::clicked,[=](){
        //先判断有没有赵云,有不添加 ,没有才添加
        bool isEmpty = ui->tableWidget->findItems("赵云",Qt::MatchExactly).empty();
        if(isEmpty)
        {
            ui->tableWidget->insertRow(0);
            ui->tableWidget->setItem(0,0,new QTableWidgetItem("赵云"));
            //添加性别
            ui->tableWidget->setItem(0,1,new QTableWidgetItem("男"));
            // int 转 QString
            ui->tableWidget->setItem(0,2,new QTableWidgetItem(QString::number(16)));
        }
        else
        {
            QMessageBox::warning(this,"警告!","赵云有了!");
        }
    });

    //点击按钮 删除 赵云
    connect(ui->pushButton_2,&QPushButton::clicked,[=](){
        bool isEmpty = ui->tableWidget->findItems("赵云",Qt::MatchExactly).empty();
        //找到行数 删除掉

        if(isEmpty)
        {
            QMessageBox::warning(this,"警告!","赵云没了");
        }
        else
        {
            //先找到赵云所在的行
            int row = ui->tableWidget->findItems("赵云",Qt::MatchExactly).first()->row();
            ui->tableWidget->removeRow(row);
        }
    });
}

在这里插入图片描述其他控件
stackWidget栈控件
1.设置当前索引 setCurrentIndex(0)
下拉框
1.addItem
2.setCurrentText()
利用QLabel显示gif图片和普通图片

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

    //stackWidget
    //设置默认 选中第0项
    ui->stackedWidget->setCurrentIndex(0);
    connect(ui->Scroll,&QPushButton::clicked,[=](){
        ui->stackedWidget->setCurrentIndex(0);
    });

    connect(ui->Tab,&QPushButton::clicked,[=](){
        ui->stackedWidget->setCurrentIndex(1);
    });

    connect(ui->Tool,&QPushButton::clicked,[=](){
        ui->stackedWidget->setCurrentIndex(2);
    });

    //下拉框的使用
    ui->comboBox->addItem("奔驰");
    ui->comboBox->addItem("宝马");
    ui->comboBox->addItem("拖拉机");

    //点击拖拉机按钮
    connect(ui->tuolajiBtn,&QPushButton::clicked,[=](){
        ui->comboBox->setCurrentText("拖拉机");
    });

    //利用QLabel显示图片
    ui->label->setPixmap(QPixmap(":/new/prefix1/jacintosh.png"));
    //利用Qlabel显示gif图片
    QMovie *movie = new QMovie(":/new/prefix1/fake.gif");
    ui->label->setMovie(movie);
    //播放gif
    movie->start();
}

自定义控件封装

1.创建QT-设计师界面类
2.拖拽Widget 右键 提升为 —类名写入 – 全局包含 – 添加 – 提升
3.QSpinBox移动 Slider跟着移动
4.对外接口

在这里插入图片描述在这里插入图片描述

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

    //QSpinBox移动 slider跟着移动
    void(QSpinBox:: *signal)(int) = &QSpinBox::valueChanged;
    connect(ui->spinBox,signal,ui->horizontalSlider,&QSlider::setValue);

    //Slider移动 SpinBox跟着移动
    connect(ui->horizontalSlider,&QSlider::valueChanged,ui->spinBox,&QSpinBox::setValue);
}
Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    //点击设置 到一半的位置
    connect(ui->serHalfValueBtn,&QPushButton::clicked,[=](){
        ui->widget->setValue(50);
    });
    //点击获取 拿到当前值
    connect(ui->getValueBtn,&QPushButton::clicked,[=](){
        qDebug()<<"当前值为"<<ui->widget->getValue();
    });

}

鼠标事件

鼠标进入 enterEvent
鼠标离开 leaveEvent
鼠标按下 释放 移动
1.通过ev获取到 x y的坐标
2.ev判断 鼠标左右键
3.QString 格式化字符串 %1 %2 .arg().arg()

MyLabel::MyLabel(QWidget *parent) : QLabel(parent)
{
    //设置鼠标追踪 鼠标放到指定区域就有追踪 不需要点击
    this->setMouseTracking(true);
}
//鼠标按下
void MyLabel::mousePressEvent(QMouseEvent *ev)
{
    //如果鼠标按下的是左键,然后提示内容
    if(ev->button() == Qt::LeftButton)
    {
        //找按下的 位置
        QString str = QString("鼠标按下了  x = %1 y = %2").arg(ev->x()).arg(ev->y());
        qDebug()<<str;
    }

    //持续状态 需要用buttons 用与操作符 进行判断
    if(ev->buttons() & Qt::LeftButton )
    {
        //找按下的 位置
        QString str = QString("鼠标按下了  x = %1 y = %2").arg(ev->x()).arg(ev->y());
        qDebug()<<str;
    }

}

定时器使用

1.timeEvent 事件
2.启动定时器 startTime(毫秒) 返回值就是id号
3.区分定时器 timerId

#include "widget.h"
#include "ui_widget.h"
#include <QTimerEvent>

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

    //启动定时器
    id1 = startTimer(1000); // 每隔1000毫秒调用一次timeEvent时间
    id2 = startTimer(2000);
}

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

void Widget::timerEvent(QTimerEvent *event)
{
    if(event->timerId() == id1)
    {
        static int num = 0;
        ui->label_2->setText(QString::number(num++));
    }
    
    if(event->timerId() == id2)
    {
        static int num2 = 0;
        ui->label_3->setText(QString::number(num2++));
    }

}

在这里插入图片描述
可见下面框框的数值大概是上面框的一半。

定时器的第二种方式(推荐)
因为是直接创建定时器对象 不需要使用timeId就可以进行控制
1.QTimer 头文件
2.创建QTimer *timer
3.启动定时器 timer->start(毫秒)
4.发送信号 timeout
5.暂停 stop()

    //定时器第二种方式
    QTimer *timer1 = new QTimer(this);
    //启动定时器对象
    timer1->start(500); //毫秒作单位
    //每隔0.5秒发送信号
    connect(timer1,&QTimer::timeout,[=](){
        ui->label_4->setText(QString::number(num2++));
    });

    //点击按钮 暂停定时器
    connect(ui->pushButton,&QPushButton::clicked,[=](){
        timer1->stop();
    });

event事件(可用于拦截)
bool event(QEvent *)
返回值用途 返回值为true 用户自己处理事件 不向下分发
false 系统处理事件

1.主要功能 事件的分发
2.bool event (QEvent *e)
3.返回值如果是true 代表用户自己处理
4.false系统处理 最好抛给父类去处理
5.static_cast<转换类型>(原对象)
6.e->type 具体事件 if(e->type()==QEvent::MouseButtonPress){xxx};

bool MyLabel::event(QEvent *e)
{
    //通常不会做拦截 ,event只要分发事件就可以了
    if(e->type()==QEvent::MouseButtonPress)
    {
        QMouseEvent *ev = static_cast<QMouseEvent *>(e);
        QString str = QString("鼠标释放了 x=%1 y=%2").arg(ev->x()).arg(ev->y());
        qDebug()<<str;
        //只有鼠标按下 自己处理 返回true
        return true;
    }
    //其他事件 让父亲做默认处理
    return QLabel::event(e);
}

事件过滤器
1.哪个控件需求安装过滤事件 就给哪个控件安装过滤器
2.做拦截
步骤一:给需要拦截的控件安装过滤器
ui->label->installEventFilter(this);
步骤二:重写事件eventFilter

bool Widget::eventFilter(QObject *watched, QEvent *event)
{
    if(watched == ui->label)
    {
        if(event->type() == QEvent::MouseButtonPress)
        {
            QMouseEvent *ev = static_cast<QMouseEvent *>(event);
            QString str = QString("事件过滤器...鼠标按下 x = %1 y = %2").arg(ev->x()).arg(ev->y());
            qDebug()<<str;
            return true;
        }
    }
    return QWidget::eventFilter(watched,event);
}

在这里插入图片描述QPainter
1.绘图 事件 paintEvent
2.QPainter painter(绘图设备 this)
3.draw 线 圆 矩形 文字
4.QPen 设置笔宽度 样式 让画家用笔
5.QBrush 设置画刷 样式 让画家用画刷

void Widget::paintEvent(QPaintEvent *)
{
    //创建画家
    QPainter painter(this);
    //设置画笔颜色
    QPen pen(QColor(255,0,0));
    //设置笔宽度
    pen.setWidth(3);
    //设置笔的风格
    pen.setStyle(Qt::DotLine);
    //画家用这支笔
    painter.setPen(pen);

    //画刷填充颜色
    QBrush brush(Qt::cyan);
    // 让画家使用画刷
    brush.setStyle(Qt::Dense3Pattern);
    painter.setBrush(brush);

    //利用画家画画
    //画线
    painter.drawLine (QPoint(0,0),QPoint(100,100));
    //画圆 (椭圆)
    painter.drawEllipse(QPoint(100,100),50,50);
    //画矩形
    painter.drawRect(QRect(10,10,50,50));
    //画字体
    painter.drawText(QRect(10,200,150,50),"好好学习 天天向上");
}

抗锯齿

      //高级设置
      painter.drawEllipse(QPoint(100,100),50,50);
      //设置抗锯齿 效率低
      painter.setRenderHint(QPainter::HighQualityAntialiasing);
      painter.drawEllipse(QPoint(200,100),50,50);

画家移动
画家状态

        painter.drawRect(QRect(20,20,50,50));
        //移动画家
        painter.translate(QPoint(100,100));
        //保存状态
        painter.save();
        //取出状态
        painter.restore();
        painter.drawRect(QRect(20,20,50,50));

手动调用绘图事件
1.update
2.画家可以画图片
3.drawPixmap(x,y,QPixmap(“图片路径”))

 painter.drawPixmap(posX,100,QPixmap(":/new/prefix1/jacintosh.png"));

绘图设备

QPixmap、QBitMap(黑白色)、QImage、QPicture、QWidget、
1.QPixmap
1.创建对象 QPixmap pix(w,h)
2.fill 填充色
3.保存save

   //QPixmap 做绘图设备 对不同平台显示做优化
   QPixmap pix(300,300);
   QPainter painter(&pix);

   painter.setPen(QPen(Qt::green));
   painter.drawEllipse(QPoint(150,150),100,100);

    //保存
   pix.save("D:\\pix.png");

2.QImage img(w,h,format) 设置像素 setPixel

    //QImage 做绘图设备 对像素级访问进行了优化
    QImage img(300,300,QImage::Format_RGB32);
    img.fill(Qt::white);
    QPainter painter(&img);
    painter.setPen(QPen(Qt::blue));
    painter.drawEllipse(QPoint(150,150),100,100);
    img.save("D:\\img.png");

3.QPicture 重现记录 绘图指令 后缀名随意

    //QPicture 绘图设备
    QPicture pic; //用于重现 记录绘图指令
    QPainter painter;
    painter.begin(&pic);
    painter.setPen(QPen(Qt::blue));
    painter.drawEllipse(QPoint(150,150),100,100);

    painter.end();
    //保存
    pic.save("D:\\pic.hxp");

调用这张图片

    //重现绘图指令 QPicture
    QPicture pic;
    pic.load("D:\\pic.hxp");
    QPainter painter(this);
    painter.drawPicture(0,0,pic);

文件操作(QFile)

1.QFile file(路径)
2.file.open 打开方式 QIDevice::ReadOnly
3.file.readAll readLine(file.atEnd 判断是否到文件尾)
4.写QIODevice::WirteOnly
5.file.write(“xxxx”);

    connect(ui->pushButton,&QPushButton::clicked,[=](){
        QString path = QFileDialog::getOpenFileName(this,"打开文件","D:\\学习笔记\\AI\\python机器学习");
        if(path.isEmpty())
        {
            QMessageBox::warning(this,"警告","打开失败");
        }
        else
        {
            //将路径放入到lineEdit中
            ui->lineEdit->setText(path);
            //读取文件
            //QFile默认支持UTF-8格式

            QTextCodec *codec = QTextCodec::codecForName("gbk");

            QFile file(path); //参数路径名称
            //指定打开方式(只读)
            //file.open(QIODevice::ReadOnly);
            file.open(QFileDevice::ReadOnly);

            QByteArray array;
            array = file.readAll();

            /*
            while(!file.atEnd())
            {
                array += file.readLine(); //读一行话
            }
            */
            //设置到 文本编辑框中
            ui->textEdit->setText(array);
            file.close();
            //读gbk
            //ui->textEdit->setText(codec->toUnicode(array));


            //写文件
            //重新指定打开方式
            file.open(QFileDevice::Append);
            file.write("哦哦哦哦哦哦哦哦哦");
            file.close();
        }
    });
}

文件信息

1.QFileInfo info
2.info 读取到文件 信息
3.路径、名称、后缀名、大小
4.创建日期、修改日期 QDateTime

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

qDebug()<<"创建日期"<<info.created().toString("yyyy-MM-dd hh:mm:ss");
qDebug()<<"修改日期"<<info.lastModified().toString("yyyy-MM-dd hh:mm:ss");

文件流QFileStream

1.文本流
1.QFile file(path)
2.QTextStream(&path)
3.stream << 写
4.stream.readAll >>

    //文件流读写文件
    //分类:文本流(基础数据类型)和数据流(大型QImage)

    //文本流
    QFile file("aaa.txt");
    file.open(QFileDevice::WriteOnly);
    QTextStream stream(&file);
    stream<<QString("helloWorld")<<123456;
    file.close();

    //读取
    file.open(QFileDevice::ReadOnly);
    QString str;
    //stream>>str; //读到空格就结束 改为如下
    str = stream.readAll();
    qDebug()<<str;

2.数据流

1.QDateStream stream(&file)
2.stream << 写数据
3. stream >> 读数据

注意://数据流读取时不同的类型会存在不同的块中

    //数据流  二进制
    QFile file("bbb.txt");
    file.open(QFileDevice::WriteOnly);
    QDataStream stream(&file);
    stream << QString ("hello world")<<123456; //数据流读取时不同的类型会存在不同的块中
    file.close();

    //读数据
    file.open(QFileDevice::ReadOnly);
    QString str;
    int num;
    stream >> str>>num;
    qDebug()<<str<<num;
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值