Qt-QWidget中的属性和方法
控件简单概述
控件Wigdet,其实也就是小组件/小部件的意思,但是读作控件就显得非常专业了。
在Qt Designer中
这些都是Qt给我们内置好的类。
Qt中的各种控件都是继承自QWidget类,并且在QWidget这里可以看到控件的属性:
QWidget
QWidget中的属性和方法对Qt的各种控件都是有效的。
enabled属性
这个属性在右侧就可以看到,还是以一个QPushButton为例:
enabled属性描述了一个控件是否可用。
如果不可用,也就是禁用,关于禁用:
如果一个控件被禁用了,那么它不能再接收任何用户的输入事件,并且在外观上往往也是灰色的。
如果一个widget被禁用,那么它的子元素也将被禁用。
关于这个禁用操作有两个API:
对于验证这个enabled属性,我们可以进行如下实验:
设计两个按钮,一个按钮用来打印日志,另一个按钮则作为上一个按钮是否可用的开关。
这里顺便说下:
在Qt命名这里:
以数字的方式来命令显然是不太规范的,我们可以根据它的功能进行命名:
比如切换可用状态:
关于objectName的补充
图形上的按钮如下:
接着就来设计槽函数,使用图形化界面快速设置的方式
运行结果:
符合预期的。
geometry属性
geometry也就是几何的意思。
Qt这里的geometry其实就是四个属性的统称:
注意这里的y是向下的。
关于它的API
其中我们获取控件的位置和尺寸,返回的结果是一个QRect的对象,它里面就包含了刚刚的那四个属性,我们设置geometry的时候,既可以传入一个QRect,也可以把四个属性都传入。
关于传入QRect对象,我们使用值传入就可以了,因为QRect很小,所以也没必要用传指针或引用的方式。
这里再做一个实验:设计四个按钮,分别对应上下左右,每一次点击都能让一个目标控件进行对应方向的移动。
注意控件的命名规范。
然后设计槽函数:
运行
这里就发现了一个问题,我们移动控件的方式好像只是移动控件的左上角,这样会移动还会改变控件的尺寸。如果我们想要让控件进行一个整体的移动而不改变尺寸可以这样修改一下槽函数
运行效果
可以看到控件的尺寸就不再发生改变了。
另外还可以再做一个有意思的
对于欣然同意自然没什么好说的,对于残忍拒绝这个选项,我们可以设计成,只要鼠标点击了,但是还没有松开,这个选项就会在窗口内进行一个随机的移动。
那么这里我们选择的信号就不再是clicked的了,而是pressed
设计槽函数:
当然,我们在此之前还会先种下一棵随机数种子:
运行:
虽然对于残忍拒绝这个选项,更合理一点的设计就是:只要我们的鼠标刚碰到控件,甚至还没有点击,它就会随机移动,但是就需要用到Qt的事件机制了,这里就不多扩展了。
window frame 的影响
注意:
windowTitle属性
windowTitle属性是从属于QWigdet的,它只针对顶层窗口这样的QWigdet才有效。
如果不是顶层窗口,实际设置了也不会有效果:
windowIcon属性
windowIcon属性表示窗口的图标。
它有以下两种API:
并且需要注意的是,windowIcon跟windowTitle一样,只能对顶层窗口有效。
使用示例:
注意事项:
这里的目录不要带有中文。
另外,我这里用的是 / ,如果是 \ ,那么在C++中会被当作转义字符,这里需要注意。
还有,之前推荐使用堆来创建对象,主要是因为要确保这个控件的声明周期是足够的,而且可以通过对象树来进行释放。
但是QIcon自身是一个比较小的对象,它创建出来后就是要设置到某个QWigdet里的,QIcon对象释不释放都不影响图标的显示。并且QIcon也不支持对象树。
使用qrc文件管理资源
刚刚我们是使用绝对路径的方式引入图片的,但是这种方式是不科学的,因为我们的程序最终是要给用户去使用的,但是我们无法保证用户图片所在的路径和我们一致。
因此相比于使用绝对路径,使用相对路径是比较好的。
但是使用相对路径也还是有一个缺点,那就是用户可能会把图片给搞没了。
于是Qt中有一个qrc机制。
它主要解决了两个问题:
1.图片的路径可能与开发机上不一致。
2.图片可能会被用户丢失。
我们可以给Qt项目引入一个额外的 xml文件,后缀是.qrc,在这个xml中把图片资源导入进来,并且在xml中记录。Qt在编译项目时,会根据qrc中的图片信息,找到图片内容,然后提取出图片的二进制数据,把这些二进制数据转化为C++代码,最终编译到.exe中。
在安卓中也有类似的机制。
它的缺点就是:无法导入太大的资源,比如视频音频之类的几个GB大小的。
如果资源太大,就会导致程序的编译和运行速度都受到影响。
qrc的使用:
1.先创建一个qrc文件:
在我们已有的项目中,右键后点击新增文件
选择qrc文件:
后面起名字随便起。
创建好后是这样的:
首先看到这个 “添加前缀”:
这里我们直接将前缀改为 / 都行。
这里的前缀可以理解为 虚拟的目录。
添加好前缀后,就可以添加文件了。
注意,这个文件必须要在当前代码所在的目录或者其同级的子目录中才行
添加好后:
这样就说明成功了。
2.开始导入图片:
其中:
这个 : 就表示 我们要访问的是qrc文件,这个目录就是我们之前设置的qrc前缀。
我们qrc导入的这个图片资源,就会被转化成一个.cpp代码:
点进去一看
就是一些二进制数据。
帮我们创建了一个char数组。
windowOpacity属性
这个属性是用来调整窗口的透明度的。
它有以下常用的两个API
再做个简单的实验:设置两个按钮,一个按钮让窗口的透明度 + 0.1,另一个让窗口的透明度- 0.1,每次触发按钮时,打印以下当前的透明度。
我们每次让透明度减去0.1的时候,我们发现它每次都并不是精确的减去0.1。
这里我们需要知道:
, C++ 中 float 类型遵守 IEEE 754 标准, 因此在进⾏运算的时候会有⼀定的精度误差
一个浮点数分为三个部分:
1.符号位
2.有效数字
3.指数部分
其中有效数字使用二进制表示的,这里主要是小于1的部分。
比如第一位就是0.5,第二位就是0.25,第三位就是0.125,以此类推。
比如我们想要表示0.1,就要让这些有效数字进行相加,使其尽可能接近0.1。
在很多语言中:C/C++/Java/python 都是这样的。
这样的优点:运算速度快,占用空间小,CPU制造的时候会专门针对这种运算进行优化。
缺点:对于有些小数不能精确表示。
另外,在上述代码中还有一个问题,虽然对于透明度超过了[0,1]这个范围我们依旧可以设置,但是它不会生效,也不会报错,但是我们写代码的时候还是要尽量在设置前就进行一个判断。
这是防御编程中的double check思想。
cursor属性
这个属性就是关于,当我们的鼠标移动到该Widget上时,会显示对应的形状。
在Qt中已经有很多内置的光标形状了。
但是这些形状可能太古老了,不好看。
Qt还允许我们用自定义图片来设置光标。
这里同样可以使用qrc管理的方式导入图片
这里关于找到合适的图片,我们可以到阿里巴巴的矢量图标库中找,这是一个开源的网站。
选好心仪的图片并导入后,我们可以用QPixmap对象来加载自定义图片。
代码:
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
QPixmap pixmap(":/kunkun.png");
pixmap.scaled(60,60); // 可以等比例缩放
// 创建 QCursor 对象, 并指定 "热点" 为 (2, 2) 坐标位置.
// 所谓 "热点" 就是⿏标点击时⽣效的位置
QCursor cursor(pixmap,2,2);
// 最后给我们的按钮设置光标
ui->pushButton->setCursor(cursor);
}
Widget::~Widget()
{
delete ui;
}
注意我们平常关于光标还有一个热点的概念,热点就是我们鼠标点击时生效的位置。
font属性
在Qt设计者界面同样可以找到:
toolTip属性
有些GUI程序,它的页面 往往很复杂,为了方便使用者,当我们鼠标在某一个按钮上悬停的时候,就会出来一个提示。
focusPolicy属性
一般来说,一个控件获取到焦点,主要是两种方式:
1.鼠标点击
2.使用键盘上的tap
styleSheet属性
CSS 中可以设置的样式属性⾮常多. 基于这些属性 Qt 只能⽀持其中⼀部分, 称为 QSS (Qt Style Sheet)
比如我们创建一个lable
这个改变样式表就是设置样式。
这里是通过键值对的方式来进行设置的。
键和值之间用 : 分割,键值对和键值对之间用 ; 分割。
我们还可以用代码的方式来进行设置。
比如:我们用两个按钮,来更改窗口的夜间模式和日间模式。
代码;
void Widget::on_pushButton_light_clicked()
{
// 这是窗口的背景
this->setStyleSheet("background-color: 240,240,240;");
// 把文字设置为黑色,文本框的背景设置成默认的颜色
ui->plainTextEdit->setStyleSheet("background-color: 240,240,240; color: black;");
// 再设置按钮的样式
ui->pushButton_light->setStyleSheet("color: black;");
ui->pushButton_dark->setStyleSheet("color: black;");
}
void Widget::on_pushButton_dark_clicked()
{
// 这是窗口的背景
this->setStyleSheet("background-color: black;");
// 把文字设置为黑色,文本框的背景设置成默认的颜色
ui->plainTextEdit->setStyleSheet("background-color: black; color: white;");
// 再设置按钮的样式
ui->pushButton_light->setStyleSheet("color: white;");
ui->pushButton_dark->setStyleSheet("color: white;");
}
夜间效果:
在光学中,有一个三原色即:红绿蓝
计算机就是用的这种RGB的方式来表示颜色的。通常每一个颜色占一个字节。
它们每个颜色的取值范围就是[0,255],这样计算机就可以用不同比例来表示不同的颜色。
如果我们想知道某一个颜色它的三原色比例是什么,可以借助取色器这样的工具来帮我们。
在我们的画板中就可以看到取色器这个工具
我们对某一个元素一点:
然后就可以看到它的三原色比例了