基本介绍
main.ccp简介
01_FirstProject文件
// Qt包含的模块core和guiQT += core gui// 版本大于4时包含widgetgreaterThan(QT_MAJOR_VERSION, 4): QT += widgets// 目标 生成的.exe程序名称TARGET = 01_FirstProject// 模板 应用程序模板 ApplicationTEMPLATE = app//DEFINES += QT_DEPRECATED_WARNINGS// 源文件 一般自动生成的SOURCES += \main.cpp \mywidget.cpp// 头文件HEADERS += \mywidget.h
使用和快捷键

mywidget.cpp中按钮和窗口的设置
#include "mywidget.h"#include <QPushButton> // 按钮文件的头文件myWidget::myWidget(QWidget *parent): QWidget(parent){// 创建一个按钮QPushButton * btn = new QPushButton;// 显示窗口 默认在顶层窗口弹出// btn->show();// 让btn对象依赖在myWidget窗口中btn->setParent(this);// 显示文本btn->setText("第一个按钮");// 创建第二个按钮 按照你的控件大小创建窗口QPushButton * btn2 = new QPushButton("第二个按钮", this);// 移动btn按钮btn2->move(20, 20);// 重组btn2按钮大小btn2->resize(50, 20);// 重置窗口大小resize(600, 400);// 设置固定窗口大小setFixedSize(600, 400);// 设置窗口标题setWindowTitle("My deng");}
对象树基本概念

mypushbutton.h文件
#ifndef MYPUSHBUTTON_H#define MYPUSHBUTTON_H// 引入QPushButton#include <QPushButton>class MyPushButton : public QPushButton{Q_OBJECTpublic:explicit MyPushButton(QWidget *parent = nullptr);// MyPushButton();~MyPushButton();signals:public slots:};#endif // MYPUSHBUTTON_H
mypushbutton.ccp文件
#include "mypushbutton.h"#include <QDebug>MyPushButton::MyPushButton(QWidget *parent) : QPushButton(parent){qDebug() << "我的按钮类构造调用";}MyPushButton::~MyPushButton(){qDebug() << "我的按钮类析构";}
mywidget.cpp文件
#include "mywidget.h"#include <QPushButton> // 按钮文件的头文件#include "mypushbutton.h"#include <QDebug>myWidget::myWidget(QWidget *parent): QWidget(parent){// 创建一个按钮QPushButton * btn = new QPushButton;// 显示窗口 默认在顶层窗口弹出// btn->show();// 让btn对象依赖在myWidget窗口中btn->setParent(this);// 显示文本btn->setText("第一个按钮");// 创建第二个按钮 按照你的控件大小创建窗口QPushButton * btn2 = new QPushButton("第二个按钮", this);// 移动btn2按钮btn2->move(20, 20);// 重组btn2按钮大小btn2->resize(100, 20);// 重置窗口大小resize(600, 400);// 设置固定窗口大小setFixedSize(600, 400);// 设置窗口标题setWindowTitle("My deng");// 创建一个自己的按钮对象MyPushButton * myBtn = new MyPushButton;myBtn->setText("我自己的按钮");myBtn->move(300, 300);// 设置到对象树中myBtn->setParent(this);}myWidget::~myWidget(){// 析构qDebug() << "myWidget的析构调用";}
对象树小结
当创建的对象在堆区的时候,如果指定的父亲是QObject派生下来的类或者QObject子类派生下来的类,可以不用管理释放的操作,将对象放入到对象树中。
一定程度上简化了内存回收机制
信号和槽机制
连接的函数:connect(参数1,参数2,参数3,参数4);
参数:
参数1:信号的发送者
参数2:发送的信号
参数3:信号的接收者
参数4:处理
#include "mywidget.h"#include <QPushButton> // 按钮文件的头文件#include "mypushbutton.h"#include <QDebug>// 命名规范// 类名 首字母大写, 单词和单纯之间首字母大写// 函数名 变量名称 首字母小写,单词和单词之间首字母大写myWidget::myWidget(QWidget *parent): QWidget(parent){// 创建一个按钮QPushButton * btn = new QPushButton;// 显示窗口 默认在顶层窗口弹出// btn->show();// 让btn对象依赖在myWidget窗口中btn->setParent(this);// 显示文本btn->setText("第一个按钮");// 创建第二个按钮 按照你的控件大小创建窗口QPushButton * btn2 = new QPushButton("第二个按钮", this);// 移动btn2按钮btn2->move(20, 20);// 重组btn2按钮大小btn2->resize(100, 20);// 重置窗口大小resize(600, 400);// 设置固定窗口大小setFixedSize(600, 400);// 设置窗口标题setWindowTitle("My deng");// 创建一个自己的按钮对象MyPushButton * myBtn = new MyPushButton;myBtn->setText("我自己的按钮");myBtn->move(300, 300);// 设置到对象树中myBtn->setParent(this);// 信号和槽// 需求 点击我的按钮 关闭窗口// 参数1 信号的发送者; 参数2 发送的信号(函数的地址); 参数3 信号的接收者;参数4 处理的槽函数connect(myBtn, &QPushButton::clicked, this, &QWidget::close);//或使用下面这个//connect(myBtn, &MyPushButton::clicked, this, &myWidget::close);}myWidget::~myWidget(){// 析构qDebug() << "myWidget的析构调用";}
自定义的信号和槽
自定义信号
teacher.h文件
#ifndef TEACHER_H#define TEACHER_H#include <QObject>class Teacher : public QObject{Q_OBJECTpublic:explicit Teacher(QObject *parent = nullptr);signals:// 自定义信号写到signals下// 返回值是void,需要声明,不需要实现// 可以有参数,可以重载void hungry();public slots:};#endif // TEACHER_H
自定义槽函数
student.h文件
#ifndef STUDENT_H#define STUDENT_H#include <QObject>class Student : public QObject{Q_OBJECTpublic:explicit Student(QObject *parent = nullptr);signals:public slots:// 早期QT版本槽函数必须要写到public slots,高级版本可用写到public或者全局下// 返回值是void,需要声明,也需要实现// 可以有参数,可以发生重载void treat();};#endif // STUDENT_H
student.ccp文件
#include "student.h"#include <QDebug>Student::Student(QObject *parent) : QObject(parent){}void Student::treat(){qDebug() << "请老师吃饭";}
窗口文件
widget.h文件
#ifndef WIDGET_H#define WIDGET_H#include <QWidget>#include "teacher.h"#include "student.h"namespace Ui {class Widget;}class Widget : public QWidget{Q_OBJECTpublic:explicit Widget(QWidget *parent = 0);~Widget();private:Ui::Widget *ui;// 声明指针Teacher * zt;Student * st;// 方法void classIsOver();};#endif // WIDGET_H
widget.ccp文件
#include "widget.h"#include "ui_widget.h"// Teacher 类 老师类// Student 类 学生类// 下课后,老师会触发一个信号,饿了,学生相应Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget){ui->setupUi(this);// 创建一个老师的对象this->zt = new Teacher(this);// 创建一个学生对象this->st = new Student(this);// 老师饿了 学生请客的连接connect(zt, &Teacher::hungry, st, &Student::treat);// 调用下课函数classIsOver();}// 实现方法void Widget::classIsOver(){// 下课函数, 调用后 触发老师饿了的信号// emit 触发自定义的信号emit zt->hungry();}Widget::~Widget(){delete ui;}

