每天更新一点点点点。。。(个人笔记)
第一天:
按照下面这个链接配置了visual studio2019+qt但是在单独使用qt creator创建好工程后没有头文件和主函数,但是visual studio中是正常的。(但是哔站教程是基于qt creator 的。。。)
具体:
创建一个project
1.//创建一个桌面qt应用,包含基于qt的主窗体
New——>Applicaion——>Qt Widgets Application——>choose
2.//项目名称和位置
ps:名称和路径下不能有中文
3.//Details——>构建窗口类——>基类
基类:QWidget 基本窗口
QMainWindow 包括菜单栏和状态栏
QDialog 包含对话窗
4.//Kits——>选择套件(windows/安卓/其他版本)
5.Summary——>版本控制系统(多人协作项目时需要)
svn vss git
6.完成!
nice 报错了.....
//报错原因:没有头文件和源文件
解决:
1. 在创建文件路径时,选择的路径有中文名........ 路径重新改完试了一次还是这样
2. 网上说缺少MainGW,仔细一想确实没装,可以通过MaintencanceTool.exe安装,但是需要登录账号 (由于之前关网装的,没有账号,于是卸载重新安装了一遍qt5.15.)
下载链接:Index of /qt/linguist_releases/ | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror
或者可以参考下面这个链接,用了镜像源据说快一些Qt5.15.2安装_qt5.15.2安装教程-优快云博客
漫长的下载.....
下载完还有漫长的解压,啊?????//环境配置真的是最痛苦的
安装好后,终于好了
************************************************************************
显示一个基本的窗口
基本文件代码:
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow> //包含头文件 QMainWindow窗口类
class MainWindow : public QMainWindow
{
Q_OBJECT //宏 允许类中使用信号和槽的机制
public:
MainWindow(QWidget *parent = nullptr); //构造函数
~MainWindow();
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
}
MainWindow::~MainWindow()
{
}
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
//a应用程序对象,在QT中,应用程序对象有且仅有一个
QApplication a(argc, argv);
//窗口对象
MainWindow w;
//w窗口进行显示
w.show();
//代码进入消息循环,除非点 × 才会关闭
return a.exec();
}
工程文件代码(自动更改,不需要手动修改):
QT += core gui //Qt包含的模块
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets //大于4版本以上qt包含widgets模块
CONFIG += c++11
# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \ //源文件
main.cpp \
mainwindow.cpp
HEADERS += \ //头文件
mainwindow.h
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
P06:QPushButton创建
一般创建在窗口类的构造函数中
mainwindow.cpp
#include "mainwindow.h"
#include"qpushbutton.h"
//命名规则
//类名首字母大写,单词和单词之间首字母大写
//函数名 变量名称 首字母小写,单词和单词之间首字母大写
//快捷键
//注释 ctrl+/
//运行 ctrl+r
// 编译 ctrl+b
// 字体缩放 ctrl+鼠标滚轮
// 查找 ctrl+f
//整行移动 ctrl+shift + ↑或↓
//帮助 左侧帮助按钮 或E:\qt5.15\5.15.2\mingw81_64\bin\assistant
//自动对齐 ctrl+i
//同名cpp与h文件切换 F4
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
//创建一个按钮
QPushButton*btn1=new QPushButton;
//让btn对象 依赖在MainWindow窗口中
btn1->setParent(this);
//按钮大小设置
btn1->setFixedSize(80,30);
//显示文本
btn1->setText("button1");
//创建第二个按钮
//窗口大小与控件一致
QPushButton*btn2=new QPushButton("button2",this);
//重置窗口大小
resize(600,400);
//移动第二个按钮
btn2->move(100,200);
//设置窗口名称
setWindowTitle("窗口1");
}
MainWindow::~MainWindow()
{
}
运行结果
汉字乱码解决方案:
删除之前代码中中文,在工具中找到外部
点配置,在文本编辑器中找到——》行为——》默认编码——》选择 UTF8——》应用——》确定
关闭QT,删除工程目录下.pro.user文件,重新打开.pro文件,输入中文,重新运行:
完美解决!
析构时会依次释放new创建的内存
P07:对象树
创建一个C++类
1.右键工程名,添加新文件,选择c++类文件,输入类名,选择要继承的父类
2.输入MyPushButton创建 我的按钮类 ,继承父类改为PushButton
3.可以在头文件中声明析构函数
4.在源程序文件中进行定义
Qt用qDebug类中qDebug() 函数进行输出。
5.在mainwindow中进行我的按钮的定义
6.显示如下
new出的对象在堆区,只要是QObject的子类,就会自动释放内存,将对象放在对象树中,一定程度上简化了内存回收机制。
构造时,从上向下,析构时相反。
P08:Qt的窗口坐标系
move(200,0);
P09:信号和槽
connect(信号的发送者,发送的具体信号,信号的接受者,信号的处理(槽))
信号槽的优点,松散耦合﹐信号发送端和接受端本身是没有关联的,通过connect连接将两端耦合在一起
//需求:点击按钮2,关闭窗口
//参数1 信号发送者 参数2 信号(signals)类型(函数地址) 参数3 信号接收者 参数4 处理的槽(slots)函数(函数地址)
connect(btn2,&QPushButton::clicked,this,&QMainWindow::close);
connect(myBtn,&MyPushButton::clicked,this,&QWidget::close);
P10:自定义信号和槽函数
自定义信号写在 signals下,只需要头文件中声明不需要实现,返回值是void,可以有参数,可以发生重载。
自定义槽函数需要声明和实现。高级版本可以写在public下或者全局函数;早期必须写在public slots下;返回值是void,可以有参数,可以发生重载;
P11:函数重载时需要函数指针明确指向函数地址
void(Teacher::*tSignal)(Qstring)=&Teacher::hungry;
Qstring转char*
.ToUtf8()转为QByteArray
.Data()转为Char*
P12:信号可以连接信号
1.点击按钮触发下课:
设置一个下课按钮,并与下课信号相连接。下课信号会触发老师饿了,并且想吃宫保鸡丁。老师饿了与学生请吃饭函数相连接。
2.用无参数信号连接信号
老师饿了连接学生请吃饭函数,然后用点击按钮信号连接lao
3.断开信号:disconnect()
disconnect(zt,teacherSignal2,st,studentSlot2);
P13:一个信号可以连接多个槽函数;
多个信号可以连接一个槽函数;
信号和槽函数参数类型必须一一对应;
信号和槽的参数个数 是不是要一致?信号参数可以多于槽函数参数,类型要一一对应;
Qt4以前版本连接信号和槽
connect(zt,SIGNAL(hungry(),st,SLOT(treat()));
Qt4版本优点:参数直观;缺点:参数类型不做检测;
Qt5以上版本支持4的写法,反之不支持。
P14:Lambda表达式(c++11后的版本直接用)
//[]为一个Lambda的开始,写“=”表示值传递;“&”表示引用传递;为空时表示没有使用任何函数对象参数;“a”表示只有a可以按值传递,其他的看不到;
//“&a”表示只有a可以按引用传递;“=,&a,&b”除a和b按照引用之外,其他按照值传递;“&,a,b”除a和b按照值之外,其他按照引用传递;
// [btn](){
// btn->setText("aaa");
// }();
//最后的()表示引用
//mutable 修改拷贝,不修改本体
//
// QPushButton*myBtn1=new QPushButton("按钮1",this);
// QPushButton*myBtn2=new QPushButton("按钮2",this);
// myBtn1->move(200,100);
// myBtn2->move(200,0);
// int m=10;
// connect(myBtn1,&QPushButton::clicked,this,[m] ()mutable { m=100+10;qDebug() << m;});
// connect(myBtn2,&QPushButton::clicked,this,[=] () {qDebug()<<m;});
// qDebug()<<m;
//->返回值类型,表示函数返回值类型
//int ret=[]()->int{return 1000;}();
// QDebug()<<"ret="<<ret;
//利用Lambda表达式,实现点击按钮关闭窗口,可以实现两个返回值类型不一致的函数的连接,this可以省略
QPushButton*btn2=new QPushButton("关闭",this);
btn2->move(0,300);
//connect(btn2,&QPushButton::clicked,this,&Widget::close);
connect(btn2,&QPushButton::clicked,this,[=](){
this->close();
emit zt->hungery("宫保鸡丁");
//Lambda表达式最常用方法:[=](){}
p15与p16为回顾与总结。。。。
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
第二天:
P17:菜单栏、工具栏设置
创建工程:QMainWindow
mainwindow.cpp:
#include "mainwindow.h"
#include<QMenuBar>
#include<QToolBar>
#include<QDebug>
#include<QPushButton>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
//重置窗口大小
resize(640,480);
//创建菜单栏 最多只能有一个
QMenuBar * bar=menuBar();
//将菜单栏放入屏幕中
setMenuBar(bar);
//创建菜单栏
//bar->addMenu("文件");
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);
// QToolBar * toolBar2=new QToolBar(this);
// addToolBar(Qt::RightToolBarArea,toolBar2);
//后期设置 只允许左右停靠
toolBar->setAllowedAreas(Qt::LeftToolBarArea|Qt::RightToolBarArea);
//设置不浮动
toolBar->setFloatable(false);
//设置移动,false时以上设置都作废
toolBar->setMovable(false);
//工具栏中设置内容
toolBar->addAction(newAction);
toolBar->addSeparator();
toolBar->addAction(openAction);
//工具栏中添加控件->按钮
QPushButton *btn=new QPushButton("aa",this);
toolBar->addWidget(btn);
}
MainWindow::~MainWindow()
{
}
P18:设置状态栏、核心窗口、浮动窗口:
//状态栏 最多一个
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);
小结:只能有一个的用set,可以添加多个的用add
P19:资源文件添加
利用拖动构件 搭建基础界面
添加工具栏构件时,可以将菜单栏展开项添加的名称拖到工具栏,展开项无法直接输入中文,可以先输入英文,再选中,在右下角text属性中进行修改为中文。
资源文件添加:
为Qt界面添加图片作为工具栏选项:
代码实现(绝对路径):actionnew为拖拽控件时Qt系统产生的控件名称
ui->setupUi(this);
ui->actionnew->setIcon(QIcon("E:/image/pic.png"));
时为解决绝对路径不方便移植到其他设备上的问题:将图片整体复制,点击下图explore显示打开工程路径,粘贴到该路径下:
右键工程,选择添加文件,按下图选择资源文件添加:
资源文件起个名字:
.qrc为qt资源文件后缀:
右键.qrc文件,在editor中打开。点击添加->前缀(做区分),点击添加->文件加入图片,点击编译(右下角的小锤子)。
资源文件应用:
方法1:
//使用Qt添加资源":+前缀名+文件名"
ui->actionnew->setIcon(QIcon(":/pic1.png"));
方法2:
打开ui编辑界面
icon旁边进行点击,选择资源,选取一张图像,加入成功!
P20:对话框:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include<QDialog>
#include<QDebug>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
resize(640,480);
//点击新建按钮,弹出一个对话框
connect(ui->actionnew,&QAction::triggered,[=](){
//对话框分为:
//模态对话框(打开后不可以对其他窗口进行操作)和非模态对话框(打开后可以对其他窗口进行操作)
//模态创建
// QDialog dlg(this);
// dlg.resize(640,480);
// dlg.exec();//阻塞
// qDebug()<<"模态对话框弹出";
//非模态创建
// QDialog dlg2(this);
// dlg2.show(); //匿名函数中,栈上执行完后就会删除掉
//指针:堆区存放 防止一闪而过
QDialog *dlg2=new QDialog(this);
dlg2->resize(640,480);
dlg2->show(); //普通显示
dlg2->setAttribute(Qt::WA_DeleteOnClose);//关闭时就释放掉,防止内存泄露
qDebug()<<"非模态对话框弹出";
});
}
MainWindow::~MainWindow()
{
delete ui;
}
P21 消息对话框
//消息对话框
//错误对话框
// QMessageBox::critical(this,"critical","错误");
//信息对话框
//QMessageBox::information(this,"information","information");
//提问对话框
//参数1:父亲 参数2:标题 参数3:提示语 参数4:按键名称 (参数5:默认关联回车按键)
//返回值也是standerdbutton 可以用于判断用户哪个按键按下
// if (QMessageBox::Save == QMessageBox::question(this,"question","question",QMessageBox::Save|QMessageBox::Cancel,QMessageBox::Cancel))
// {
// qDebug()<<"save";
// }
// else
// {
// qDebug()<<"cancel";
// }
//警告对话框
//QMessageBox::warning(this,"warning","warning");
P22 其他对话框
//其他对话框
//颜色对话框 返回值为颜色RGB参数QColor color
// QColor color = QColorDialog::getColor(QColor(255,0,0));
// qDebug()<<"r="<<color.red();
//文件对话框
//参数1:父亲 参数2:对话框名称 参数3:默认打开位置 参数4:显示的文件格式 返回值为:路径 string格式
// QString str=QFileDialog::getOpenFileName(this,"打开文件","F:\\","(*.txt)");
// qDebug()<<str;
//字体对话框
bool flag;
QFont font=QFontDialog::getFont(&flag,QFont("华文彩云",36));
qDebug()<<"字体"<<font.family().toUtf8().data()<<"字号"<<font.pointSize()<<"是否加粗"<<font.bold()<<"是否斜体"<<font.italic();
P23 界面布局
将控件放入widget、修改widget布局为:垂直、水平或栅格,加入弹簧控制位置和控件间距(界面的放大缩小需要加入这个使得界面具有“弹性”)。
控件:
按键是:PushButton
用户名、密码字样是:label
输入框是:QLineEdit
从上向下依次是布局和弹簧,弹簧拖入即可固定位置。想固定大小可以通过修改size type得格式为fixed,再改变大小。。。。默认都是expanding的。
结果:
P24:控件—按钮组
QPushButton
常用按钮,一般用来显示文字
Tool button
允许加入icon图像,并在图像旁边显示文字(修改风格ToolButtonStyle实现文字显示),autoRise实现透明突起效果
Radiobutton
单选按钮,两个组合配合GroupBox可以实现只许选一个
Check box
组合配合GroupBox可以运行多选(默认为全选) 2是选中,0未选
打开属性中QCheckBox的tristate 会出现半选状态,半选选中输出为1