QT学习笔记
1.对象树:在Qt中,每个 QObject 内部都有一个list,用来保存所有的 children,还有一个指针,保存自己的parent。当它自己析构时,它会将自己从parent的列表中删除,并且析构掉所有的children。
我们需要显试删除(就是用DELETE删除)的对象是那些使用NEW创建的并且没有父对象的对象(切记是new的才要delete,通过成员函数获得的对象,没有特殊说明的,千万不要随便delete.)。如果我们在删除一个对象的父对象之前删除它,QT会自动地从它的父对象的子对象列表中移除它的
2.什么是回调函数?
回调函数就是把函数的地址作为参数传入另一个函数
回调函数就是一个通过函数指针调用的函数。
① 函数指针的作用:首先,函数指针可以在不同时间传递不同函数的地址,即在不同的时间使用不同的函数,如果不用函数指针只能顺序执行函数。
注:信号与槽的槽函数中使用匿名函数或函数指针时时可以考虑使用兰姆达表达式。
QT资源文件使用格式:
“:+前缀+文件名”
QtMainWindow
MenuBar是菜单栏,toolbars是工具栏,Dock Widgets是小窗口,Central Widget是中央窗口,Status Bar是状态栏
QWidget QMainWindow QDialog类的区别:
QWidget类是所有用户界面对象的基类。 窗口部件是用户界面的一个原子:它从窗口系统接收鼠标、键盘和其它事件,并且在屏幕上绘制自己的表现。每一个窗口部件都是矩形,并且它们按Z轴顺序排列的。一个窗口部件可以被它的父窗口部件或者它前面的窗口部件盖住一部分。
QMainWindow 类提供一个有菜单条、锚接窗口(例如工具条)和一个状态条的主应用程序窗口。主窗口通常用在提供一个大的中央窗口部件(例如文本编辑或者绘制画布)以及周围菜单、工具条和一个状态条。QMainWindow常常被继承,因为这使得封装中央部件、菜单和工具条以及窗口状态变得更容易。继承使创建当用户点击菜单项或者工具条按钮时被调用的槽成为可能。你也可以使用Qt设计器来创建主窗口。
QDialog类是对话框窗口的基类。对话框窗口是主要用于短期任务以及和用户进行简要通讯的顶级窗口。QDialog可以是模式的也可以是非模式的。QDialog支持扩展性并且可以提供返回值。它们可以有默认按钮。QDialog也可以有一个QSizeGrip在它的右下角,使用setSizeGripEnabled()。
QDialog 是最普通的顶级窗口。不被嵌入到一个父窗口部件的窗口部件被叫做顶级窗口部件。通常情况下,顶级窗口部件是有框架和标题栏的窗口(尽管如果使用了一定的窗口部件标记,创建顶级窗口部件时也可能没有这些装饰。)在Qt中,QMainWindow和和不同的QDialog的子类是最普通的顶级窗口。摘自CSDNQWidget,QMainWindow和QDialog的区别ikahn的博客-CSDN博客qmainwindow和qdialog
模态和非模态对话框
非模态对话框是对话框后面的其他对话框或窗口依然可用
模态对话框是对话框后面的其他对话框或窗口不能操作 只能先操作当前的对话框
如果从线程角度来讲,模态对话框实际上是线程阻塞的,也就是子对话框是一个线程,但是在创建这个子线程之后,父窗口就阻塞了;而非模态对话框则不是阻塞型的线程模型,父子线程可以并行运行。
过程:
1 新建一个dialog
2 利用dialog 成员函数 指定窗体大小 显示窗体(非模态)
3 模态:
方式1 :exec()函数 阻塞函数 如果没有关闭窗口 程序会停在这里不会向下运行
方式2 :dialog成员函数 setModal(true) 再显示窗体
需要继续加一个函数delete相应的New(因为只有主窗体关闭时才自动释放 子窗口创建的对话框需要手动释放)
dialog->setAttribute(Qt::WA_DeleteOnClose)
8种标准对话框:
功能 按下按键弹出对应的对话框(颜色对话框、文件对话框、字体对话 框、输入对话框)
1 利用信号与槽的操作,右键UI中的按键创建出槽函数,填充即可
2 颜色对话框需要包含头文件QColorDialog
在槽函数中实现颜色对话框 用类创建一个对象
静态函数方式实现:QColor color = QColorDialog::getColor(Qt::red,this);
qDebug显示一下color
3 在槽函数中实现文件对话框 文件对话框需要包括QFileDialog
搜索手册发现他也是有静态成员函数,省去了用类创建对象再调用函数的过程
与上面类似,QString filename = QFileDialog::getOpenFileName(this,"OpenFile(显示内容)",“C:\”,"图片文件(*.png *.jpg)");
qDebug显示一下
4 字体对话框 include
与上面一样,函数为getFont(bool类型的指针,this); 返回QFont类型的变量
if(ok)
ui->pushButton_3->setFont(返回的变量);
5 输入对话框
仿照上面的写法 静态成员函数有好几个 手册上可以看
例如getText(this,“输入的title”,"提示",QLineEdit::Normal,"什么都不敲显示的默认字符",bool类型的是否敲入);返回值QString类型变量
测试输入整数getInt(...)
6 消息对话框
question函数 问题对话框
information函数: 提示对话框
warning函数:警告对话框
critical函数:错误对话框
about函数:关于对话框
7 进度对话框
定义指针的话,需要开辟空间,只有mainWindow关闭的时候才会回收空间
创建对象的话,函数结束对象就结束了。对象的构造函数里要加一些东西
成员函数:setWindowTitle("string") 窗口名设置
show() 显示 setWindowModality(Qt::WindowModal)变为模态
prodlg.setValue(i)
if(prodlg.wasCanceld()) break;
prodlg.setValue(50000) 输出结束
多线程:大文件复制拷贝时,可以继续做其他的事情。增加函数调用,QCoreApplicaion::processEvents();
8 错误信息对话框
创建对象 不对 (why? 因为创建对象的话函数结束就释放了,再点击一次相当于重新创建对象,无法保存上次的设置)
用指针开辟空间 把其放在mainWindow里
9 向导对话框
16 按钮控件组 button
控件和布局学习
Buttons是一个按键组,
push Button 过。
(1)tool button 工具按钮,多以图形或图标方式出现,如QQ头像。
流程:1 添加资源文件 加一张图片 把图片加到tool button按钮上
2.代码方式添加:ui->toolButton->setIcon(QIcon(":+前缀+文件名"))
3.添加文本并更改显示方式(toolButtonStyle)
4.autoRise
(2) Radio Button,选择相关按钮 几选一,有点像投票的选项(单选)
运行时有默认选项功能(代码实现)
ui->radioButton(也可以改成别的)->setCheck(true);
流程:一年级 二年级 三年级 分数分档次, 选中<60分时用信号和槽的功能实现打印信息 不及格
(3) Group Box
用来分组
(4) check Box 多选
List Widget 列表选择
Item views(model-based)适用于大量数据的操作
Item Widgets(item-based)比较简单
代码:
listWidget 添加内容,用addItem或addItems函数
addItem(指针or字符串)
用QListWigetItem指针方式的构造函数
(List是一个容器)
文字对齐:指针->setTextAlignment() 助手中查看该函数的使用方法
用addItems()函数 一次添加多行
Tree Widget
1 创建列:
代码实现:ui->treeWigdet->setHeaderLabel()
用到QStringList 可以试试创建匿名对象
2 创建树
代码:ui->treeWidget->addTopLevelItem();
用到QTreeWidgetItem 指针
3 添加图标 setIcon
4 添加分支 指针->addChild();
Table widget控件
建立控件 √
设置行列(setColumnCount/setRowCount) √
设置头标签(setHorizontalHeaderLabels) √
填充内容(setItem) 用循环 先填第一列 再填后边的列 通过QString类里的number函数将int类转换为字符串
Containers控件
Group Box 分组
Scroll Area 滚动区域
Tool Box 类似QQ分组
Tab Widget 类似选项卡
Stacked Widget 栈 可以把其他控件放在里边 QStackedWidget提供了一个控件栈,在这个栈中,一次只能显示一个控件。
用按键切换的方式换页复习一下兰姆达表达式的相关知识 实现按钮信号与槽的功能 输出一些字。再实现按下按钮切换到相应页面的功能 (setCurrentIndex函数)
InputWidgets控件
combo box 下拉列表 通过addItem函数添加选项
Font Combo Box 选择字体 信号与槽实现字体的选择
LineEdit 一行 用于输入姓名或者密码之类
Text Edit 和Plain Text Edit的区别:TE可以编辑字体 设计格式 PTE是单纯的文字没有别的
SpinBox、DoubleSpinBox: 数字增减
TimeEdit、DateEdit、Date/Time Edit 设置时间、年月日。例如:显示系统时间,利用setTime函数 需要创建一个QDateTime类型的对象,这个对象用该类里的函数currentDateTime()
Dial :旋钮 改变数值
H/V scroll Bar 水平条和纵向条
H/V Silder 调整值
自定义控件
1 添加Qt设计师界面类 widget
2 ui中添加widget容器 右键提升为 添加上面创建的类的名称
3 关联两个控件:
4.添加按键 获取当前值
添加函数 返回ui->spinBox中的value值 用信号与槽关联按钮与自定义的控件
Label控件
功能:1 显示字符串
2 显示图片信息setPixmap 改变图片大小:setScaledContents
3 添加动图 setMovie 显示动图 对象->start
事件 --鼠标事件
1 捕获事件是否产生:通过调用QApplication里对象a的函数a.exec()
2 事件过滤
3 事件分发
4 事件处理
先声明 再定义鼠标点击事件
常用鼠标处理事件:
mousePressEvent
mouseReleaseEvent
mouseDoubleClickEvent
例如:双击时设置为全屏 用到函数windowState
全屏:Qt::WindowFullScreen
设置窗体状态:setWindowState()
mouseMoveEvent
wheelEvent
定时器
两种使用方法:
方法一:
1 包含头文件QTimer 然后创建一个该类型的指针 开辟空间
2 函数使用start设置定时时间
3 connect设置联系 用到QTime::timeout,和兰姆达表达式 设置label里的内容 +1
方法二:(事件)
用定时器的事件,事件到来时用定时器处理函数
1 调用函数startTimer(定时时间) 该函数返回一个timer的编号 可以利用返回值用到不同的timer
2 重新编写timerEvent函数 同上
3 在类中设置不同的timer id 然后考虑两种不同时长情况下的变化
事件分发
个性化处理
串口调试助手
功能:1.软件打开时识别出可用串口 放在下拉列表中
第一步:在pro文件中加入 QT +=serialport
第二步:添加头文件
第三步:设计UI 显示串口号
第四步:代码初始化。设置窗口大小、设置标题
第五步:由于软件运行时要周期性扫描,因此定义一个定时器,创建定时器指针,定时,再利用信号和槽实现。需要定义一个函数,做为槽函数。
第六步:槽函数设计:foreach关键字 按顺序遍历容器中的所有成员
foreach(容器里边的类型,容器名字)
发现当前可用串口信息:QSerialPortInfo::availablePorts()
类型:QSerialPortInfo 容器:上边的列表
此时完成了遍历串口信息,然后通过portName得到串口名字 该函数返回Qstring类型
创建一个QStringList类型的容器,把名字放进这个容器里 初始时清空
然后把该容器添加到comboBox里
定义一个QStringList的对象 赋初值0 然后判断一下当前串口数量和上次的是否相等 不相等再执行添加的功能
功能2:
点击打开串口 设置下面的参数 再点击关闭串口
1 转到槽 编写槽函数
两种情况 第一种情况是按键内容=打开串口
在头文件里声明一个私有变量 类型是SerialPort* 用其创建一个串口
设置串口名字 setPortName(comboBox里的当前串口名字currentText)
设置波特率:setBaudRate 需要先把字符转换为整型再填进去 用到toInt函数
设置数据位:setDatabits 用switch case语句根据不同情况选择不同枚举类型
设置奇偶校验:setParity 此时用currentIndex+swich case
停止位设置:setStopBits 仿照之前的写法
打开串口:open(读写)如果打开失败 使用QMessageBox消息对话框(记得包含头文件)弹出消息,information(this,"错误提示",“串口打开失败”,QMessageBox::OK)
最后打开后设置所有参数不能修改 用setEnable(false)
把当前的文本设置为关闭窗口
第二种情况 串口已经处于打开状态
直接用close函数
把setEnable(false)都改为true
设置文本
优化:添加初始参数默认值
用setCurrentIndex
如何添加功能让串口受到数据
1 UI界面创建:
添加label 接收设置
checkBox 接收方式 ASCII码(默认选中 用setCheckState函数)、十六进制、暂停 (只能选中一个)
添加TextEdit 接收数据 发送数据
Label 接收字节:0 发送字节:0
2 创建信号和槽 connect(串口, readyRead, this, )
槽函数编写:(重点)
serialPort_readyRead()
首先判断当前模式(暂停,ASCII,16进制)
如果当前不是暂停,就读取全部串口数据 函数:readAll 用字符串类型接收
用字符串里的Length函数看收到了多少字节数据 放到一个long类型的整型数据里,在当前的label里显示(注意+=);
如果当前模式是16进制,
优化:
问题 怎么收完一组后换行??
如果当前模式是ASCII,
最后设置txetEdit显示即可
优化:读取前一轮数据,并追加到当前显示中
发送功能
1 UI创建按钮 发送 转到槽 编写槽函数
2 提取要发送的内容 toPlainText 放到一个字符串中
3 用串口的函数write 需要把字符串类型转换为QByteArray类型。用到toLatin1函数
4 计算发送的字节长度 用lenth函数 +=一个值 然后label中显示
5 添加清空接收区和清空发送区的功能