自定义信号和槽发生重载的解决
teacher.h文件
#ifndef TEACHER_H#define TEACHER_H#include <QObject>class Teacher : public QObject{Q_OBJECTpublic:explicit Teacher(QObject *parent = nullptr);signals:// 自定义信号写到signals下// 返回值是void,需要声明,不需要实现// 可以有参数,可以重载void hungry();// 有两个hungry方法void hungry(QString foodName);public slots:};#endif // TEACHER_H
student.h文件
#ifndef STUDENT_H#define STUDENT_H#include <QObject>class Student : public QObject{Q_OBJECTpublic:explicit Student(QObject *parent = nullptr);signals:public slots:// 早期QT版本槽函数必须要写到public slots,高级版本可用写到public或者全局下// 返回值是void,需要声明,也需要实现// 可以有参数,可以发生重载void treat();// 有两个treat方法void treat(QString foodName);};#endif // STUDENT_H
student.cpp文件
#include "student.h"#include <QDebug>Student::Student(QObject *parent) : QObject(parent){}void Student::treat(){qDebug() << "请老师吃饭";}// 加作用域void Student::treat(QString foodName){// QString -> chat * 先转成QByteArray (.toUtf8() ) 在转char *()qDebug() << "请老师吃饭,老师要吃" << foodName.toUtf8().data();}
widget.cpp文件
#include "widget.h"#include "ui_widget.h"// Teacher 类 老师类// Student 类 学生类// 下课后,老师会触发一个信号,饿了,学生相应Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget){ui->setupUi(this);// 创建一个老师的对象this->zt = new Teacher(this);// 创建一个学生对象this->st = new Student(this);// // 老师饿了 学生请客的连接// connect(zt, &Teacher::hungry, st, &Student::treat);// // 调用下课函数// classIsOver();//解决重载问题// 连接带参数的信号和槽// 指针->地址// 函数指针 -> 函数地址// Teacher作用域下的teacherSignal函数指针void(Teacher:: *teacherSignal)(QString) = &Teacher::hungry;void(Student:: *studentSlot)(QString) = &Student::treat;connect(zt, teacherSignal, st, studentSlot);classIsOver();}// 实现方法void Widget::classIsOver(){// 下课函数, 调用后 触发老师饿了的信号// emit 触发自定义的信号//emit zt->hungry();emit zt->hungry("宫保鸡丁");}Widget::~Widget(){delete ui;}
信号和信号的连接&断开&Qt4版本槽连接
#include "widget.h"#include "ui_widget.h"#include <QPushButton>// Teacher 类 老师类// Student 类 学生类// 下课后,老师会触发一个信号,饿了,学生相应Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget){ui->setupUi(this);// 创建一个老师的对象this->zt = new Teacher(this);// 创建一个学生对象this->st = new Student(this);// // 老师饿了 学生请客的连接// connect(zt, &Teacher::hungry, st, &Student::treat);// // 调用下课函数// classIsOver();// 连接带参数的信号和槽// 指针->地址// 函数指针 -> 函数地址// Teacher作用域下的teacherSignal函数指针void(Teacher:: *teacherSignal)(QString) = &Teacher::hungry;void(Student:: *studentSlot)(QString) = &Student::treat;connect(zt, teacherSignal, st, studentSlot);classIsOver();// 点击一个下课的按钮,再触发下课QPushButton * btn = new QPushButton("下课", this);this->resize(600, 400);// 点击按钮,触发下课connect(btn, &QPushButton::clicked, this, &Widget::classIsOver);// 无参信号和槽连接void(Teacher:: *teacherSignal2)(void) = &Teacher::hungry;void(Student:: *studentSlot2)(void) = &Student::treat;connect(zt, teacherSignal2, st, studentSlot2);// 信号和信号连接connect(btn, &QPushButton::clicked, zt, teacherSignal2);// 断开信号disconnect(zt, teacherSignal2, st, studentSlot2);// 拓展// 1.信号是可以连接信号// 2.一个信号可以连接多个槽函数// 3.多个信号可以连接同一个槽函数// 4.信号和槽函数的参数必须类型一一对应// 5.信号的参数个数可以多与槽参数个数//Qt4版本以前的信号和槽的连接方式// 利用Qt4信号槽连接无参版本connect(zt, SIGNAL(hungry()), st, SLOT(treat()));// Qt4版本的优点:参数直观; 缺点:类型不做检测}// 实现方法void Widget::classIsOver(){// 下课函数, 调用后 触发老师饿了的信号// emit 触发自定义的信号//emit zt->hungry();emit zt->hungry("宫保鸡丁");}Widget::~Widget(){delete ui;}
QMainWindow
#include "mainwindow.h"#include <QMenuBar>#include <QToolBar>#include <QDebug>#include <QPushButton>#include <QStatusBar>#include <QLabel>#include <QDockWidget>#include <QTextEdit>MainWindow::MainWindow(QWidget *parent): QMainWindow(parent){// 重置窗口大小resize(600, 400);// 菜单栏最多只能有一个// 菜单栏创建QMenuBar * bar = menuBar();// 将栏放入窗口中setMenuBar(bar);// 创建菜单 (有返回值QMenu)QMenu * fileMenu = bar->addMenu("文件");QMenu * editMenu = bar->addMenu("编辑");// 创建菜单项fileMenu->addAction("新建");// 添加分隔线fileMenu->addSeparator();fileMenu->addAction("打开");// 工具栏,可以有多个QToolBar * toolBar = new QToolBar(this);// 添加到视图上addToolBar(Qt::RightToolBarArea, toolBar);// 只允许左右停靠toolBar->setAllowedAreas(Qt::LeftToolBarArea | Qt::RightToolBarArea);// 设置浮动操作toolBar->setFloatable(false);// 设置移动 (相当于总开关)toolBar->setMovable(false);// 工具栏中可以设置内容 将菜单栏中的新建和打开放到这toolBar->addAction(newAction);// 添加分割线toolBar->addSeparator();toolBar->addAction(openAction);// 工具栏中添加一些控件QPushButton * btn = new QPushButton("AA", this);toolBar->addWidget(btn);// 状态栏 最多也只能有一个QStatusBar * stBar = statusBar();// 设置到窗口中setStatusBar(stBar);// 放标签控件QLabel * label = new QLabel("提示的信息", this);stBar->addWidget(label);QLabel * label2 = new QLabel("右侧提示信息", this);stBar->addPermanentWidget(label2);// 铆接部件 (浮动窗口)QDockWidget * dockWidget = new QDockWidget("浮动", this);// 设置区域addDockWidget(Qt::BottomDockWidgetArea, dockWidget);// 设置中心部件 只能一个dockWidget->setAllowedAreas(Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea);// 设置中心部件编辑 只能有一个值QTextEdit * edit = new QTextEdit(this);setCentralWidget(edit);}MainWindow::~MainWindow(){}
资源文件添加
#include "mainwindow.h"#include "ui_mainwindow.h"//#include <QIcon>MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow){ui->setupUi(this);// 使用添加Qt资源 ": + 前缀名 + 文件名"ui->actionnew->setIcon(QIcon(":/Image/20191016140642.jpg"));ui->actionopen->setIcon(QIcon(":/Image/1-15052216143c40-lp.jpg"));}MainWindow::~MainWindow(){delete ui;}
对话框QDialog
#include "mainwindow.h"#include "ui_mainwindow.h"#include <QDialog>#include <QDebug>MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow){ui->setupUi(this);// 点击新建按钮 弹出一个对话框connect(ui->actionnew, &QAction::triggered, [=](){// 对话框分类// 模态对话框(不可以对其他窗口进行操作); 非模块对话框(可以对其他窗口进行操作)// 模态创建QDialog dlg(this);dlg.resize(200, 100);dlg.exec();qDebug() << "模态对话框弹出了";// 非模态对话框QDialog * dlg2 = new QDialog(this);dlg2->resize(200, 100);dlg2->show();// 关闭窗口后就释放内存,防止内存泄漏dlg2->setAttribute(Qt::WA_DeleteOnClose); // 55号属性qDebug() << "非模态对话框弹出了";});}MainWindow::~MainWindow(){delete ui;}
消息对话框
#include "mainwindow.h"#include "ui_mainwindow.h"#include <QDebug>#include <QMessageBox>MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow){ui->setupUi(this);// 点击新建按钮 弹出一个对话框connect(ui->actionnew, &QAction::triggered, [=](){// 消息对话框 参数:父亲,标题,内容// 错误对话框//QMessageBox::Critical(this, "critical", "错误");// 信息对话框//QMessageBox::information(this, "info", "信息");// 提问对话框 参数1:父亲,参数2:标题,参数3:内容, 参数4:按钮类型(默认值为yes,no),参数5:默认关联回车键的if (QMessageBox::Save == QMessageBox::question(this, "ques", "提问", QMessageBox::Save|QMessageBox::Cancel, QMessageBox::Cancel)){qDebug() << "选择的是保存";}else {qDebug() << "选择的是取消";}// 警告对话框QMessageBox::warning(this, "warning", "警告");});}MainWindow::~MainWindow(){delete ui;}
QMessageBox的简单使用
判断QmessageBox点击的按钮判断QmessageBox点击的按钮
其他标准对话框
#include "mainwindow.h"#include "ui_mainwindow.h"#include <QDebug>#include <QColorDialog>#include <QFileDialog>#include <QFontDialog>MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow){ui->setupUi(this);connect(ui->actionnew, &QAction::triggered, [=](){// 其他标准对话框// 颜色对话框// QColor color = QColorDialog::getColor(QColor(244, 0, 0));// qDebug() << "r=" << color.red() << " g=" << color.green() << " b=" << color.blue() << " a=" << color.alpha();// 文件对话框 参数1:父亲,参数2:标题,参数3:默认打开路径,参数4:过滤文件格式// 返回值是选取的路径// QString str = QFileDialog::getOpenFileName(this, "打开文件", "C:\\Users\\Administrator\\Desktop", "(*.txt)");// qDebug() << str;// 字体对话框bool flag;QFont font = QFontDialog::getFont(&flag, QFont("华文彩云", 36));qDebug() << "字体:" << font.family() << " 字号:" << font.pointSize() << " 是否加粗:" << font.bold() << " 是否倾斜:" << font.italic();});}MainWindow::~MainWindow(){delete ui;}
登入窗口布局
按钮组
Button
Tool Button 一般用于图片
Radio Button 配合Group Box进行分组
// 设置单选按钮 男默认选中ui->rBtnMan->setChecked(true);// 选中女后打印信息connect(ui->rBtnWoman, &QRadioButton::clicked, [=](){qDebug() << "选中女";});
check box
// 多选按钮connect(ui->cBox, &QCheckBox::stateChanged, [=](int state){qDebug() << state;});
Item Widge…
QListWidget 控件
// 利用listWidget写诗QListWidgetItem * item = new QListWidgetItem("锄禾日当午");// 将一行诗放入到listWidget控件中ui->listWidget->addItem(item);// 居中item->setTextAlignment(Qt::AlignHCenter);// QStringList QList<QString>QStringList list;list << "aaaaa" << "bbbb" << "cccc";ui->listWidget->addItems(list);
QTreeWidget 控件
// treeWidget树控件使用// 设置水平头ui->treeWidget->setHeaderLabels(QStringList() << "英雄" << "英雄介绍");QTreeWidgetItem * liItme = new QTreeWidgetItem(QStringList() << "力量");QTreeWidgetItem * minItme = new QTreeWidgetItem(QStringList() << "敏捷");QTreeWidgetItem * zhiItme = new QTreeWidgetItem(QStringList() << "智力");// 加载顶层的节点ui->treeWidget->addTopLevelItem(liItme);ui->treeWidget->addTopLevelItem(minItme);ui->treeWidget->addTopLevelItem(zhiItme);// 追加子节的QStringList heroL1;QStringList heroL1_2;heroL1 << "刚被猪" << "前排坦克,能在吸收伤害的同时造成客观的范围输出";heroL1_2 << "刚被猪" << "前排坦克,能在吸收伤害的同时造成客观的范围输出";QTreeWidgetItem * l1 = new QTreeWidgetItem(heroL1);QTreeWidgetItem * l1_2 = new QTreeWidgetItem(heroL1_2);liItme->addChild(l1);liItme->addChild(l1_2);QStringList heroL2;heroL2 << "刚被猪" << "前排坦克,能在吸收伤害的同时造成客观的范围输出";QTreeWidgetItem * l2 = new QTreeWidgetItem(heroL2);minItme->addChild(l2);QStringList heroL3;heroL3 << "刚被猪" << "前排坦克,能在吸收伤害的同时造成客观的范围输出";QTreeWidgetItem * l3 = new QTreeWidgetItem(heroL3);zhiItme->addChild(l3);

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<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)));// QString::number(i+8) int 转stringui->tableWidget->setItem(i, col++, new QTableWidgetItem(QString::number(i+8)));}

