windowTitle
API | 说明 |
---|---|
windowTitle() | 获取到控件的窗⼝标题. |
setWindowTitle(const QString& title) | 设置控件的窗⼝标题. |
注意!上述设置操作针对不同的widget可能会有不同的⾏为.
如果是顶层widget(独⽴窗⼝),这个操作才会有效.
如果是⼦widget,这个操作⽆任何效果.
代码⽰例:设置窗⼝标题
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
this->setWindowTitle("这是窗口标题");
}
Widget::~Widget()
{
delete ui;
}
#include "widget.h"
#include "ui_widget.h"
#include <QPushButton>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
this->setWindowTitle("这是窗口标题");
QPushButton* button = new QPushButton(this);
button->setText("按钮");
button->setWindowTitle("通过按钮设置窗口标题");
}
Widget::~Widget()
{
delete ui;
}
当前不应该给按钮设置windowTitle.但是实际设置了之后,没有任何效果,也没有报错此时“没有报错”这样的设定是不太科学的~
这一点,更希望当代码写出不科学的代码的时候,能够给一些报错提示~~
windowIcon
API | 说明 |
---|---|
windowIcon() | 获取到控件的窗⼝图标.返回QIcon对象. |
setWindowIcon(const QIcon& icon) | 设置控件的窗⼝图标. |
同windowTitle,上述操作仅针对顶层widget有效. | |
Qt把各种涉及到的相关概念,都封装成了类. Qlcon就表示一个图标 |
1)先在D盘中放⼀个图⽚,名字为rose.jpg
#include "widget.h"
#include "ui_widget.h"
#include <QIcon>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
// 设置图标
QIcon icon("d:/rose.jpg");
this->setWindowIcon(icon);
}
Widget::~Widget()
{
delete ui;
}
之前推荐使用堆来创建对象,主要是因为要确保当前的控件的生命周期是足够的.要通过Qt对象树来释放对象
Qlcon自身是一个比较小的对象
创建出来之后,就是要设置到某个QWidget里面,
Qlcon对象本身释放不释放,不影响图标最终的显示 Qlcon也不支持对象树.无法给他执行父对象.
注意:Windows下路径的分隔符可以使⽤ / 也可以使⽤ \ .但是如果在字符串中使⽤ \ ,需要写作转义字符的形式 \\
.因此我们还是更推荐使⽤ /
C++11中引l入了rawstring解决上述问题
字符串里不包含任何转义字符.(所有的字符都不会转义)
r("d:\rose.jpg")
通过绝对路径的方式引入图片是不科学的
你写的程序,最终是要发布到用户的电脑上的
你无法确保,你开发机上图片的路径和用户电脑上图片的路径完全一致!
实际开发中,我们⼀般不会在代码中通过绝对路径引⼊图⽚.因为我们⽆法保证程序发布后,⽤⼾的电脑上也有同样的路径.
如果使⽤相对路径,则需要确保代码中的相对路径写法和图⽚实际所在的路径匹配(⽐如代码中写作"./image/rose.jpg",就需要在当前⼯作⽬录中创建image⽬录,并把rose.jpg放进去).
绝对路径:以盘符(windows)或者以 / (Linux)开头的路径.
相对路径:以 . (表⽰当前路径)或者以 … (表⽰当前路径上级路径)开头的路径.其中 . 经常也会省略.相对路径的前提是需要明确"当前⼯作⽬录"
对于Qt程序来说,当前⼯作⽬录可能是变化的.⽐如通过Qt Creator运⾏的程序,当前⼯作⽬录是项⽬的构建⽬录;直接双击exe运⾏,⼯作⽬录则是exe所在⽬录.
所谓构建⽬录,是和Qt项⽬并列的,专⻔⽤来放⽣成的临时⽂件和最终exe的⽬录.
qrc机制
这个机制就是从根本上解决上述的两个问题
- 确保你的图片所在的路径在目标用户机器上存在
- 确保你的图片不会被用户搞没了
给Qt项目引l入一个额外的xml文件(后缀名使用.qrc表示)
在这个xml中把要使用的图片资源给导入进来,并且在xml中进行记录
Qt在编译项目的时候,就会根据grc中描述的图片信息,找到图片内容,并且提取出图片的二进制数据,把这些二进制数据转成C++代码.最终编译到exe里. qrc缺点:无法导入太大的资源文件比如搞几个GB这种视频文件,grc无能为力了~~
qrc⽂件是⼀种XML格式的资源配置⽂件,它⽤XML记录硬盘上的⽂件和对应的随意指定的资源名称.应⽤程序通过资源名称来访问这些资源.
在Qt开发中,可以通过将资源⽂件添加到项⽬中来⽅便地访问和管理这些资源.这些资源⽂件可以位于qrc⽂件所在⽬录的同级或其⼦⽬录下.
在构建程序的过程中,Qt会把资源⽂件的⼆进制数据转成cpp代码,编译到exe中.从⽽使依赖的资源变得"路径⽆关".
这种资源管理机制并⾮Qt独有,很多开发框架都有类似的机制.例如Android的Resources和AssetManager也是类似的效果
代码⽰例:通过qrc管理图⽚作为图标
1)右键项⽬,创建⼀个Qt Resource File(qrc⽂件),⽂件名随意起(不要带中⽂)此处叫做resource.qrc .
2)在qrc编辑器中,添加前缀.
所谓的“前缀”可以理解成虚拟的目录,
这个目录没有在你的电脑上真实存在,是Qt自己抽象出来的
qrc 机制本质上就是把 图片 的二进制数据,转成C++代码.(最终就会在代码中看到很大的 char 数组,里面就是图片的二进制数据)
为了方便Qt代码中访问到这个图片,Qt就自己抽象出了 虚拟的目录~~
3)在资源编辑器中,点击 add Files 添加资源⽂件.此处我们需要添加的是rose.jpg
这个按钮在创建prefix之前是禁用的创建好prefix之后就可以使用了.
添加的文件就是添加到prefix下面的
注意:添加的⽂件必须是在qrc⽂件的同级⽬录,或者同级⽬录的⼦⽬录中.因此我们需要把之前D盘中的rose.jpg复制到上述⽬录中.
添加完毕后,可以在资源编辑器中看到添加好的⽂件
4)在代码中使⽤rose.jpg
#include "widget.h"
#include "ui_widget.h"
#include <QIcon>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
// 设置图标
// QIcon icon("d:/rose.jpg");
QIcon icon(":/rose.jpg");
this->setWindowIcon(icon);
}
Widget::~Widget()
{
delete ui;
}
当代码中需要访问qrc中管理的文件时,就需要在路径上带有:前缀
注意上述路径的访问规则.
- 使⽤ : 作为开头,表⽰从qrc中读取资源.
- / 是上⾯配置的前缀
- rose.jpg 是资源的名称
需要确保代码中编写的路径和添加到qrc中资源的路径匹配.否则资源⽆法被访问(同时也不会有报错提⽰).
qrc 中导入的图片资源,就会被转成这个 qrc_resource.cpp 这个c++代码
这里的字节内容就是rose.jpg里的每个字节的数据
当 Qt 项目进行编译的时候,这个cpp 文件就被一起编译到了exe 中. 当exe程序运行的时候,上述图片的数据也就被加载到内存中了.
上述代码其实就是通过unsigned char数组,把rose.jpg中的每个字节都记录下来.这些代码会被编译到exe中.后续⽆论exe被复制到哪个⽬录下,都确保能够访问到该图⽚资源.
上述qrc这⼀套资源管理⽅案,优点和缺点都很明显.
优点:确保了图⽚,字体,声⾳等资源能够真正做到"⽬录⽆关",⽆论如何都不会出现资源丢失的情况.
缺点:不适合管理体积⼤的资源.如果资源⽐较⼤(⽐如是⼏个MB的⽂件),或者资源特别多,⽣成的最终的exe体积就会⽐较⼤,程序运⾏消耗的内存也会增⼤,程序编译的时间也会显著增加.
windowOpacity
API | 说明 |
---|---|
windowOpacity() | 获取到控件的不透明数值.返回float,取值为0.0->1.0其中0.0表⽰全透明,1.0表⽰完全不透明. |
setWindowOpacity(float n) | 设置控件的不透明数值. |
代码⽰例:调整窗⼝透明度
1)在界⾯上拖放两个按钮,分别⽤来增加不透明度和减少不透明度.
objectName分别为 pushButton_add 和 pushButton_sub
2)编写wdiget.cpp,编写两个按钮的slot函数
- 点击 pushButton_sub 会减少不透明度,也就是窗⼝越来越透明.
- 点击 pushButton_add 会增加不透明度,窗⼝会逐渐恢复
void Widget::on_pushButton_add_clicked()
{
float opacity = this->windowOpacity();
if (opacity >= 1.0){
return;
}
qDebug() << opacity;
opacity += 0.1;
this->setWindowOpacity(opacity);
}
void Widget::on_pushButton_sub_clicked()
{
float opacity = this->windowOpacity();
if (opacity <= 0.0){
return;
}
qDebug() << opacity;
opacity -= 0.1;
this->setWindowOpacity(opacity);
}
IEEE754标准
规定了浮点数要使用二进制科学计数法的方式来表示~~
把一个浮点数分成三个部分:
1)符号位 2)有效数字 3)指数部分
使用二进制表示的有效数字~
而且这里是小于0的小数部分 (默认整数部分是1)
第一个有效数字位表示0.5 第二个有效数字位表示0.25
第三个表示0.125 101 => 0.625 0.1这样的小数
由于float和double有效数字部分长度都是有限的~ 导致无法凑出一个非常非常接近0.1这样的数字
很多编程语言
C/C++, Java, Python, Go… 都是这套体系~~
优点:运算速度快,占用空间小
(CPU制造的时候针对这种运算专门优化的) 缺点:对于有些小数无法精确表示~~
平时写代码,千万不能把两个浮点数直接使用==
进行比较! 0.1 + 0.2 == 0.3 false!!!
正确写法,作差,判定差的绝对值小于预期误差范围~
后续工作中编写代码的时候,尤其是涉及到一些需要精确计算的场景,比如算钱~~ 一定要慎重使用float/double!!!
上述代码中,在进行设置之前,先判定了opacity的范围.然后再决定是否要设置,这个判定其实可以不写.为啥我们仍然要写上??
这里加了判定条件
实际上如果不加这样的条件,代码也是ok的
超过1.0的数字设置不进去(setWindowOpacity内部也进行了判定)
<代码大全〉就进行了详细的讨论~~
"防御性编程’
别人犯错了,不会对咱们自身构成太大的伤害~~
很多时候写代码的时候,往往是要把一个大的项目拆分成几个部分/模块~~由不同的人负责分别完成模块之间要进行交互.往往模块A提供API(函数,类)给模块B调用
你在使用别人提供的API来进行调用的时候,你是否要对传入的参数进行检查呢?
比如你要传一个实参,你也不知道这个参数是否是一个NULL指针. 是否应该在调用函数之前就对这个指针进行判空呢??
cursor
API | 说明 |
---|---|
cursor() | 获取到当前widget的cursor属性,返回QCursor对象. 当⿏标悬停在该widget上时,就会显⽰出对应的形状. |
setCursor(const QCursor& cursor) | 设置该widget光标的形状.仅在⿏标停留在该widget上时⽣效. |
QGuiApplication::setOverrideCursor(const QCursor& cursor) | 设置全局光标的形状.对整个程序中的所有widget都会⽣效.覆盖上⾯的setCursor设置的内容. |
代码⽰例:在QtDesigner中设置按钮的光标
1)在界⾯中创建⼀个按钮.
在右侧属性栏可以直接设置cursor属性
修改为十字
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
QCursor cursor(Qt::WaitCursor);
ui->pushButton->setCursor(cursor);
}
Widget::~Widget()
{
delete ui;
}
可以使指针移动到按钮上的时候变为等待状态
系统内置的光标形状如下:
Ctrl+左键点击 Qt::WaitCursor 跳转到源码即可看到.
代码⽰例:⾃定义⿏标光标
1)创建qrc资源⽂件,添加前缀 / ,并加⼊ huaji.jpg
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
//创建⼀个位图对象, 加载⾃定义光标图⽚
QPixmap pixmap(":/huaji.jpg");
//缩放图⽚为 100 * 100 的尺⼨
pixmap = pixmap.scaled(100, 100);
//构造光标对象
QCursor cursor(pixmap, 10, 10);
//设置光标
this->setCursor(cursor);
}
Widget::~Widget()
{
delete ui;
}
QCursor cursor(pixmap);
这个默认情况下,鼠标点击时,相当于图片的左上角在进行点击
QCursor cursor(pixmap, 10, 10);
热点所在的位置
以图片左上角为0,0原点,找到10,10 这个位置作为鼠标真正点击的位置了.
pixmap = pixmap.scaled(100, 100);
通过这个函数对图片进行缩放
注意缩放不是修改图片对象本身,而是返回一个新的图片对象副本