QT学习笔记
DAY1
04 创建第一个QT程序
QWidget是QMainWindow和QDialog的父类,其中QMainWindow多菜单栏,QDialog是一个对话框
.pro文件是“工程”文件
main.cpp初始文件解释
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//main程序入口 argc是命令行变量的数量 argv是命令行变量的数组
int main(int argc, char *argv[])
{
//a是应用程序对象,在Qt中,应用程序对象有且只有一个
QApplication a(argc, argv);
//窗口对象 myWidget父类 ->QWidget
myWidget w;
//窗口对象 默认不会显示,必须要调用show方法显示窗口
w.show();
//让应用程序对象进入消息循环机制
return a.exec();
}.pro文件的解释:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19QT += core gui //Qt包含的模块
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets //大于4版本以上包含widget模块
CONFIG += c++11
DEFINES += QT_DEPRECATED_WARNINGS
SOURCES += \ //源文件
main.cpp \
mywidget.cpp
HEADERS += \ //头文件
mywidget.h
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
05命名规范以及快捷键
myWidget.h文件的解释
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class myWidget : public QWidget
{
Q_OBJECT// Q_OBJECT宏,允许类中使用信号和槽机制
public:
myWidget(QWidget *parent = nullptr);//构造函数
~myWidget();//虚构函数
};
命名规范及快捷键myWidget.cpp文件解释
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
//命名规范
//类名 首字母大写,单词与单词之间首字母大写
//函数名 变量名称 首字母小写,单词和单词之间首字母大写
//快捷键
//注释 ctrl+/
//运行 ctrl+r
//编译 ctrl+b
//字体缩放 ctrl+鼠标滚轮
//查找 ctrl+f
//整行移动 ctrl+shift+↑或者↓
//帮助文档 F1
//自动对齐 ctrl+i
//同名之间的.h和.cpp切换 F4
//帮助文档:
//第一种方式 F1
//第二种方式 左侧按钮
//第三种方式 D:\QT_installer\install_data\5.14.2\mingw73_64\bin
myWidget::myWidget(QWidget *parent)
: QWidget(parent)
{
//创建第一个按钮
QPushButton *btn=new QPushButton;
//让btn对象依赖在myWidget窗口中
btn->setParent(this);
//显示文本
btn->setText("the first button");
//创建第二个按钮
QPushButton* btn2 =new QPushButton("the second button",this);
//移动btn2按钮
btn2->move(100,100);
//重置窗口大小
resize(600,400);
//设置固定的窗口大小
setFixedSize(600,400);
//设置窗口标题
setWindowTitle("the firt window");
}
myWidget::~myWidget()
{
}
06QPushButton创建
- 创建QPushButton* btn=new QPushButton
- 设置父亲 setParent(this)
- 设置文本 setText(“文字”)
- 设置位置 move(宽,高)
- 重新指定窗口大小 resize
- 设置窗口标题 setWindowTitle
- 设置窗口固定大小 setFixSize
1 | //按钮控件 |
07对象树
- 当创建的对象在堆区的时候,如果指定的父亲是QObject派生下来的类或者QObject子类派生下来的类,可以不用管理释放的操作,将对象会放入对象树中。
- 一定程度上简化了回收机制
08Qt中的坐标系
- 坐标体系:以左上角为原点,X轴向右增加,Y向下增加
09信号和槽-点击按钮关闭窗口
连接函数 connect
参数:
- 参数1 信号的发送者
- 参数2 发送的信号(函数的地址)
- 参数3 信号的接受者
- 参数4 处理的槽函数
松散耦合
实现点击按钮 关闭窗口的案例
1
2
3
4
//需求:点击我的按钮 关闭窗口
//参数1 信号的发送者 参数2 发送的信号(函数的地址) 参数3 信号的接受者 参数4 处理的槽函数
connect(myBtn,&QPushButton::clicked,this,&myWidget::close);
10自定义的信号和槽
自定义信号
写到signals下
返回值是void
- 需要声明,不需要实现
- 可以有参数,可以重载
自定义槽函数
写到public slot下,或者public或者全局函数
返回值是void
- 需要声明,需要实现
- 可以有参数,可以重载
触发自定义的信号
- emit 自定义的信号
案例:下课后,老师出发饿了信号,学生响应信号,请客吃饭(见文件the_second_day_learning)
11&12自定义的信号和槽发生重载的解决&信号连接信号
需要利用函数指针,明确指向函数的地址
```
void (Teacher::*teacherSignal)(QString)=&Teacher::hungry;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
+ QString转成char*
+ .ToUtf8()转为QByteArray
+ .Data()转为char *
+ 信号可以连接信号
+ 断开信号:disconnect
+ 拓展
+ 1、信号是可以连接
+ 2、一个信号可以连接多个槽函数
+ 3、多个信号可以连接同一个槽函数
+ 4、信号和槽函数的参数必须类型一一对应
+ 5、信号和槽的参数个数不需要一致,信号的参数个数可以多于槽函数的参数个数
### 13 Qt4版本信号槽连接
+ connect(信号的发送者,发送的信号 SIGNAL(信号),信号接受者,槽函数 SLOT(槽函数))
+ 优点 参数直观
+ 缺点 编译器不会检测参数类型
### 14 Lambda表达式
+ []标识符 匿名函数
+ =值传递
+ &引用传递
+ ()参数
+ {}实现体
+ mutable 修饰值传递变量,可以修改拷贝出的数据,改变不了本体
+ 返回值 [] ()->int{}
## DAY2
### 02 Qmainwindow_菜单栏和工具栏
+ QMainWindow
+ 菜单栏 最多有一个
```c++
//菜单栏创建
//菜单栏只有一个
QMenuBar* bar=menuBar();
//将菜单栏放入窗口中
setMenuBar(bar);
//创建菜单
//bar->addMenu("文件");
QMenu *fileMenu=bar->addMenu("文件");
QMenu *editMenu=bar->addMenu("编辑");
//创建菜单项
//fileMenu->addAction("新建");
QAction *newAction= fileMenu->addAction("新建");
//添加分隔符
fileMenu->addSeparator();
//fileMenu->addAction("打开");
QAction *openAction= fileMenu->addAction("打开");工具栏 可以有多个
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22//工具栏 可以有多个
QToolBar* toolBar=new QToolBar(this);
//addToolBar(toolBar);
addToolBar(Qt::BottomToolBarArea,toolBar);//第一个内容参考帮助文档
//后期设置 只允许 左右停靠
toolBar->setAllowedAreas(Qt::LeftToolBarArea|Qt::RightToolBarArea);
//设置浮动
toolBar->setMovable(true);
//设置移动(总开关)
toolBar->setMovable(false);
//工具栏中可以设置内容
toolBar->addAction(newAction);
//添加分割线
toolBar->addSeparator();
toolBar->addAction(openAction);
//工具栏中添加控件
QPushButton *btn=new QPushButton("aa",this);
toolBar->addWidget(btn);
03 QMainWindow_状态栏、铆接部件、核心部件
1 | //状态栏 最多有一个 |
04 资源文件添加
- 将图片文件拷贝到项目文件下
- 创建 右键项目->添加新文件->Qt->Qt resource File ->给资源文件起名字
- res生成res.qrc
- open in editor 编辑资源
- 添加前缀 添加文件
- 使用 “:+前缀名+文件名”
05 模态和非模态对话框创建
对话框分类
模态对话框(不可以对其他窗口进行操作)
非模态对话框(可以对其他窗口进行操作)
```c++
ui->setupUi(this); this->resize(1200,1400); //点击新建按钮 弹出一个对话框 connect(ui->actionnew,&QAction::triggered,[=](){ //对话框 分类 //模态对话框(不可以对其他窗口进行操作) 非模态对话框(可以对其他窗口进行操作) //模态创建 QDialog dlg(this); dlg.resize(800,1000); dlg.exec(); qDebug()<<"out"<<endl;
//非模态创建
QDialog* dlg2=new QDialog(this);
dlg2->resize(800,600);
dlg2->show();
dlg2->setAttribute(Qt::WA_DeleteOnClose);//55号 属性
qDebug()<<"out"<<endl;
});
1 |
|
07 其他标准对话框
- 颜色对话框 QColorDialog::getColor
- 文件对话框 QFileDialog::getOpenFileName(父亲,标题,默认路径,过滤文件)
- 字体对话框 QFontDialog::getFont
1 | //颜色对话框 没有加QColor函数默认是白色 |
08 登陆窗口布局
- 界面布局
- 实现登陆窗口
- 利用布局方式 给窗口进行美化
- 选取widget进行布局,水平布局,垂直布局,栅格布局
- 给用户名、密码、登陆、退出按钮进行布局
- 默认窗口和控件之间有9间隙,可以调整 layoutLeftMargin
- 利用弹簧进行布局
09 控件
- 按钮组
- QPushButton 常用按钮
- QToolButton 工具按钮 用于显示图片 如果想显示文字,修改风格:toolButtonStyle
- radioButton 单选按钮,设置默认:ui->rBtnMan->setChecked(true);
- checkBox 多选按钮,监听状态:2是选中 1是半选中 0是未选中
10 QListWidget控件
- QListWidget列表容器
- QListWidgetitem 一行内容
- ui->listWidget->additem(item);
- 设置居中方式item->setTextAlignment(Qt::AlignHCenter);
11 QTreeWidget树控件
设置头
- ```c++
ui->treeWidget->setHeaderLabels(QStringList()<<”英雄”<<”英雄介绍”);1
2
3
4
5
6
7
+ 创建根节点
+ ```
QTreeWidgetItem* liItem =new QTreeWidgetItem(QStringList()<<"力量");
QTreeWidgetItem* minItem =new QTreeWidgetItem(QStringList()<<"敏捷");
QTreeWidgetItem* zhiItem =new QTreeWidgetItem(QStringList()<<"智力");
- ```c++
添加根节点到树控件上
```c++
//加载顶层的节点ui->treeWidget->addTopLevelItem(liItem); ui->treeWidget->addTopLevelItem(minItem); ui->treeWidget->addTopLevelItem(zhiItem);
1
2
3
4
5
6
7
8
9
+ 添加子节点
+ ```c++
//追加子节点
QStringList heroL1;
heroL1 << "刚被猪" << "前排坦克,能在吸收伤害的同时造成可观的范围输出";
QTreeWidgetItem* l1 =new QTreeWidgetItem(heroL1);
liItem->addChild(l1);
12 QTableWidget控件
设置列数
- ```c++
//TableWidget控件//设置列数 ui->tableWidget->setColumnCount(3);
1
2
3
4
5
6
7
+ 设置水平表头
+ ```c++
//设置水平表头
ui->tableWidget->setHorizontalHeaderLabels(QStringList()<<"姓名"<<"性别"<<"年龄");
- ```c++
设置行数
- ```c++
//设置 行数 ui->tableWidget->setRowCount(5);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
+ 设置正文
+ ```c++
// //设置正文
// 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)));
// ui->tableWidget->setItem(i,col++,new QTableWidgetItem("18"));
//int 转QString
ui->tableWidget->setItem(i,col++,new QTableWidgetItem(QString::number(i+18)));
}
- ```c++
13 其它常用控件介绍
- stackedWidget控件:
- ui->stackedWidget->setCurrentIndex(1);
- 下拉框
- ui->comboBox->addItem(“奔驰”);
- QLabel 显示图片
- QLabel 显示动图
- 设置后要加movie->start();
DAY3
02 自定义控件封装
- 自定义控件封装
- 添加新文件 Qt-设计师界面类(.h .cpp .ui)
- .ui中 设计 QSpringBox 和QSlider 两个控件
- Widget中使用自定义控件,拖拽一个Widget,点击提升为,点击添加,点击提升
- 实现功能,改变数字,滑动条跟着移动,信号槽监听
- 提供getNum和setNum对外接口
- 测试接口
03 Qt中的鼠标事件
- 鼠标事件
- 鼠标进入事件 enterEvent
- 鼠标离开事件 leaveEvent
- 鼠标按下 mousePressEvent(QMouseEvent *ev)
- 鼠标释放 mouseReleaseEvent(QMouseEvent *ev)
- 鼠标移动 mouseMoveEvent(QMouseEvent *ev)
- ev->x() x坐标 ev->y() y坐标
- ev->button() 可以判断所有按键 Qt::LeftButton Qt::RightButton
- ev->buttons()判断组合按键 判断move时候的左右键 结合&操作符
- 格式化字符串 QString(“%1 %2”).arg(111).arg(222)
1 | myWidget::myWidget(QWidget *parent) : QLabel(parent) |
04 定时器1
- 利用时间 void timerEvent(QTimerEvent*ev);
- 启动定时器 startTimer(1000) 毫秒单位
- timerEvent的返回值是定时器的唯一表示 可以和ev->timerId作比较
1 | Widget::Widget(QWidget *parent) |
05 定时器2
- 利用定时器类Qtimer
- 创建定时器对象 QTimer *timer=new QTimer(this)
- 启动定时器 timer->start(毫秒)
- 每隔一定毫秒 发送信号timeout 进行监听
- 暂停timer->stop
1 | //定时器第二种方式 |
06 event事件分发器
- 用途:用于事件的分发
- 也可以做拦截操作,不建议
- bool event(QEvent* e)
- 返回值 如果是true 代表用户处理这个事件,不向下分发了
- e->type()==鼠标按下
07 事件过滤器
- 在程序将事件分发到事件分发器前,可以利用过滤器做拦截
- 步骤
- 给控件安装事件过滤器
- 重写eventFilter(obj,e)函数
08 QPainter 绘图
- 绘图事件 void Widget::paintEvent(QPaintEvent*)
- 声明一个画家对象 QPainter painter(this);
- 画线,画圆,画矩形,画文字
- 设置画笔 QPen 设置画笔宽度 风格
- 设置画刷 QBrush 设置画刷 风格
- 如果要刷新,那么用update()函数或者repaint()函数
1 | void Widget::paintEvent(QPaintEvent*) |
09 QPainter高级设置
抗锯齿 效率低
1
painter.setRenderHint(QPainter::Antialiasing);
对画家进行移动
1
painter.translate(100,0);
保存状态 save
还原状态 restore
如果想手动调用绘图时间 利用update
- 利用画家画图片 painter.drawPixmap(x,y,QPixmap””);
11 绘图设备
- QPixmap QImage QBitmap(黑白色) QPicture QWidget
- QPixmap对不同平台做了显示的优化
- QPixmap pix(300,300);
- pix.fill(颜色)
- 利用画家 往pix上画画
- 保存 pix.save(“路径”)
- QImage 可以对像素进行访问
- 使用和QPixmap差不多QImage img(300,300,QImage::Format_RGB32);
- 其他流程一样
- 可以对像素进行修改 img.setPixel(i,j,value);
- QPicture 记录和重现 绘图的指令
- QPicture pic
- painter.begin(&pic)
- 保存 pic.save(任意后缀名)
- 重现 利用画家可以重现 painter.drawPicture(0,0,pic);
12 QFile对文件进行读写操作
- QFile进行读写操作
- QFile file(path 文件路径)
- file.open(打开方式)
- 读
- 全部读取 file.readAll()
- 按行读 file.readLine()
- atend()判断是否读到文件尾
- 利用编码格式
- 写
- file.open()
- file.write()
13QFileInfo 读取文件信息
1 | //QFileInfo 文件信息类 |
补充
1 | QRect rect(10 * i + 100, 10 * j + 100, 10, 10); // 定义每个格子的位置和大小 |
1 | filename= QFileDialog::getOpenFileName(this,"打开文件","C:\\Users\\23861\\Desktop","(*.txt *.docx)"); |