其他
Stacked Widget 控件
//栈控件使用// 设置默认定位是scrollAreaui->stackedWidget->setCurrentIndex(0);// scrollArea按钮connect(ui->btn_scrollArea, &QPushButton::clicked, [=](){ui->stackedWidget->setCurrentIndex(1);});// toolBox按钮connect(ui->btn_ToolBox, &QPushButton::clicked, [=](){ui->stackedWidget->setCurrentIndex(2);});// TabWidget按钮connect(ui->btn_TabWidget, &QPushButton::clicked, [=](){ui->stackedWidget->setCurrentIndex(0);});


下拉框 Combo box
// 下拉框添加内容ui->comboBox->addItem("奔驰");ui->comboBox->addItem("宝马");ui->comboBox->addItem("奥迪");// 点击按钮选中奥迪选项connect(ui->btn_select, &QPushButton::clicked, [=](){// ui->comboBox->setCurrentIndex(2);// 方法二ui->comboBox->setCurrentText("奥迪");});
Label可以显示图片
#include "widget.h"#include "ui_widget.h"#include <QMovie> // 加载依赖Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget){ui->setupUi(this);// 利用QLabel显示图片ui->lal_Image->setPixmap(QPixmap(":/Image/butterfly.png"));// 利用QLabel显示gif动态图片QMovie * movie = new QMovie(":/Image/mario.gif");ui->lbl_movie->setMovie(movie);// 播放动图movie->start();}Widget::~Widget(){delete ui;}
自定义控件封装

