1.创建一个QT文件
点击创建项目,选择项目路径以及名称(不能含中文)
默认创建有窗口类,基类有三种选择:Qwidget,QmyWindow,QDialog.main.cpp介绍
main函数:看注释
#include "widget.h"
#include <QApplication>//包含一个应用程序类的头文件
#include <QLocale>
#include <QTranslator>
//main程序入口,argc命令行变量的数量,argvming命令行变量的数组
int main(int argc, char *argv[])
{
//a 应用程序对象,在Qt中,应用程序对象,有且只有一个
QApplication a(argc, argv);
QTranslator translator;
const QStringList uiLanguages = QLocale::system().uiLanguages();
for (const QString &locale : uiLanguages) {
const QString baseName = "test01_" + QLocale(locale).name();
if (translator.load(":/i18n/" + baseName)) {
a.installTranslator(&translator);
break;
}
}
//窗口对象
Widget w;
//窗口对象,默认不会显示,必须要调用show方法显示窗口
w.show();
//让应用程序对象 a 进入消息循环机制,让代码停留在这行
return a.exec();
}
1.1命名规范
类名:首字母大写,单词和单词之间首字母大写
函数名 变量名称:首字母小写,单词和单词之间首字母大写
1.2快捷键
注释 :ctrl + /
运行: ctrl + r
编译: ctrl + b
字体缩放: ctrl + 鼠标滚轮
查找: ctrl + f
整行移动: ctrl + shift + ↑或↓
帮助文档:F1
自动对齐:ctrl + i
同名之间的.h和.cpp切换:f4
2QPushButton创建
创建QPushButtn *btn = new QPushButton
设置父亲 setParent(this)
设置文本 setText("文字")
设置位置 move(宽,高)
重新指定窗口大小 resize
设置窗口标题 setWindowTitle("窗口");
设置固定窗口大小 setFixedSize(600,600);
mainwindow.cpp
#include "mainwindow.h"
#include<QPushButton>//按钮头文件
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
//创建一个按钮
QPushButton *btn = new QPushButton;
//btn->show();//show以顶层方式弹出控件
btn->setParent(this);
//重新制定按钮大小
btn->resize(100,100);
//显示文本
btn->setText("first");
//创建第二个按钮 按照控件大小创建窗口
QPushButton *btn2=new QPushButton("second",this);
//移动btn2按钮
btn2->move(100,100);
//重置窗口大小
resize(800,800);
//设置窗口标题
setWindowTitle("窗口");
//设置固定窗口大小
setFixedSize(600,600);
}
MainWindow::~MainWindow()
{
}
2.1防止汉语乱码
哪个文件需要,就在哪个上面加这行代码
pragma execution_character_set("utf-8")//防止乱码
打开选项->文本编辑器->行为,如图设置
打开编辑->select enconding如图设置
2.2对象树
当创建的对象再堆区的时候,如果指定的父亲是Qobject派生下来的类或者Qobject子类派生下来的类,可以不用管理释放的操作,会将对象放入到对象树中
一定程度上简化了内存回收机制
2.3Qt窗口坐标体系
以左上角为远点(0,0),X向右增加,Y向下增加
3信号和槽机制
connect(发送者,信号(函数地址),接收者,槽函数)
connect( mybtn , &QPushButton::clicked , this , &MainWindow::close );
3.1自定义信号和槽
自定义老师->饿了->学生->请客吃饭(饿了是信号,吃饭是槽)
创建老师和学生的类(Teacher;Student)->头文件声明->源文件槽函数实现
头文件声明时:
3.1.1自定义信号:
自定义信号,写到signals下
返回值是void,只需要声明,不需要实现
可以有参数,可以重载
signals:
void hungry();
3.1.2自定义槽:
早期版本qt,必须写到public slots,高级版本可以下到public或者全局函数下
返回值是void,需要声明,也需要实现
可以有参数,可以发生重载
public slot:
void treat();
源文件的槽函数实现:
void Student::treat()
{
qDebug()<<"请老师吃饭";
}
Widget.cpp文件:
Widget::Widget(QWidget *parent): QWidget(parent)
{
//创建一个老师的对象
this->zt=new Teacher(this);
//创建一个学生的对象
this->st=new Student(this);
//老师饿了 学生请客吃饭连接
connect(zt,&Teacher::hungry,st,&Student::treat);
//调用下课函数
classIsOver();//有顺序的,需要先连接再调用
}
void Widget::classIsOver()
{
//下课函数,调用后,老师饿了
emit zt->hungry();//触发的关键字:emit
}
void Widget::classIsOver()
{
//下课函数,调用后,老师饿了
//emit zt->hungry();//触发的关键字:emit
emit zt->hungry("烤腰子");
}
触发信号的关键字:emit
3.2自定义信号和槽发生重载
3.2.1重载:
teacher.h文件中:
signals:
void hungry();
void hungry(QString foodNname);
student.h文件中:
public slot:
void treat();
void treat(QString foodName);
槽函数(学生请客吃饭)实现:
void Student::treat(QString foodName)
{
qDebug()<<"请老师吃饭,老师要吃:"<<foodName;
}
3.2.2连接解决办法:
需要利用函数指针,明确指向函数的地址
void(Teacher::*teacherSignal)(QString)=&Teacher::hungry;
void(Student::*studentSlot)(QString) = &Student::treat;
connect(zt,teacherSignal,st,studentSlot);//有参
3.2.3QString输出的内容带引号解决办法:
q
Debug()<<"请老师吃饭,老师要吃:"<<foodName;
解决方法:
QString->char* 先转成QByerArray(.toUtf8())再转char*()
qDebug()<<"请老师吃饭,老师要吃:"<<foodName.toUtf8().data();
3.3信号槽的拓展
设置一下:点击一个按钮,触发下课信号
QPushButton *btn=new QPushButton("下课",this);
connect(btn,&QPushButton::clicked,this,&Widget::classIsOver);//按钮->触发->下课
3.3.1无参信号和槽连接
void(Teacher::*teacherSignal2)(void)=&Teacher::hungry;
void(Student::*studentSlot2)(void) = &Student::treat;
connect(zt,teacherSignal2,st,studentSlot2);
3.3.2信号连接信号
(按钮->老师饿了->学生请客)
connect(zt,teacherSignal2,st,studentSlot2);
connect(btn,&QPushButton::clicked,zt,teacherSignal2);
3.3.3断开信号:disconnect
disconnect(zt,teacherSignal2,st,studentSlot2);
3.3.4一个信号可以连接多个槽函数
connect(btn,&QPushButton::clicked,zt,teacherSignal2);
connect(btn,&QPushButton::clicked,this,&Widget::close);
3.3.5多个信号可以连接同一个槽函数
3.3.6信号和槽函数的参数必须一一对应
3.3.7信号的参数个数可以比槽函数参数个数多,但是需要一一对应,反之不可
3.4Lambda表达式
[](){};
[=](){
btn->setText("放学");
}();
[]时Lambda的开始,必须存在,不能省略
中括号内:
=:值传递; &:引用传递; this:类似于=; a:将a按值进行传递;
&a:将a按引用进行传递; & ,a , b :除a,b值传递,其他都是引用传递;
= ,&a ,&b:除a,b引用传递,其他都是值传递
小括号内:
标识重载的()操作符的参数,没有参数时可以不写
参数可以通过按值和按引用两种方式进行传递
可修改标识符:
mutable:修改按值传递进来的拷贝的值,而非修改本体。这部分可以省略
函数返回值:
->返回值类型,标识函数返回值的类型,但返回值为void时,或者函数体中只有一处return的地方(此时编译器可以自动推断除返回值类型)时,这部分可以省略
函数体:
{},标识函数的实现,这部分不能省略,但函数体可以为空
lambda表达式的使用:
第三个表达式时this时,可以省略
//利用lambda表达式实现点击按钮关闭窗口
QPushButton *btn2=new QPushButton("关闭",this);
btn2->move(300,0);
connect(btn2,&QPushButton::clicked,this,[=](){
this->close();
emit zt->hungry("烤腰子");
btn2->setText("aaa");
});
3.5Open Close控制实现案例
#include "widget.h"
#include<QPushButton>
#pragma execution_character_set("utf-8")//防止乱码
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
QWidget *New_Window = new QWidget;
New_Window->setWindowTitle("点击open出现的");
QPushButton *btn = new QPushButton("Open",this);
btn->resize(100,50);
btn->move(300,400);
resize(800,800);
setWindowTitle("黑马练习一");
```c++
connect(btn,&QPushButton::clicked,New_Window,[=](){
if(btn->text()=="Open")
{
New_Window->show();
btn->setText("Close");
}
else
{
New_Window->close();
}
});
```
}
Widget::~Widget()
{
}
4.QMainWindow
4.1菜单栏:
QMenuBar *bar = menuBar();//创建菜单栏,菜单栏只能有一个
setMenuBar(bar);//将菜单栏放入到窗口中
QMenu * fileMenu=bar->addMenu("文件"); //创建菜单
QMenu * editMenu=bar->addMenu("编辑"); //返回的是QMenu *
fileMenu->addAction("新建");//创建菜单项目,返回的是QAction *
fileMenu->addSeparator();//添加分隔线
fileMenu->addAction("打开");
4.2工具栏:
QToolBar *toolBar = new QToolBar(this); //工具栏 ,可以有多个
//将工具栏放在窗口中addToolBar
addToolBar(Qt::LeftToolBarArea,toolBar);//参数一:自定义工具栏默认位置
//后期设置 只允许 左右停靠
toolBar->setAllowedAreas(Qt::LeftToolBarArea|Qt::RightToolBarArea);
//设置浮动操作
toolBar->setFloatable(0);//bool类型,0代表不允许浮动
//设置移动(总开关)
toolBar->setMovable(0);//bool型,0-不允许移动,1-允许
toolBar->addAction("新建"); //工具栏中可以 设置内容
toolBar->addSeparator();//分割线
toolBar->addAction("打开");
QPushButton *btn = new QPushButton("open",this);
toolBar->addWidget(btn);//工具栏中添加控件
4.3状态栏:
QStatusBar *stBar= statusBar(); //状态栏 最多只能有一个
setStatusBar(stBar); //设置在窗口中
QLabel *label = new QLabel("提示信息",this); //放标签控件
stBar->addWidget(label);//左侧
QLabel *label2 = new QLabel("右侧提示信息",this);
stBar->addPermanentWidget(label2);//右侧
4.4铆接部件(浮动窗口):
QDockWidget *dockwidget = new QDockWidget("浮动",this);//铆接部件(浮动窗口) 可以有多个
addDockWidget(Qt::BottomDockWidgetArea,dockwidget);
//设置后期停靠区域,只允许上下
dockwidget->setAllowedAreas(Qt::TopDockWidgetArea|Qt::BottomDockWidgetArea);
4.5中心部件:
//设置中心部件 只能有一个
QTextEdit * edit = new QTextEdit(this);
setCentralWidget(edit);
4.6全部代码
#include "mainwindow.h"
#pragma execution_character_set("utf-8")//防止乱码
#include<QMenuBar>
#include<qtoolbar.h>
#include<QDebug>
#include<QPushButton>
#include<QStatusBar>
#include<QLabel>
#include<QDockWidget>
#include<QTextEdit>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
resize(600,600);//重置窗口
```c++
//创建菜单栏,菜单栏只能有一个
QMenuBar *bar = menuBar();
//将菜单栏放入到窗口中
setMenuBar(bar);
//创建菜单
QMenu * fileMenu=bar->addMenu("文件");
QMenu * editMenu=bar->addMenu("编辑");
//创建菜单项目
fileMenu->addAction("新建");
//添加分隔线
fileMenu->addSeparator();
fileMenu->addAction("打开");
```
```c++
//工具栏 ,可以有多个
QToolBar *toolBar = new QToolBar(this);
//将工具栏放在窗口中addToolBar
addToolBar(Qt::LeftToolBarArea,toolBar);//自定义工具栏默认位置
//后期设置 只允许 左右停靠
toolBar->setAllowedAreas(Qt::LeftToolBarArea|Qt::RightToolBarArea);
//设置浮动操作
toolBar->setFloatable(0);//bool类型,0代表不允许浮动
//设置移动(总开关)
toolBar->setMovable(0);//bool型,0-不允许移动,1-允许
//工具栏中可以 设置内容
toolBar->addAction("新建");
toolBar->addSeparator();//分割线
toolBar->addAction("打开");
//工具栏中添加控件
QPushButton *btn = new QPushButton("open",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);
```
```c++
//设置中心部件 只能有一个
QTextEdit * edit = new QTextEdit(this);
setCentralWidget(edit);
```
}
MainWindow::~MainWindow()
{
}
4.7资源文件添加
1.将图片文件拷贝到项目文件下
2.创建一个新文件,右键项目->添加新文件->Qt->Qt Resource File->起名
3.起名res->生成res.qrc
4.res.qrc打开方式:右键->open in editor
5.添加前缀->添加文件
6.使用”:+前缀名+文件名“
//一般
ui->actionnew->setIcon(QIcon("D:\\photo\\a.jpg"));
//使用添加QT资源 ":+前缀名+文件名"
ui->actionnew->setIcon(QIcon(":/new/prefix1/photo/a.jpg"));
5.对话框
对话框 分类:模态对话框(不可以对其他窗口进行操作)和 非模态对话框(可以对其他窗口进行操作)
5.1自定义消息框
5.1.1模态创建:
//模态创建 有阻塞功能
QDialog dlg(this);
dlg.resize(200,100);
dlg.exec();
5.1.2非模态创建:
//非模态对话框创建,防止一闪而过,所以创建在堆区
QDialog *dlg2=new QDialog(this);
dlg2->resize(500,100);
dlg2->setAttribute(Qt::WA_DeleteOnClose);//关闭小对话框时会释放堆区数据
dlg2->show();
5.2标准对话框
标准对话框是Qt内置的一系列对话框。
Qt的内置对话框大致分为以下基类:
QClorDialog: 选择颜色
QFileDialog: 选择文件或者目录
QFontDialog: 选择字体
QInputDialog: 允许用户输入一个值,并将其值返回
QMessageBox: 模态对话框,用于显示信息,询问问题等
QPageSetupDialog: 为打印机提供纸张相关的选项
QPrintPreviewDialog: 打印预览
QProngressDialog: 显示操作过程
5.2.1QMessageBox下的四种对话框:
//错误对话框
QMessageBox::critical(this,"错误提示","出错了404");
//信息对话框
QMessageBox::information(this,"提示","5+3=8");
//问题对话框question(父亲,标题,内容,按键类型,默认按键)
if(QMessageBox::Save==QMessageBox::question(this,"问题对话框","who is who?",QMessageBox::Save|QMessageBox::Cancel,QMessageBox::Cancel))
{
qDebug()<<"选择的是save";
}
else if(QMessageBox::Cancel==QMessageBox::question(this,"问题对话框","who is who?",QMessageBox::Save|QMessageBox::Cancel,QMessageBox::Cancel))
{
qDebug()<<"选择的是Cancel";
}
//警告对话框
QMessageBox::warning(this,"警告","你小子今晚别睡太死!");
5.3其他标准对话框
5.3.1颜色对话框:
//其他标准对话框
QColor color =QColorDialog::getColor(QColor(255,0,0));//返回值是QColor类型
qDebug()<<color.red();
5.3.2文件对话框:
//文件对话框QFileDialog::getOpenFileName(父亲,标题,默认打开路径,过滤文件格式)
//返回值是选取的路径
QString str = QFileDialog::getOpenFileName(this,"打开文件","E:\\Project\\QT_project\\HeiMa_Class\\HeiMa_SecondDay_03","(*.txt)");//返回值QString
qDebug()<<str;
5.3.3字体对话框:
//选择字体对话框
bool flag;
QFont font = QFontDialog::getFont(&flag,QFont("仿宋",36));
qDebug()<<font.
5.4全部代码
#include "mainwindow.h"
#include "ui_mainwindow.h"
#pragma execution_character_set("utf-8")//防止乱码
#include<QDialog>
#include<QDebug>
#include<QMessageBox>
#include<QColorDialog>
#include<QFileDialog>
#include<QFontDialog>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
```c++
//点击新建按钮,弹出一个对话框
connect(ui->actionnew,&QAction::triggered,[=](){
```
// //对话框 分类:模态对话框(不可以对其他窗口进行操作)和 非模态对话框(可以对其他窗口进行操作)
// //模态创建 有阻塞功能
// QDialog dlg(this);
// dlg.resize(200,100);
// dlg.exec();
// qDebug()<<"模态对话框弹出了";
// //非模态对话框创建,防止一闪而过,所以创建在堆区
// QDialog *dlg2=new QDialog(this);
// dlg2->resize(500,100);
// dlg2->setAttribute(Qt::WA_DeleteOnClose);//关闭小对话框时会释放堆区数据
// dlg2->show();
```c++
//消息对话框
//错误对话框
//QMessageBox::critical(this,"错误提示","出错了404");
//信息对话框
//QMessageBox::information(this,"提示","5+3=8");
//问题对话框question(父亲,标题,内容,按键类型,默认按键)
```
// if(QMessageBox::Save==QMessageBox::question(this,"问题对话框","who is who?",QMessageBox::Save|QMessageBox::Cancel,QMessageBox::Cancel))
// {
// qDebug()<<"选择的是save";
// }
// else if(QMessageBox::Cancel==QMessageBox::question(this,"问题对话框","who is who?",QMessageBox::Save|QMessageBox::Cancel,QMessageBox::Cancel))
// {
// qDebug()<<"选择的是Cancel";
// }
//警告对话框
//QMessageBox::warning(this,"警告","你小子今晚别睡太死!");
```c++
//其他标准对话框
//QColor color =QColorDialog::getColor(QColor(255,0,0));//返回值是QColor类型
//qDebug()<<color.red();
//文件对话框QFileDialog::getOpenFileName(父亲,标题,默认打开路径,过滤文件格式)
//返回值是选取的路径
//QString str = QFileDialog::getOpenFileName(this,"打开文件","E:\\Project\\QT_project\\HeiMa_Class\\HeiMa_SecondDay_03","(*.txt)");//返回值QString
//qDebug()<<str;
//选择字体对话框
bool flag;
QFont font = QFontDialog::getFont(&flag,QFont("仿宋",36));
qDebug()<<font;
});
```
}
MainWindow::~MainWindow()
{
delete ui;
}
6.界面布局
->实现登录窗口,利用布局方式对窗口进行美化
->选取widget进行布局,水平布局,垂直布局,栅格布局(几行几列的时候用)
->给用户名、密码、登录、退除按钮进行布局
->默认窗口和控件之间有9像素间隙,可以选中窗口,在layout中可以修改
->利用弹簧进行布局
7.控件
7.1按钮组
QPushButton 常用按钮
QToolButton 工具按钮,一般用于显示图片,如果想显示文字,修改风格toolbuttonStyle,突起风格:autoRaise
Radio Button 单选按钮,设置默认 setchecked(true)
checkbox 多选按钮,监听状态,2是选中,1是半选,0是未选
7.2QListWidget 列表容器
//利用listwidget写诗
QListWidgetItem * item = new QListWidgetItem("锄禾日当午");
//将这行诗放到listwidget中
ui->listWidget->addItem(item);
item->setTextAlignment(Qt::AlignHCenter);//设置水平剧中
//第二种方法,没办法居中,但是可以一次多行
//QStringList QList<QString>
QStringList list;
list <<"锄禾日当午"<<"汗滴禾下土"<<"谁知盘中餐"<<"粒粒皆辛苦";
ui->listWidget->addItems(list);
7.3QTreeWidget 树控件
//treewidget树控件使用
//设置水平头
ui->treeWidget->setHeaderLabels(QStringList()<<"英雄"<<"英雄介绍");
//设置力量
QTreeWidgetItem *poweritem = new QTreeWidgetItem(QStringList()<<"力量");
//加载顶层的节点
ui->treeWidget->addTopLevelItem(poweritem);
//设置敏捷
QTreeWidgetItem *minjieitem = new QTreeWidgetItem(QStringList()<<"敏捷");
//
ui->treeWidget->addTopLevelItem(minjieitem);
//设置速度
QTreeWidgetItem *zhiliitem = new QTreeWidgetItem(QStringList()<<"智力");
//
ui->treeWidget->addTopLevelItem(zhiliitem);
//追加子节点
QStringList list;
list<<"四大金刚i上看到你告诉官方";
QTreeWidgetItem *l1 = new QTreeWidgetItem(list);
poweritem->addChild(l1);
7.4QTableWidget 表格控件
//设置列数
ui->tableWidget->setColumnCount(3);//3列
//设置水平表头
ui->tableWidget->setHorizontalHeaderLabels(QStringList()<<"姓名"<<"性别"<<"年龄");
//设置行数
ui->tableWidget->setRowCount(5);
QList<QString>nameList; == QStringList nameList;
//设置正文
//第一种可以这样写
//ui->tableWidget->setItem(0,0,new QTableWidgetItem("亚瑟"));//0行0列
//也可以for循环
QList<QString>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)));
}
7.5自定义封装控件
1.添加新文件->QT->设计师界面类
2.在新建的.ui文件中设置QSpinBox和QSlider两个控件
3.在widget.ui中使用自定义的控件
拖拽widget控件,右键提升窗口成刚才设置的ui文件名
4.联动效果
在新建的.cpp文件中设置信号槽联动
//QSpinBox移动 QSlider跟着移动
void(QSpinBox::* spSignal)(int) = &QSpinBox::valueChanged;
connect(ui->spinBox,spSignal,ui->horizontalSlider,&QSlider::setValue);
//QSlider移动 QSpinBox跟着移动
connect(ui->horizontalSlider,&QSlider::valueChanged,ui->spinBox,&QSpinBox::setValue);
5.提供接口,获取数字和设置数字
在widget.ui中提供两个按钮
在新建的.h文件中添加声明
void setNum(int num);//设置数字
int getNum();//获取 数字
然后在新建的.cpp文件中构建函数体
void SmallWidge::setNum(int num)//设置 数字
{
ui->spinBox->setValue(num);
}
int SmallWidge::getNum()//获得 数字
{
return ui->spinBox->value();
}
然后在widget.cpp文件中添加信号槽的联动
//点击获取 获取值
connect(ui->btnGet,&QPushButton::clicked,[=](){
qDebug()<<ui->widget->getNum();
});
//点击设置 设置到一半
connect(ui->btnSet,&QPushButton::clicked,[=](){
ui->widget->setNum(50);
8.QT中的鼠标事件
在widget.ui中设置一个label
然后新建一个C++类,名为mylabel(包含.h,.cpp)
注意:mylabel类应继承QLabel
8.1鼠标进入事件enterEvent
8.1.1在mylabel.h头文件中添加声明
//鼠标进入
void enterEvent(QEvent *event);
8.1.2在mylabel.cpp文件中设置函数体
void myLabel::enterEvent(QEvent *event)
{
//qDebug()<<"鼠标进入了";
}
8.2鼠标离开事件leaveEvent
8.2.1在mylabel.h中添加声明
//鼠标离开
void leaveEvent(QEvent *event);
8.2.2在mylabel.cpp文件中设置函数体
void myLabel::leaveEvent(QEvent *event)
{
//qDebug()<<"鼠标退出了";
}
8.3.鼠标按下 鼠标释放 鼠标移动
8.3.1 mylabel.h中声明
virtual void mousePressEvent(QMouseEvent *ev);//鼠标按下
```c++
virtual void mouseReleaseEvent(QMouseEvent *ev);//鼠标释放
virtual void mouseMoveEvent(QMouseEvent *ev);//鼠标移动
```
8.3.2 ev->x() ev->y() x坐标,y坐标
QString("x=%1 y=%2 globalX=%3 globalY=%4").arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY());
8.3.3 ev->button() 判断左右键
左为Qt::LeftButton 右为Qt::RightButton
void myLabel::mousePressEvent(QMouseEvent *ev)
{
//鼠标左键按下 提示信息
if(ev->button()==Qt::LeftButton)
{
}
}
8.3.4 ev->buttons() 判断组合按键
判断move时候的左右键 结合与操作符
void myLabel::mouseMoveEvent(QMouseEvent *ev)
{
if(ev->buttons()&Qt::LeftButton)//位与运算符 同真才为真
{
}
}
8.3.5 设置鼠标追踪
//设置鼠标追踪,鼠标放上去不需要点击即可打印
setMouseTracking(true);
8.3.6 mylabel.cpp中写函数体
#include "mylabel.h"
#include<QDebug>
#include<QMouseEvent>
#pragma execution_character_set("utf-8")//防止乱码
myLabel::myLabel(QWidget *parent)
: QLabel{parent}
{
//设置鼠标追踪,鼠标放上去不需要点击即可打印
setMouseTracking(true);
}
void myLabel::enterEvent(QEvent *event)
{
qDebug()<<"鼠标进入了";
}
void myLabel::leaveEvent(QEvent *event)
{
qDebug()<<"鼠标退出了";
}
void myLabel::mousePressEvent(QMouseEvent *ev)
{
//鼠标左键按下 提示信息
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)
{
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::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;
}
}
8.3.7格式化字符串
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;
9.定时器、分发器、过滤器、绘图
9.1定时器的第一种方式
9.1.1利用事件 void timerEvent(QTimerEvent *ev)
widget.h中写:
//重写定时器的事件
void timerEvent(QTimerEvent *);
9.1.2启动定时器 startTimer() 毫秒单位
//启动定时器
id1=startTimer(1000);//参数1:间隔,单位是毫秒ms
9.1.3timerEvent的返回值是定时器的唯一标识
timerEvent的返回值是定时器的唯一标识可以和ev->timerId做比较
widget.h中写:
int id1;//定时器1的唯一标识
int id2;//定时器2的唯一标识
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:间隔,单位是毫秒ms
```c++
id2=startTimer(2000);
```
}
void Widget::timerEvent(QTimerEvent *ev)
{
if(ev->timerId()==id1)
{static int num =1;
//label_2每隔1秒+1
ui->label_2->setText(QString::number(num++));}
if(ev->timerId()==id2)
{//label_3每隔2秒+1
static int num2 =1;
ui->label_3->setText(QString::number(num2++));}
}
Widget::~Widget()
{
delete ui;
}
9.2定时器的第二种方式
9.2.1利用定时器的类 QTimer
#include<QTimer>//定时器的类
9.2.2创建定时器对象
QTimer *timer = new QTimer(this);//创建定时器对象
9.2.3启动定时器 timer->start
//启动定时器
timer->start(500);//0.5s
9.2.4信号槽连接
connect(timer,&QTimer::timeout,[=](){
static int num =1;//信号:timeout,进行监听
ui->label_4->setText(QString::number(num++));
});
9.2.5暂停 timer->stop
//点击暂停按钮,实现停止定时器
connect(ui->btn,&QPushButton::clicked,[=](){
timer->stop();
});
9.3 事件分发器event
用于事件分发,也可以做拦截操作,但是不建议
9.3.1 bool event(QEvent * e)
//通过event事件分发器 拦截 鼠标按下事件
bool event(QEvent *e);
9.3.2 返回值若是true,则代表用户处理这个时间,不向下分发了
bool myLabel::event(QEvent *e)
{
//如果是鼠标按下,事件分发器中做拦截操作
if(e->type()==QEvent::MouseButtonPress)
{
QMouseEvent *ev=static_cast<QMouseEvent *>(e);//将e转换为ev
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);
}
9.3.3 e->type() 可以判断事件
bool myLabel::event(QEvent *e)
{
//如果是鼠标按下,事件分发器中做拦截操作
if(e->type()==QEvent::MouseButtonPress)
{}
}
9.4事件过滤器
在程序将事件分发到事件分发器前,可以利用过滤器做拦截
9.4.1给控件安装事件过滤器
//1.给label1安装事件过滤器
ui->label->installEventFilter(this);
9.4.2重写eventFilter(obj,e)函数
//重写事件过滤器的事件
bool eventFilter(QObject *,QEvent *);
//2.重写eventfilter事件
bool Widget::eventFilter(QObject *obj, QEvent *e)
{
if(obj==ui->label)
{
if(e->type()==QEvent::MouseButtonPress)
{
QMouseEvent *ev=static_cast<QMouseEvent *>(e);//将e转换为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;
return true;//true代表用户自己处理事件,不向下分发
}
}
//其他事件 交给父类处理 默认处理
return QWidget::eventFilter(obj,e);
}
9.5 QPainter绘图
9.5.1绘图事件 void paintEvent
//绘图事件
void paintEvent(QPaintEvent *);
9.5.2声明一个画家对象
/
/实例化画家对象 this指定的是绘图的设备
QPainter painter(this);
9.5.3画图、画文字、设置风格等
void Widget::paintEvent(QPaintEvent *)
{
//实例化画家对象 this指定的是绘图的设备
QPainter painter(this);
```c++
//设置画笔
QPen pen(QColor(255,0,0));
//设置画笔宽度
pen.setWidth(3);
//设置画笔风格
pen.setStyle(Qt::DotLine);
//使用画笔
painter.setPen(pen);
//设置画刷
QBrush brush(Qt::cyan);
//设置画刷风格
brush.setStyle(Qt::Dense7Pattern);
//使用画刷
painter.setBrush(brush);
//划线
painter.drawLine(QPoint(0,0),QPoint(100,100));
//画圆
painter.drawEllipse(QPoint(100,100),50,50);
//❀矩形
painter.drawRect(QRect(200,200,200,50));
//画文字
painter.drawText(QRect(50,200,150,50),"好好学习,天天向上");
```
}
9.6 QPainter 高级设置
9.6.1抗锯齿操作 (效率较低)
painter.drawEllipse(QPoint(100,50),50,50);
//设置抗锯齿能力 效率较低
painter.setRenderHint(QPainter::Antialiasing);
painter.drawEllipse(QPoint(200,50),50,50);
9.6.2对画家进行移动
painter.translate(100,0);
9.6.3保存画家状态
painter.save();
9.6.4还原状态
painter.restore();
高级设置:
//高级设置///
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.drawRect(QRect(20,20,50,50));
painter.translate(100,0);
//还原画家保存状态
painter.restore();
painter.drawRect(QRect(20,20,50,50));
9.7手动调用绘图事件
9.7.1利用画家画图片
painter.drawPixmap(posX,0,QPixmap(":/xinglixiang1.jpg"));
9.7.2利用update手动调用绘图事件
//点击移动按钮 移动图片
connect(ui->pushButton,&QPushButton::clicked,[=](){
//如果手动调用绘图事件 用update更新
posX+=20;
update();
/利用画家 画资源图片///
QPainter painter(this);
//如果超出屏幕 从0开始
if(posX>this->width())
{
posX = 0;
}
painter.drawPixmap(posX,0,QPixmap(":/xinglixiang1.jpg"));
9.8 QPaintDevice绘图设备
QPixmap,QBitmap(黑白色),QPicture,QWidget;QImage
9.8.1QPixmap
/pixmap绘图设备 专门为平台做了显示的优化///
QPixmap pix(500,500);
//填充颜色
pix.fill(Qt::red);
//声明画家
QPainter painter(&pix);
painter.setPen(QPen(Qt::green));
painter.drawEllipse(QPoint(250,250),100,100);
//保存
pix.save("E:\\pix.png");
9.8.2QImage
//QImage 绘图设备 可以对像素进行访问///
QImage img(500,500,QImage::Format_RGB32);
img.fill(Qt::blue);
QPainter painter(&img);
painter.setPen(QPen(Qt::red));
painter.drawEllipse(QPoint(250,250),100,100);
//保存
img.save("E:\\img.png");
可以对像素进行访问
```c++
//绘图事件
void paintEvent(QPaintEvent *);
```
void Widget::paintEvent(QPaintEvent *)
{
QPainter painter(this);
//利用QImage对像素进行修改
QImage img;
img.load(":/color.jpg");
```c++
//修改像素点
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);
```
}
9.8.3QPicture
///QPicture 绘图设备 可以记录和重现绘图指令///
QPicture pic;
QPainter painter;
painter.begin(&pic);//开始往pic画
```c++
painter.setPen(QPen(Qt::cyan));
painter.drawEllipse(QPoint(250,250),100,100);
painter.end();//结束画画
//保存
pic.save("E:\\pic.syh");
```
可以记录和重现绘图指令
```c++
//重现QPicture的绘图指令
QPainter painter(this);
QPicture pic;
pic.load("E:\\pic.syh");
painter.drawPicture(0,0,pic);
```
10 QFile 对文件进行读写操作
设置一个ui界面如下:
准备一个txt文档
10.1读文件
10.1.1信号槽连接按钮与文件
//点击选取文件按钮,弹出文件对话框
connect(ui->pushButton,&QPushButton::clicked,[=](){
QString path = QFileDialog::getOpenFileName(this,"打开文件","E:\\杂七杂八\\长恨歌.txt");
以下代码均在信号槽连接中:
10.1.2将路径放在lineEdit中
//将路径放在lineEdit中
ui->lineEdit->setText(path);
10.1.3读取的文件格式
QFile默认支持的格式是utf-8
//编码格式类
QTextCodec *codec = QTextCodec::codecForName("gbk");
10.1.4只读方式打开文件
QFile file(path);//参数就是读取文件的路径
//设置打开方式
file.open(QIODevice::ReadOnly);//只读
10.1.5读取文件
全部读取
QByteArray array = file.readAll();
一行一行读取
```c++
QByteArray array;
while(!file.atEnd())//文件尾的条件
{array += file.readLine();//按行读
};
```
10.1.6文件尾部
file.atEnd()
10.1.7读到的数据放入文本框
//将读到的数据放入textEdit
ui->textEdit->setText(array);
10.1.8需要转格式读取
//转格式
ui->textEdit->setText(codec->toUnicode(array));
file.open(QIODevice::Append);//用追加的方式进行写
file.write("十多年佛山呢过分啊");
file.close();
10.1.9对文件进行关闭
file.close();
10.2写文件
file.open(QIODevice::Append);//用追加的方式进行写
file.write("十多年佛山呢过分啊");
file.close();
10.3读写文件全部代码
#include "widget.h"
#include "ui_widget.h"
#pragma execution_character_set("utf-8")//防止乱码
#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,"打开文件","E:\\杂七杂八\\长恨歌.txt");
//将路径放在lineEdit中
ui->lineEdit->setText(path);
//编码格式类
//QTextCodec *codec = QTextCodec::codecForName("gbk");
//读取内容放到textEdit中
//QFile默认支持的格式是utf-8
QFile file(path);//参数就是读取文件的路径
//设置打开方式
file.open(QIODevice::ReadOnly);//只读
//QByteArray array = file.readAll();
QByteArray array;
while(!file.atEnd())//文件尾的条件
{array += file.readLine();//按行读
};
//将读到的数据放入textEdit
ui->textEdit->setText(array);
//转格式
//ui->textEdit->setText(codec->toUnicode(array));
//对文件对象进行关闭
file.close();
//进行写文件
file.open(QIODevice::Append);//用追加的方式进行写
file.write("十多年佛山呢过分啊");
file.close();
});
}
Widget::~Widget()
{
delete ui;
}
10.4 QFlieInfo读取文件信息
QFileInfo info(path);
qDebug()<<"文件的大小:"<<info.size();
qDebug()<<"文件的后缀名:"<<info.suffix();
qDebug()<<"文件的名称:"<<info.fileName();
qDebug()<<"文件的路径:"<<info.filePath();
qDebug()<<"文件的创建日期:"<<info.created().toString("yyyy/MM/dd hh:mm:ss");
qDebug()<<"文件的最后修改日期:"<<info.lastModified().toString("yyyy/MM/dd hh:mm:ss");
11翻金币的案例
翻金币资源: https://pan.baidu.com/s/1EV-Wph01AKy69C3Orwqw2g#list/path=%2F
11.1创建项目 添加资源配置
创建一个项目,然后将所需要的资源添加进文件内
11.2项目配置设置背景 大小 标题 背景 图标
11.2.1配置大小、图标、标题、退出按钮
//配置主场景
//设置固定大小
setFixedSize(320,588);
//设置图标
setWindowIcon(QIcon(":/res/Coin0001.png"));
//设置标题
setWindowTitle("翻金币主场景");
//退出按钮的实现
connect(ui->actionquit,&QAction::triggered,[=](){
this->close();
});
11.2.2配置背景
//重写paintEvent事件 画背景图
void paintEvent(QPaintEvent *);
//重写paintEvent事件 画背景图
void MainScene::paintEvent(QPaintEvent *)
{
QPainter painter(this);
QPixmap pix;
pix.load(":/res/PlayLevelSceneBg.png");
painter.drawPixmap(0,0,this->width(),this->height(),pix);//背景拉伸满屏
//画背景上的图标
pix.load(":/res/Title.png");
pix = pix.scaled(pix.width()*0.5,pix.height()*0.5);//缩放图标
painter.drawPixmap(10,30,pix);
}
11.3创建开始按钮
11.3.1 封装自定义的按钮 MyPushButton
新建一个类为MyPushButton
主场景创建开始按钮
//开始的按钮
MyPushButton * startBtn = new MyPushButton(":/res/MenuSceneStartButton.png");
startBtn->setParent(this);
startBtn->move(this->width()*0.5-startBtn->width()*0.5,this->height()*0.7);
11.3.2构造函数(默认显示图片,按下后显示图片)
//构造函数 参数1,正常显示的图片路径 参数2,按下后显示的图片路径
MyPushButton(QString normalImg,QString perssImg="");
//成员属性 保存用户传入的默认显示路径 以及按下后显示的图片路径
QString normalImgPath;
QString pressImgPath;
MyPushButton::MyPushButton(QString normalImg, QString perssImg)
{
this->normalImgPath=normalImg;
this->pressImgPath =pressImgPath;
QPixmap pix;
bool ret =pix.load(normalImg);
if(!ret)
{
qDebug()<<"图片加载失败";
return;
}
//设置图片的固定大小
this->setFixedSize(pix.width(),pix.height());
//设置不规则图片样式
this->setStyleSheet("QPushButton{border:0px}");
//设置图标
this->setIcon(pix);
//设置图标大小
this->setIconSize(QSize(pix.width(),pix.height()));
}
11.3.3开始制作特效zoom1,zoom2
//弹跳特效
void zoom1();//向下跳
void zoom2();//向上跳
void MyPushButton::zoom1()
{
//创建一个动画对象
QPropertyAnimation * animation = new QPropertyAnimation(this,"geometry");
//设置动画时间间隔
animation->setDuration(200);
//起始位置
animation->setStartValue(QRect(this->x(),this->y(),this->width(),this->height()));
//结束位置
animation->setEndValue(QRect(this->x(),this->y()+10,this->width(),this->height()));
//设置弹跳曲线
animation->setEasingCurve(QEasingCurve::OutBounce);
//开始执行动画
animation->start();
}
void MyPushButton::zoom2()
{
//创建一个动画对象
QPropertyAnimation * animation = new QPropertyAnimation(this,"geometry");
//设置动画时间间隔
animation->setDuration(200);
//起始位置
animation->setStartValue(QRect(this->x(),this->y()+10,this->width(),this->height()));
//结束位置
animation->setEndValue(QRect(this->x(),this->y(),this->width(),this->height()));
//设置弹跳曲线
animation->setEasingCurve(QEasingCurve::OutBounce);
//开始执行动画
animation->start();
}
11.4创建选择关卡场景
创建一个选择关卡场景类
11.4.1点击开始按钮后延时进入到选择关卡场景
主场景添加:
ClooseLevelScene * chooseScene = NULL;
connect(startBtn,&MyPushButton::clicked,[=](){
qDebug()<<"点击了开始";
//做一个弹起的特效
startBtn->zoom1();
//做一个回弹特效
startBtn->zoom2();
//延时进入到选择关卡场景
QTimer::singleShot(200,this,[=](){
//进入到选择关卡场景中
//将自身隐藏
this->hide();
//显示选择关卡场景
chooseScene->show();
});
});
11.4.2 配置选择关卡场景(设置背景 大小 标题 背景 图标)
配置选择关卡场景的相关设置
//配置选择关卡场景
this->setFixedSize(320,588);
//设置图标
this->setWindowIcon(QPixmap(":/res/Coin0001.png"));
//设置标题
this->setWindowTitle("选择关卡");
//创建菜单栏
QMenuBar *bar = menuBar();
setMenuBar(bar);
//创建开始菜单
QMenu * startMenu = bar->addMenu("开始");
//创建退出的菜单项
QAction * quitAction = startMenu->addAction("退出");
//点击退出实现退出游戏
connect(quitAction,&QAction::triggered,[=](){
this->close();
});
配置背景图:
//重写paintEvent事件 画背景图
void paintEvent(QPaintEvent *);
//重写paintEvent事件 画背景图
void ClooseLevelScene::paintEvent(QPaintEvent *)
{
QPainter painter(this);
QPixmap pix;
pix.load(":/res/OtherSceneBg.png");
painter.drawPixmap(0,0,this->width(),this->height(),pix);//背景拉伸满屏
//画背景上的图标
pix.load(":/res/Title.png");
pix = pix.scaled(pix.width(),pix.height());//缩放图标
painter.drawPixmap(40,30,pix);
}
11.4.3创建返回按钮
/
/返回按钮
MyPushButton * backBtn = new MyPushButton(":/res/BackButton.png",":/res/BackButtonSelected.png");
backBtn->setParent(this);
backBtn->move(this->width()-backBtn->width(),this->height()-backBtn->height());
//点击返回
connect(backBtn,&MyPushButton::clicked,[=](){
qDebug()<<"点击了返回按钮";
});
11.4.4返回关卡的返回按钮特效切换
//重写按钮 按下 释放 事件
void mousePressEvent(QMouseEvent *e);
void mouseReleaseEvent(QMouseEvent *e);
void MyPushButton::mousePressEvent(QMouseEvent *e)
{
if(this->pressImgPath!="")//传入摁下图片非空,说明需要有按下状态,切图
{
QPixmap pix;
bool ret =pix.load(this->pressImgPath);
if(!ret)
{
qDebug()<<"图片加载失败";
return;
}
//设置图片的固定大小
this->setFixedSize(pix.width(),pix.height());
//设置不规则图片样式
this->setStyleSheet("QPushButton{border:0px}");
//设置图标
this->setIcon(pix);
//设置图标大小
this->setIconSize(QSize(pix.width(),pix.height()));
}
//让父类执行其他的内容
return QPushButton::mousePressEvent(e);
}
void MyPushButton::mouseReleaseEvent(QMouseEvent *e)
{
if(this->normalImgPath!="")//传入摁下图片非空,说明需要有按下状态,切为初始图片
{
QPixmap pix;
bool ret =pix.load(this->normalImgPath);
if(!ret)
{
qDebug()<<"图片加载失败";
return;
}
//设置图片的固定大小
this->setFixedSize(pix.width(),pix.height());
//设置不规则图片样式
this->setStyleSheet("QPushButton{border:0px}");
//设置图标
this->setIcon(pix);
//设置图标大小
this->setIconSize(QSize(pix.width(),pix.height()));
}
//让父类执行其他内容
return QPushButton::mouseReleaseEvent(e);
}
11.4.5 开始场景与选择关卡场景的切换
signals:
//写一个自定义的信号,告诉主场景,点击了返回
void chooseSceneBack();
//点击返回
connect(backBtn,&MyPushButton::clicked,[=](){
//qDebug()<<"点击了返回按钮";
//告诉主场景 我返回了 主场景监听ChooseLevelScene的返回按钮
//做一个延时的返回
QTimer::singleShot(200,this,[=](){
emit this->chooseSceneBack();
});
//监听选择关卡的返回按钮的信号
connect(chooseScene,&ClooseLevelScene::chooseSceneBack,this,[=](){
chooseScene->hide();
this->show();//重新显示主场景
11.5选择关卡按钮创建
11.5.1单个for循环创建矩阵
//创建选择关卡的按钮
for(int i=0;i<20;i++)//单个for循环写矩阵
{
MyPushButton * menuBtn = new MyPushButton(":/res/LevelIcon.png");
menuBtn->setParent(this);
menuBtn->move(25+i%4 * 70,130+i/4 * 70);
//监听每个按钮的点击事件
connect(menuBtn,&MyPushButton::clicked,[=](){
QString str = QString("您选择的是第 %1 关").arg(i+1);
qDebug()<<str;
});
11.5.2按钮上设置显示关卡数
QLabel * label = new QLabel;
label->setParent(this);
label->setFixedSize(menuBtn->width(),menuBtn->height());
label->setText(QString::number(i+1));
label->move(25+i%4 * 70,130+i/4 * 70);
//设置label上的文字对齐方式
label->setAlignment(Qt::AlignHCenter|Qt::AlignVCenter);//设置水平居中和垂直居中
//设置让鼠标进行穿透(51号属性)
label->setAttribute(Qt::WA_TransparentForMouseEvents);
}
11.6翻金币场景的基本配置
新建类PlayScene,注意选择QmainWindow
11.6.1配置游戏场景(设置背景 大小 标题 背景 图标)
与之前相同
11.6.2实现返回按钮可以返回上一场景
与之前相同
11.6.3实现显示关卡的label
//显示当前关卡数
QLabel *label = new QLabel;
label->setParent(this);
QFont font;
font.setFamily("仿宋");
font.setPointSize(20);
QString str1 = QString("Level:%1").arg(this->levelIndex);
//将字体设置到标签控件中
label->setFont(font);
label->setText(str1);
label->setGeometry(30,this->height()-50,120,50);
11.7创建金币类
11.7.1先将金币的背景图案放入PlayScene中
//显示金币的背景图案
for(int i = 0; i < 4 ; i++)
{
for(int j = 0; j < 4; j++)
{
//绘制背景图片
QLabel*label = new QLabel;
label->setGeometry(0,0,50,50);
label->setPixmap(QPixmap(":/res/BoardNode.png"));
label->setParent(this);
label->move(57+i*50,200+j*50);
}
}
11.7.2创建MyCoin自定义金币按钮类
//参数代表传入的金币路径 还是银币路径
MyCoin(QString btnImg);
MyCoin::MyCoin(QString btnImg)
{
QPixmap pix;
bool ret =pix.load(btnImg);
if(!ret)
{
QString str = QString("图片 %1 加载失败").arg(btnImg);
qDebug()<<str;
}
```c++
this->setFixedSize(pix.width(),pix.height());
this->setStyleSheet("QPushButton{border:0px;}");
this->setIcon(pix);
this->setIconSize(QSize(pix.width(),pix.height()));
```
}
构造函数中那个传入默认显示的图片金币
构造函数中那个传入默认显示的图片金币
11.7.3在playscene创建所有的金币按钮
//显示金币的背景图案
for(int i = 0; i < 4 ; i++)
{
for(int j = 0; j < 4; j++)
{
//绘制背景图片
QLabel*label = new QLabel;
label->setGeometry(0,0,50,50);
label->setPixmap(QPixmap(":/res/BoardNode.png"));
label->setParent(this);
label->move(57+i*50,200+j*50);
```c++
//创建金币
MyCoin * coin = new MyCoin(":/res/Coin0001.png");
coin->setParent(this);
coin->move(59+i*50,204+j*50);
}
}
```
11.8每个关卡的默认显示
引入dataConfig.h和dataConfig.cpp文件到项目中
在PlayScene中写了int gameArray[4][4]的数组 维护每个关卡的金币状态
初始化每个关卡的显示
11.9翻金币特效
11.9.1给每个硬币加属性 posx posy bool flag
/
/金币的属性
int posX;//X坐标位置
int posY;//Y坐标位置
bool flag;//正反标识
//给金币的属性赋值
coin->posX=i;
coin->posY=j;
coin->flag=this->gameARRAY[i][j];//1正面 0反面
11.9.2给MyCoin加函数
/
/改变标志的方法
void changeFlag();
QTimer *timer1;//正面翻反面定时器
QTimer *timer2;//反面翻正面定时器
int min = 1;
int max = 8;
//执行动画的标志
bool isAnimation = false;
//初始化定时器对象
timer1 = new QTimer(this);
timer2 = new QTimer(this);
void MyCoin::changeFlag()
{
//如果是正面翻转反面
if(this->flag)
{
//开始正面翻反面的定时器
timer1->start(30);
isAnimation = true;//开始做动画
this->flag =false;
}
else//相反
{
timer2->start(30);
isAnimation = true;//开始做动画
this->flag = true;
}
}
11.9.3监听信号并翻转
//监听正面翻反面的信号 并且翻转
connect(timer1,&QTimer::timeout,[=](){
QPixmap pix;
QString str = QString(":/res/Coin000%1.png").arg(this->min++);
pix.load(str);
this->setFixedSize(pix.width(),pix.height());
this->setStyleSheet("QPushButton{border:0px;}");
this->setIcon(pix);
this->setIconSize(QSize(pix.width(),pix.height()));
//判断 如果翻完了,将min重置为1
if(this->min>this->max)
{
this->min = 1;
isAnimation = false;
timer1->stop();
}
});
//监听反面翻正面的信号 并且翻转
connect(timer2,&QTimer::timeout,[=](){
QPixmap pix;
QString str = QString(":/res/Coin000%1.png").arg(this->max--);
pix.load(str);
this->setFixedSize(pix.width(),pix.height());
this->setStyleSheet("QPushButton{border:0px;}");
this->setIcon(pix);
this->setIconSize(QSize(pix.width(),pix.height()));
//判断 如果翻完了,将min重置为1
if(this->min>this->max)
{
this->max = 8;
isAnimation = false;
timer2->stop();
}
});
//点击金币 进行翻转
connect(coin,&MyCoin::clicked,[=](){
coin->changeFlag();
this->gameARRAY[i][j] = this->gameARRAY[i][j]==0?1:0;
});
11.9.4解决快速点击效果不好的问题
//重写 按下 和 释放
void mousePressEvent(QMouseEvent *e);
void MyCoin::mousePressEvent(QMouseEvent *e)
{
if(this->isAnimation==true)
{
return;
}
else
{
QPushButton::mousePressEvent(e);
}
}
11.9.5点击硬币周围一起翻转
MyCoin *coinBtn[4][4];
//将金币放入到 金币的二维数组中 以便以后的维护
coinBtn[i][j]=coin;
//点击金币 进行翻转
connect(coin,&MyCoin::clicked,[=](){
coin->changeFlag();
this->gameARRAY[i][j] = this->gameARRAY[i][j]==0?1:0;
//翻转周围硬币
QTimer::singleShot(300,this,[=](){
if(coin->posX+1<=3)//翻右侧金币
{
coinBtn[coin->posX+1][coin->posY]->changeFlag();
this->gameARRAY[coin->posX+1][coin->posY] = this->gameARRAY[coin->posX+1][coin->posY]==0?1:0;
}
//周围的左侧硬币翻转条件
if(coin->posX-1>=0)
{
coinBtn[coin->posX-1][coin->posY]->changeFlag();
this->gameARRAY[coin->posX-1][coin->posY] = this->gameARRAY[coin->posX-1][coin->posY]==0?1:0;
}
//上侧硬币翻转条件
if(coin->posY-1>=0)
{
coinBtn[coin->posX][coin->posY-1]->changeFlag();
this->gameARRAY[coin->posX][coin->posY-1] = this->gameARRAY[coin->posX][coin->posY-1]==0?1:0;
}
//下侧硬币翻转条件
if(coin->posY+1<=3)
{
coinBtn[coin->posX][coin->posY+1]->changeFlag();
this->gameARRAY[coin->posX][coin->posY+1] = this->gameARRAY[coin->posX][coin->posY+1]==0?1:0;
}
});
});
11.9.6判断胜利
playsence中 添加iswin标志判断是否胜利
//是否胜利的标志
bool isWin;
//判断是否胜利
this->isWin = true;
for(int i = 0 ; i < 4 ; i++)
{
for(int j = 0 ; j < 4 ; j++)
{
if(coinBtn[i][j]->flag==false)//只要有一个是反面
{
this->isWin = false;
break;
}
}
}
if(this->isWin == true)
{
//胜利了
qDebug()<<"游戏胜利";
//将所有按钮的胜利标志改为true,再次点击,直接return
for(int i = 0 ; i < 4 ; i++)
{
for(int j = 0 ; j < 4 ; j++)
{
coinBtn[i][j]->isWin=true;
}
}
}
将iswin的判断添加进来,如果全部为true,直接return
void MyCoin::mousePressEvent(QMouseEvent *e)
{
if(this->isAnimation||this->isWin==true)
{
return;
}
else
{
QPushButton::mousePressEvent(e);
}
}
11.9.7胜利图片设置
//胜利图片的显示
QLabel* winLable = new QLabel;
QPixmap tmpPix;
tmpPix.load(":/res/LevelCompletedDialogBg.png");
winLable->setGeometry(0,0,tmpPix.width(),tmpPix.height());
winLable->setPixmap(tmpPix);
winLable->setParent(this);
winLable->move((this->width()-tmpPix.width())*0.5,-tmpPix.height());
if(this->isWin == true)
{
//胜利了
qDebug()<<"游戏胜利";
//将所有按钮的胜利标志改为true,再次点击,直接return
for(int i = 0 ; i < 4 ; i++)
{
for(int j = 0 ; j < 4 ; j++)
{
coinBtn[i][j]->isWin=true;
}
}
//将胜利的图片砸下来
QPropertyAnimation * animation = new QPropertyAnimation(winLable,"geometry");
//设置时间间隔
animation->setDuration(1000);
//设置开始位置
animation->setStartValue(QRect(winLable->x(),winLable->y(),winLable->width(),winLable->height()));
//设置结束位置
animation->setEndValue(QRect(winLable->x(),winLable->y()+114,winLable->width(),winLable->height()));
//设置缓和曲线
animation->setEasingCurve(QEasingCurve::OutBounce);
//执行动画
animation->start();
}
11.9.8音效设置
QSound所属模块 multimedia 需要加载.pro文件中
QSound *startSound = new QSound(":/res/TapButtonSound.wav",this);
startSound->setLoops(-1);//设置循环,-1为无限循环
startSound->play();
11.9.9每个场景保持一个位置
开始进入下一个场景:
//设置choosescene场景的位置
chooseScene->setGeometry(this->geometry());
返回上一个场景,show之前写
this->setGeometry(chooseScene->geometry());
11.10项目打包及游戏扩展
debug改为release并运行
找到.exe,放在文件夹里,打开该位置命令符
找到QT里的bin里的windeployqt
在命令行输入windeployqt 文件名.exe运行
QT介绍
Qt [1] 是一个1991年由Qt Company开发的跨平台C++图形用户界面应用程序开发框架。它既可以开发GUI程序,也可用于开发非GUI程序,比如控制台工具和服务器。Qt是面向对象的框架,使用特殊的代码生成扩展(称为元对象编译器(Meta Object Compiler, moc))以及一些宏,Qt很容易扩展,并且允许真正地组件编程。
Qt Assistant(Qt 助手)
可配置且可重新发布的文档阅读器,可以方便地进行定制,并与Qt应用程序一起重新发布。
功能:
定制Qt Assistant并与应用程序一起重新发布
快速查找关键词,全文本搜索,生成索引和书签
同时为多个帮助文档或在应用程序中提供在线帮助
Qt Designer(Qt 设计师)
强大的跨平台GUI布局和格式构建器
功能:
使用拖放功能快速设计用户界面
定制部件或从标准部件库中选择部件
以本地外观快速预览格式
通过界面原型生成C++或Java代码
将QT Designer与Visual Studio或Eclipse IDE配合使用
使用Qt信号与槽机制构建功能齐全的用户界面
Qt Linguist(Qt 语言家)
提供一套加速应用程序翻译和国际化的工具
功能:
收集所有UI文本,并通过简单的应用程序提供给翻译人员
语言和字体感知外观
通过智能的合并工具快速为现有应用程序增加新的语言
Unicode编码支持世界上大多数字母
运行时可切换从左向右或从右向左的语言
在一个文档中混合多种语言
Qt creator创建项目
选择项目模板,文件→新建文件或项目(crtl+N) :Application →Qt Widgets Application→choose
输入项目信息, 项目介绍和位置 :设置项目名称 浏览:设置项目路径(项目名称和路径不能出现中文)
选择构建套件 (Kits) 设置 然后下一步
输入类信息,类信息定义类 设置好之后进行下一步
设置项目管理 设置之后点击完成
文件说明
项目建立完成之后会直接进入编辑模式
生成文件说明:
文件 说明
文件.pro 项目文件,包含项目相关信息
文件.pro.user 包含与用户有关的项目信息
文件.h 新建的类的头文件
文件.cpp 新建的类的源文件
main.cpp 包含了main()主函数
文件.ui 设计师设计的界面对应的界面文件
ui文件说明
双击文件.ui可以进入ui界面,进入设计模式
主设计区
用来设计界面以及编辑各个部件的属性
部件列表窗口
窗口分类罗列各种常用的标准部件,可以使用鼠标拖入主设计区,放到主设计区的界面
对象查看器
列出界面上所有的对象名称和父类,而且以树形结构显示了各个部件的所属关系,可以在这里单击对象选中该部件
属性编辑器
显示各个部件的常用属性信息,可以更改部件的一些属性。这些属性按照从祖先继承的属性、从父类继承的属性和自己属性的顺序进行了分类
动作编辑器与信号和槽编辑器
两个编辑器可以对相应的对象内容进行编辑。
常用功能图标
最上面前4个图标可以进入相应的模式,窗口部件编辑模式 信号/槽编辑模式 伙伴编辑模式 Tab顺序编辑模式 后面几个图标实现添加布局管理器以及调整大小等功能
程序运行
编译运行程序
使用快捷键Crtl+R或者通过左下角运行按钮来运行程序
构建项目生成的文件
当在Qt creator运行程序之后,会在目录生成一个Debug文件夹。是默认的构建目录。Qt creator将项目源文件和编译生成的文件进行了分类存放。
问题:直接运行可执行文件出现错误
双击运行Debug文件夹下的可执行文件,可能会出现系统错误
内容:无法启动此程序,计算机中丢失…,尝试重新安装该程序以解决此问题。
解决办法:添加环境变量,找到系统属性→环境变量→Path→新建→丢失文件的路径→确定
之后就可以运行可执行文件
程序的发布
程序编译完成之后,要发布程序,让程序在别人的计算机业同样可以运行,发布程序要使用release版本。
设置release格式:点击左下角的目标选择器将构建目标设置为release 单机运行图标,生成一个release文件夹
打包:将release文件夹中的.exe文件复制到一个打包文件夹里面,将Qt安装目录的bin目录中的libgcc_s_dw2-1.dll、libstdc+±6.dll、libwinpthread-1.dll、Qt5Core.dll、Qt5Gui.dll、Qt5Widgets.dll
动态编译\静态编译
在Qt Creator默认的情况下,编译的程序想要发布就需要包含dll文件的支持,这种编译方式称为动态编译
静态编译就是将Qt的库进行重新编译,用静态编译的Qt库来链接程序,这样生成的目标文件就可以直接运行,而不再需要dll文件的支持。不过生成的exe文件会很大,静态编译缺乏灵活性,也不能部署插件。
设置应用程序图标
创建.ico文件。将ico图标文件复制到工程文件夹中。 ico文件可以通过网上在线转换 将png等文件转换为ico
修改项目文件,在Qt creator中的编辑模式将文件.pro最后面添加一行代码
RC_ICONS = 图标名称.ico
1
RC_ICONS = 图标名称.ico
3.运行程序,在release文件夹中的exe文件查看是否更换图标,将这里换好图标的exe文件复制到程序发布文件夹中,就可以得到一个完整的程序
helloworld程序源码与编译过程详解
此模块通过不同的项目写方法来输出一个"HELLO WORLD! 你好Qt!"的对话框
纯代码编写程序与命令行编译
纯代码编写
测试过程:
第一步,新建空项目,打开Qt creator并新建项目,选择其他项目中的Empty qmake Project,将项目命名之后并设置路径。完成后,双击 .pro文件,添加一行代码
greaterThan(QT_MAJOR_VERSION,4):QT += widgets #如果Qt主版本大于4,则需要添加widgets模块
第二步,在项目中添加main.cpp文件,在项目文件列表中的项目文件夹上右击,选择"Add new" 然后选择C++ Source File,名称设置为main.cpp,后面保持默认即可。
第三步,编写源代码,向新建的main.cpp文件中添加如下代码:
#include <QApplication>
#include <QDialog>
#include <QLabel> #前三行是头文件包含,Qt中每一个类都有一个与其同名的头文件
int main(int argc,char *argv[]) #C++中常见的main()函数 有两个参数,接收命令行参数
{
QApplication a(argc,argv); #新建一个QApplication类对象,用于管理应用程序的资源,任何一个Qt Widgets程序都要有一个QApplication对象,因为Qt程序可以接收命令行参数,所以需要argc和argv两个参数。
QDialog w; #新建一个QDialog对象,QDialog类用来实现一个对话框界面
QLabel label(&w); #新建一个QLabel对象,并将QDialog对象作为参数,表明了对话框是它的父窗口,也就是说这个标签放在对话框窗口中。
label.setText("HELLO WORLD! 你好Qt!"); #给标签设置要显示的字符。
w.show(); #让对话框显示出来。
return a.exec();
}
第四步,编译运行。显示窗口小,更改代码
#include <QApplication>
#include <QDialog>
#include <QLabel>
int main(int argc,char *argv[])
{
QApplication a(argc,argv);
QDialog w;
w.resize(400,300); #修改对话框大小
QLabel label(&w);
label.move(120,120); #修改标签在对话框的位置
label.setText(QObject::tr("HELLO WORLD! 你好Qt!")); #QObject::tr()函数可以实现多语言支持,建议程序中所有要显示到界面上的字符串都使用tr()函数括起来。
w.show();
return a.exec();
}
实用功能
一、代码自动补全功能 打完开头几个字母出现相关的列表选项,可以直接查找。此外 比如想要打出setWindowTitle,可以直接输入swt三个字母来快速定位,然后Enter就可以完成输入
二、快速查看帮助,将鼠标指针放到一个类名或函数上,出现一个提示框显示简单介绍。按下F1可以在编辑器右边快速打开帮助文档。可以单机左上角的“切换到帮助模式”进入帮助模式。
命令行编译程序
命令行编译程序指不使用Qt creator,而是在其他的编辑器中编写源码,然后再到命令行去编译该程序。
测试过程:
第一步,新建工程目录。在Qt的安装目录创建一个文件夹(命名为工程名字)
第二步,在工程文件夹里面创建一个文本,将上面做的main.cpp的内容复制到文本里面,并将文本改为main.cpp
第三步,打开开始菜单找到Qt的命令提示符程序,从这里打开将Qt环境已经搭建好了,之后进入工程文件夹 (cd 绝对路径)
第四步,进入文件夹之后 输入 qmake -project 输入之后会在工程文件夹内生成一个工程文件夹名字.pro
第五步,通过文本程序打开.pro文件,在最后一行输入
greaterThan(QT_MAJOR_VERSION,4):QT += widgets
第六步,在命令提示符程序输入qmake ,之后会在文件夹生成release等文件夹,此时文件夹都是空的
第七步,在命令提示符程序输入mingw32-make命令来编译程序,编译完成后会在release目录中出现exe文件/
第八步,进入release文件夹(cd release),运行.exe文件,就会运行程序
这就是Qt程序编辑、编译和运行的整个过程。
使用.ui文件
使用.ui界面文件
测试过程:
第一步,添加.ui文件,在项目中左上角文件→新建文件或项目→文件和类→QT→Qt Designer Form→Dialog without Buttons→更改文件名称
第二步,设计界面,生成好文件便进入设计模式,在界面右边添加一个Label部件,拖入到中间对话框,并更改Label内容为”HELLO WORLD! 你好Qt!“,右边属性栏的geometry属性更改坐标位置。更改类对象,在右上角的类列表中选择QDialog类对象,之后在下面可以对其更改类对象名称
第三步,生成ui头文件,按下Crtl+S快捷键先保存更改,按下Crtl+2快捷键回到编辑模式,之后使用右下角锤子图标或者Crtl+Shift+B快捷键构建工程,然后本地项目文件夹会生成一个由ui文件生成的.h头文件
/********************************************************************************
** Form generated from reading UI file 'hellodialog.ui'
**
** Created by: Qt User Interface Compiler version 5.12.3
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/ #注释信息
#ifndef UI_HELLODIALOG_H #预处理指令 防止对这个头文件的多重包含
#define UI_HELLODIALOG_H #预处理指令 防止对这个头文件的多重包含
#include <QtCore/QVariant> #类的头文件
#include <QtWidgets/QApplication> #类的头文件
#include <QtWidgets/QDialog> #类的头文件
#include <QtWidgets/QLabel> #类的头文件
QT_BEGIN_NAMESPACE #Qt的命名空间的开始宏
class Ui_HelloDialog 定义了一个UI_HelloDialog类,类名就是前面更改的对话框类对象的名称前添加了"UI_"字符,这是默认的名字。
{
public:
QLabel *label; #定义了一个QLabel类对象的指针,这个就是在对话框添加的Label部件
void setupUi(QDialog *HelloDialog) #setupUi()函数用来生成界面。
{
if (HelloDialog->objectName().isEmpty()) #设置了对话框的对象名称
HelloDialog->setObjectName(QString::fromUtf8("HelloDialog")); #设置了对话框的对象名称
HelloDialog->resize(503, 346); #设置了窗口大小
label = new QLabel(HelloDialog); #创建了标签对象
label->setObjectName(QString::fromUtf8("label")); #设置了标签对象名称
label->setGeometry(QRect(150, 70, 191, 131)); #设置了标签大小和位置
retranslateUi(HelloDialog); #调用了retranslateUi()函数,这个函数下面5行进行了定义,实现了对窗口里的字符串进行编码转换的功能
QMetaObject::connectSlotsByName(HelloDialog); #调用了 QMetaObject类的connectSlotsByName()静态函数,使得窗口中的部件可以实现按对象名进行信号和槽的关联
} // setupUi
void retranslateUi(QDialog *HelloDialog)
{
HelloDialog->setWindowTitle(QApplication::translate("HelloDialog", "Dialog", nullptr));
label->setText(QApplication::translate("HelloDialog", "Hello World!\344\275\240\345\245\275QT!", nullptr));
} // retranslateUi
};
namespace Ui { #定义了命名空间Ui,其中定义了一个HelloDialog类,继承自Ui_HelloDialog类
class HelloDialog: public Ui_HelloDialog {};
} // namespace Ui
QT_END_NAMESPACE #Qt的命名空间的结束宏
#endif // UI_HELLODIALOG_H
第四步,更改main.cpp文件
include "ui_hellodialog.h" #头文件包含,ui_hellodialog.h中已经包含其他类的定义,只需要包含这个文件就可以 使用"<>"系统会到默认目录(编译器及环境变量、项目文件所定义的头文件寻找目录,包括Qt安装的include目录,这是标准方式,用双引号时,系统先到用户当前目录中查找要包含的文件,找不到在按标准方式查找。
int main(int argc,char *argv[])
{
QApplication a(argc,argv);
QDialog w;
Ui::HelloDialog ui; #使用命名空间Ui中的HelloDialog类定义了一个ui对象
ui.setupUi(&w); #使用setupUi()函数,并将对话框类对象作为参数,可以将设计好的界面应用到对象w所表示的对话框上
w.show();
return a.exec();
}
第五步,运行程序,可以看到和用纯代码编写和命令行编译相同的对话框窗口
在命令行编译ui文件和程序
测试过程:
第一步,新建工程目录,在C:/Qt目录中创建文件夹,然后将在使用.ui界面文件的hellodialog.ui和main.cpp复制过来
第二步,编译.ui文件,打开Qt的命令提示符程序,进入cd C:\Qt\刚才建立的文件夹名字
uic -o ui_hellodialog.h hellodialog.ui #生成.h文件
第三步,输入 qmake -project 输入之后会在工程文件夹内生成一个工程文件夹名字.pro,通过文本程序打开.pro文件,在最后一行输入
greaterThan(QT_MAJOR_VERSION,4):QT += widgets
第四步,在命令提示符程序输入qmake ,之后会在文件夹生成release等文件夹,此时文件夹都是空的
qmake
第五步,在命令提示符程序输入mingw32-make命令来编译程序,编译完成后会在release目录中出现exe文件/mingw32-make
第六步,进入release文件夹(cd release),运行.exe文件,就会运行程序
cd release
helloworld
第一步
next
next
next
next
对TextBrowser按钮添加信号槽即鼠标点击时间
对第二个按钮添加鼠标事件
构建
添加背景图片 改变背景颜色等资源
首先在自己的项目所在的路径下的文件夹里面新建一个文件夹(用来存放图片、音乐等资源)
NEXT
NEXT
TEXT
点击下一步 --- 下一步 -- 完成
NEXT
点击Add Files(每次增加图片都要重复此步骤需要执行构建才能把图片资源导入进去)
就会出现如下界面点击构建(图片命名不能有中文,否则会报错)
然后回到mainwindows.ui设计页面
(注释:这里有三个资源,根据自己选择)
成功哈哈哈哈
改变字体颜色
根据自己喜欢的颜色自行选择(每个label上的文字重复该操作就ok)
完成
构建运行
qt配置opencv
qt版本:Qt Creator 4.11.1 (Community)
opencv版本:opencv4.5.1
OpenCV
Download
OpenCV截止目前的最新版是4.5.1,链接:https://opencv.org/releases.html
cmake:CMake (cmake-gui)
前提是下载好这三个资源(建议到官网上下载避免编译出现其他错误)
首先在下载好的opencv文件下新建一个新的文件夹命名为new-build(用来存放编译后生成的新的opencv资源)
下载好opencv和qt后先配置其电脑环境变量,之前安装有的opencv环境变量先删除再执行cmake的编译否则编译不成功
打开cmake
等待
会出现爆红(不要怕)
找到WITH下的WITH-OPENGL和WITH-QT勾选重新点击Configure
避免编译出现其它错误我们需要在执行一个步骤
检查一下看看这个有没有勾选,如果勾选取消勾选
这个也要取消勾选
点击Configure,这是报红的就没了
点击Generate
此时编译成功
进入到opencv文件夹下的new-build文件双击打开
按住shift单击鼠标右键打开PowerShell
输入命令mingw32-make -j 8 回车
等待
等待完成后 输入命令: mingw32-make install
new-build文件夹下就会自动生成一个install文件
完成后进入到new-build文件夹下的install文件夹
添加到电脑的环境变量中就OK了