smallwidget.h文件
#ifndef SMALLWIDGET_H#define SMALLWIDGET_H#include <QWidget>namespace Ui {class SmallWidget;}class SmallWidget : public QWidget{Q_OBJECTpublic:explicit SmallWidget(QWidget *parent = 0);~SmallWidget();// 自定义一个方法(声明)// 设置数字void setNum(int num);// 获取数字int getNum();private:Ui::SmallWidget *ui;};#endif // SMALLWIDGET_H
smallwidget.cpp文件
#include "smallwidget.h"#include "ui_smallwidget.h"SmallWidget::SmallWidget(QWidget *parent) :QWidget(parent),ui(new Ui::SmallWidget){ui->setupUi(this);// QSpinBox移动 QSlider跟着移动void(QSpinBox:: * spSignal)(int) = &QSpinBox::valueChanged;connect(ui->spinBox, spSignal, ui->horizontalSlider, &QSlider::setValue);connect(ui->horizontalSlider, &QSlider::valueChanged, ui->spinBox, &QSpinBox::setValue);}// 自定义一个方法(实现) 接口给外部调用// 设置数字void SmallWidget::setNum(int num){ui->spinBox->setValue(num);}// 获取数字int SmallWidget::getNum(){return ui->spinBox->value();}SmallWidget::~SmallWidget(){delete ui;}
widget.cpp文件
#include "widget.h"#include "ui_widget.h"#include <QDebug>Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget){ui->setupUi(this);// 点击按钮获取当前的值connect(ui->getNowBtn, &QPushButton::clicked, [=](){qDebug() << ui->widget->getNum();});// 点击按钮设置一半值connect(ui->setHelfBtn, &QPushButton::clicked, [=](){ui->widget->setNum(50);});}Widget::~Widget(){delete ui;}
QT控件中的鼠标事件
mylabel.h文件
#ifndef MYLABEL_H#define MYLABEL_H#include <QLabel>class myLabel : public QLabel{Q_OBJECTpublic:explicit myLabel(QWidget *parent = nullptr);// 鼠标进入事件void enterEvent(QEvent *event);// 鼠标离开void leaveEvent(QEvent *);// 重写鼠标事件// 鼠标的按下virtual void mousePressEvent(QMouseEvent *ev);// 鼠标的释放virtual void mouseReleaseEvent(QMouseEvent *ev);// 鼠标的按下移动virtual void mouseMoveEvent(QMouseEvent *ev);signals:public slots:};#endif // MYLABEL_H
mylabel.cpp文件
#include "mylabel.h"#include <QDebug>#include <QMouseEvent>myLabel::myLabel(QWidget *parent) : QLabel(parent){// 设置鼠标追踪状态 未设置时,鼠标按下移动才进行捕捉setMouseTracking(true);}// 鼠标进入事件void myLabel::enterEvent(QEvent *event){qDebug() << "鼠标进入了";}// 鼠标离开void myLabel::leaveEvent(QEvent *){qDebug() << "鼠标离开了";}// 重写鼠标事件// 鼠标的按下void myLabel::mousePressEvent(QMouseEvent *ev){// QT格式化字符串// global是距离屏幕的距离// 当鼠标左键按下时,才打印信息if(ev->button() == Qt::LeftButton) {QString str = QString("鼠标按下了 x= %1 y=%2 globalX=%3 globalY=%4").arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY());qDebug() << "鼠标点击了" << str;}}// 鼠标的释放void myLabel::mouseReleaseEvent(QMouseEvent *ev){QString str = QString("鼠标按下了 x= %1 y=%2 globalX=%3 globalY=%4").arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY());qDebug() << "鼠标释放了" << str;}// 鼠标的按下移动void myLabel::mouseMoveEvent(QMouseEvent *ev){// 联合操作if(ev->buttons() & Qt::LeftButton){QString str = QString("鼠标按下了 x= %1 y=%2 globalX=%3 globalY=%4").arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY());qDebug() << "鼠标按下移动了" << str;}}
然后label提升为myLabel类
定时器1
widget.h文件
#ifndef WIDGET_H#define WIDGET_H#include <QWidget>namespace Ui {class Widget;}class Widget : public QWidget{Q_OBJECTpublic:explicit Widget(QWidget *parent = 0);~Widget();// 重写定时器的事件void timerEvent(QTimerEvent *);int id1; // 定时器1的唯一标识int id2; // 定时器2的唯一标识private:Ui::Widget *ui;};#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);// 启动定时器id1 = startTimer(1000); // 参数1 间隔,单位为msid2 = startTimer(2000);}void Widget::timerEvent(QTimerEvent *ev){// static为静态,可以提升作用域// label2每隔1秒+1if(ev->timerId() == id1){static int num = 1;ui->label_2->setText(QString::number(num++));}// label2每隔2秒+1if(ev->timerId() == id2){static int num2 = 1;ui->label_3->setText(QString::number(num2++));}}Widget::~Widget(){delete ui;}

定时器2
widget.cpp文件
#include "widget.h"#include "ui_widget.h"#include <QTimer> // 定时器的类Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget){ui->setupUi(this);// 定时器第二种方式QTimer * timer = new QTimer(this);// 启动定时器timer->start(500);connect(timer, &QTimer::timeout, [=](){// label_4 每隔0.5s加1static int num = 1;ui->label_4->setText(QString::number(num++));});// 点击暂停按钮 实现停止定时器connect(ui->btnStop, &QPushButton::clicked, [=](){timer->stop();});// 点击开始按钮 实现开始定时器connect(ui->btnStart, &QPushButton::clicked, [=](){timer->start();});}Widget::~Widget(){delete ui;}
开始
用于事件分发和拦截
#ifndef MYLABEL_H#define MYLABEL_H#include <QLabel>class myLabel : public QLabel{Q_OBJECTpublic:explicit myLabel(QWidget *parent = nullptr);// 鼠标进入事件void enterEvent(QEvent *event);// 鼠标离开void leaveEvent(QEvent *);// 重写鼠标事件// 鼠标的按下virtual void mousePressEvent(QMouseEvent *ev);// 鼠标的释放virtual void mouseReleaseEvent(QMouseEvent *ev);// 鼠标的按下移动virtual void mouseMoveEvent(QMouseEvent *ev);// 通过event事件分发器拦截鼠标按下事件bool event(QEvent *e);signals:public slots:};#endif // MYLABEL_H
#include "mylabel.h"#include <QDebug>#include <QMouseEvent>myLabel::myLabel(QWidget *parent) : QLabel(parent){// 设置鼠标追踪状态 未设置时,鼠标按下移动才进行捕捉setMouseTracking(true);}// 鼠标进入事件void myLabel::enterEvent(QEvent *event){qDebug() << "鼠标进入了";}// 鼠标离开void myLabel::leaveEvent(QEvent *){qDebug() << "鼠标离开了";}// 重写鼠标事件// 鼠标的按下void myLabel::mousePressEvent(QMouseEvent *ev){// QT格式化字符串// global是距离屏幕的距离// 当鼠标左键按下时,才打印信息if(ev->button() == Qt::LeftButton) {QString str = QString("鼠标按下了 x= %1 y=%2 globalX=%3 globalY=%4").arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY());qDebug() << "鼠标点击了" << str;}}// 鼠标的释放void myLabel::mouseReleaseEvent(QMouseEvent *ev){QString str = QString("鼠标按下了 x= %1 y=%2 globalX=%3 globalY=%4").arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY());qDebug() << "鼠标释放了" << str;}// 鼠标的按下移动void myLabel::mouseMoveEvent(QMouseEvent *ev){// 联合操作if(ev->buttons() & Qt::LeftButton){QString str = QString("鼠标按下了 x= %1 y=%2 globalX=%3 globalY=%4").arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY());qDebug() << "鼠标按下移动了" << str;}}// 通过event事件分发器拦截鼠标按下事件bool myLabel::event(QEvent *e){if(e->type() == QEvent::MouseButtonPress){// static_cast为类型转换 将e转成evQMouseEvent *ev = static_cast<QMouseEvent *>(e);QString str = QString("Event函数中 鼠标按下了 x= %1 y=%2 globalX=%3 globalY=%4").arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY());qDebug() << str;return true; // true 代表用户自己处理这个事件,不向下分发}// 其他事件交给父类处理 默认处理return QLabel::event(e);}
绘图事件
QPaint基本设置
widget.h文件
#ifndef WIDGET_H#define WIDGET_H#include <QWidget>namespace Ui {class Widget;}class Widget : public QWidget{Q_OBJECTpublic:explicit Widget(QWidget *parent = 0);~Widget();// 绘图事件void paintEvent(QPaintEvent *event);private:Ui::Widget *ui;};#endif // WIDGET_H
#include "widget.h"#include "ui_widget.h"#include <QPainter> // 画家类Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget){ui->setupUi(this);}void Widget::paintEvent(QPaintEvent *event){// 实例化画家对象 this指的是绘图设备QPainter painter(this);// 设置画笔QPen pen(QColor(255, 0, 0));// 设置画笔的宽度pen.setWidth(3);// 设置画笔风格 默认为实线pen.setStyle(Qt::DotLine);//使用这个笔painter.setPen(pen);// 设置画刷QBrush brush(QColor(0, 255, 0));// 设置画刷风格brush.setStyle(Qt::Dense7Pattern);// 让画家使用画刷painter.setBrush(brush);// 画线painter.drawLine(QPoint(0, 0), QPoint(100, 100));// 画圆painter.drawEllipse(QPoint(100, 100), 50, 50);// 画矩形 在x:20, y:20画width:50, height:50的矩形painter.drawRect(QRect(20, 20, 50, 50));// 画文字painter.drawText(QRect(10, 200, 100, 50), "好好学习");}Widget::~Widget(){delete ui;}
QPaint高级设置
#include "widget.h"#include "ui_widget.h"#include <QPainter> // 画家类Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget){ui->setupUi(this);}void Widget::paintEvent(QPaintEvent *event){// // 实例化画家对象 this指的是绘图设备// 高级设置QPainter painter(this);// painter.drawEllipse(QPoint(100, 50), 50, 50);// // 设置抗锯齿能力 效率低// painter.setRenderHint(QPainter::Antialiasing);// painter.drawEllipse(QPoint(200, 50), 50, 50);// 画矩形painter.drawRect(QRect(20, 20, 50, 50));// 移动画笔painter.translate(100, 0);// 保存画家状态painter.save();// 还原画家保存状态painter.restore();// 画矩形painter.drawRect(QRect(20, 20, 50, 50));}Widget::~Widget(){delete ui;}
利用画家 画资源图片
widget.h文件
#ifndef WIDGET_H#define WIDGET_H#include <QWidget>namespace Ui {class Widget;}class Widget : public QWidget{Q_OBJECTpublic:explicit Widget(QWidget *parent = 0);~Widget();// 绘图事件void paintEvent(QPaintEvent *event);// 设置图片的x位置int posX = 0;private:Ui::Widget *ui;};#endif // WIDGET_H
widget.ccp文件
#include "widget.h"#include "ui_widget.h"#include <QPainter> // 画家类Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget){ui->setupUi(this);// 点击移动按钮,移动图片connect(ui->pushButton, &QPushButton::clicked, [=](){// 如果要手动调用绘图事件 用update更新posX +=20;update();});}void Widget::paintEvent(QPaintEvent *event){// // 实例化画家对象 this指的是绘图设备// 利用画家 画资源图片QPainter painter(this);// 如果超出屏幕 从0开始if(posX > this->width()){posX = 0;}painter.drawPixmap(posX, 0, QPixmap(":/Image/zf.jpg"));}Widget::~Widget(){delete ui;}
绘图设备
widget.h文件
#ifndef WIDGET_H#define WIDGET_H#include <QWidget>namespace Ui {class Widget;}class Widget : public QWidget{Q_OBJECTpublic:explicit Widget(QWidget *parent = 0);~Widget();// 绘图事件void paintEvent(QPaintEvent *);private:Ui::Widget *ui;};#endif // WIDGET_H
widget.ccp文件
#include "widget.h"#include "ui_widget.h"#include <QPixmap>#include <QPainter>#include <QImage>#include <QPicture>Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget){ui->setupUi(this);// Pixmap绘图设备 专门为平台做了显示的优化QPixmap pix(300, 300);// 填充颜色pix.fill(Qt::white);// 声明画家QPainter painter(&pix);painter.setPen(QPen(Qt::green));painter.drawEllipse(QPoint(150, 0150), 100, 100);// 保存pix.save("E:\\pix.png");// 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("E:\\img.png");// QPicture 绘图设备 可以记录和重现绘图指令QPicture pic;QPainter painter;painter.begin(&pic); // 开始往pic上画painter.setPen(QPen(Qt::cyan));painter.drawEllipse((QPoint(150, 150), 100, 100));painter.end(); // 结束画画pic.save("E:\\pic.zt");}// 绘图事件void Widget::paintEvent(QPaintEvent *){QPainter painter(this);// 利用QImage 对象进行修改QImage img;img.load((":/Image/Luffy.png"));// 修改像素点for(int i=50; i<100; i++){for(int j=50; j<100; j++){QRgb value = qRgb(255, 0, 0);img.setPixel(i, j, value);}}painter.drawImage(0, 0, img);QPainter painter(this);// 重现QPicture的绘图指令QPicture pic;pic.load("E:\\pic.zt");painter.drawPicture(0, 0, pic);}Widget::~Widget(){delete ui;}
QFile文件读写操作
#include "widget.h"#include "ui_widget.h"#include <QFileDialog>#include <QFile> // 对文件进行读和写#include <QTextCodec>Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget){ui->setupUi(this);// 点击选取文件按钮,弹出文件对话框connect(ui->pushButton, &QPushButton::clicked, [=](){QString path = QFileDialog::getOpenFileName(this, "打开文件", "c:\\Users\\Administrator\\Desktop", "*txt");// 将路径放入到lineEdit中ui->lineEdit->setText(path);// 编码格式类QTextCodec * codec = QTextCodec::codecForName("gbk");// 读取内容 放入到 textEdit中// QFile默认支持utf-8格式QFile file(path); // 参数就是读取文件的路径/************************************************** QIODevice::ReadWrite 可读写* QIODevice::Text 换行符生效* QIODevice::Append 追加写入* QFile::Truncate 表示将原文件清空**************************************************/// 设置打开方式file.open(QIODevice::ReadOnly);QByteArray array = file.readAll();// // 按行读// QByteArray array2;// // 循环读取文件,值到无文件可读// while(!file.atEnd()) // atEnd判断是否到文件末尾了// {// array2 += file.readLine();// }// 将读取到的数据放入textEdit中ui->textEdit->setText(array);// 使用toUnicode进行转码// ui->textEdit->setText(codec->toUnicode(array));// 对文件对象进行关闭file.close();// 进行写文件file.open(QIODevice::Append); // 用追加的方式进行写file.write("啊啊啊啊");file.close();});}Widget::~Widget(){delete ui;}
QFileInfo文件信息读取
#include "widget.h"#include "ui_widget.h"#include <QFileDialog>#include <QTextCodec>#include <QFileInfo> // 获取文件信息头#include <QDebug>#include <QDateTime>Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget){ui->setupUi(this);// 点击选取文件按钮,弹出文件对话框connect(ui->pushButton, &QPushButton::clicked, [=](){QString path = QFileDialog::getOpenFileName(this, "打开文件", "c:\\Users\\Administrator\\Desktop", "*txt");// QFileInfo 文件信息类QFileInfo info(path);qDebug() << "大小:" << info.size() << " 后缀名:" << info.suffix() << " 文件名称:" << info.fileName() << " 文件路径:" << info.filePath();qDebug() << "创建日期" << info.created().toString("yyyy/MM/dd hh:mm:ss");qDebug() << "最后修改日期" << info.lastModified().toString("yyyy-MM-dd hh:mm:ss");});}Widget::~Widget(){delete ui;}
