前言
作者:小蜗牛向前冲
名言:我可以接受失败,但我不能接受放弃
如果觉的博主的文章还不错的话,还请点赞,收藏,关注👀支持博主。如果发现有问题的地方欢迎❀大家在评论区指正
目录
一、什么是控件
二、QWidget属性
1、什么是QWidget
2、Qwidget核心属性
2.1、enabled
2.2、geometry
2.3、windowTitle
2.4、windIcon
2.5、windowOpacity
本期学习:学习控件的基础常识,对部分Qwidget的核心部分进行学习enable,geometry,window-Tilte,windowIcom,windowOpacity。
一、什么是控件
Widget是Qt中的核⼼概念.英⽂原义是"⼩部件",我们此处也把它翻译为"控件"控件是构成⼀个图形化界⾯的基本要素
上面图中的标识,我们都可以称为控件,在QT中控件的学习是非常重要的,所以我们要学习和掌握它。
在下面我们会学习到上图的一些控件,大家可以结合上图,对应去理解,当我第一次看前面这张图的时候不大脑还是懵逼的,学完之后豁然开然。
当我们打开Qt Creator的时候会有一个Forms文件夹,里面会有我们的widget.ui文件存放我们的相关控件
理解控件可以从两个方面来考虑:
视觉方面:控件是用户界面上可见的元素,它们有各种不同的外观和样式,用于呈现信息、接收输入或执行操作。例如,按钮控件用于触发操作,文本框控件用于接收用户输入,标签控件用于显示文本等等。
功能方面:控件具有各种功能,例如响应用户输入、发出信号、执行操作等。通过连接控件的信号(例如点击按钮时发出的信号)和槽(用于处理信号的函数),可以实现控件之间的交互和应用程序逻辑。
二、QWidget属性
1、什么是QWidget
在Qt中,QWidget(窗口部件)是所有可视化控件的基类,它提供了基本的用户界面功能。QWidget本身可以作为一个容器,用于包含其他控件,也可以作为一个可视化控件直接显示在用户界面上。
因此,QWidget可以被看作是控件的基础,它提供了控件所需的基本功能,如绘制、事件处理、布局管理等。其他更具体的控件,如按钮、文本框、标签等,通常都是从QWidget派生出来的特定类。
因此,可以说QWidget是控件的基类,而其他各种控件则是从QWidget派生出来的具体实现。
2、Qwidget核心属性
2.1、enabled
从字面意思理解,有激活的意思,主要控制控件是否可以被使用。
相关API
API | 说明 |
isEabled | 获取到控件的可⽤状态 |
setEabled | 设置控件是否可使⽤ true 表⽰可⽤,false 表⽰禁⽤ |
对于禁用其实非常好理解,就是该控件不在接收任何用户的输入,外观是灰色的,鼠标点击是没有任何反应的(如果点击控件本身可以触发信息的话)。
代码示例: 通过按钮2切换按钮1的禁⽤状态
核心代码:
Widget.cpp
void Widget::on_pushButton_clicked()
{
qDebug() << "按下按钮";
}
void Widget::on_pushButton_2_clicked()
{
bool flag = this->ui->pushButton->isEnabled();
this->ui->pushButton->setEnabled(!flag);
}
其中
2.2、geometry
对于geometry控件,我们要理解其核心属性:
x:横做标
y:纵坐标
width:宽度
height:高度
这里我们要注意的是 对于Qt的坐标系,是"左⼿坐标系".其中坐标系的原点是当前元素的⽗元素的左上⻆。
在图形用户界面编程中,窗口通常作为父元素,而窗口中的控件(如按钮、文本框、标签等)作为子元素。父元素(窗口)负责管理和布局这些子元素
但是实际开发中,我们并不会直接使⽤这⼏个属性,⽽是通过⼀系列封装的⽅法来获取/修改.
常用API
API | 说明 |
geometry() | 获取控制的位置(x,y)和尺寸(width,hight),返回类型是QRect,包含了x,y,width,height的属性 |
setGeometry(QRect) setGeometry(int x,int y, int wideh,int hight) | 设置控件的位置和尺寸,可以直接设置⼀个QRect,也可以分四个属性单独设置 |
例子演示:⼀个表⽩程序
在widget,cpp中,添加slot(槽函数)
void Widget::on_pushButton_clicked()
{
ui->label->setText("太好了,一起去玩吧!!!");
}
void Widget::on_pushButton_2_clicked()
{
//获取窗口的高度和宽度
int width = this->geometry().width();
int height = this->geometry().height();
//重新生成按键的位置
int x = rand()%width;
int y = rand()%height;
//重新设置位置
ui->pushButton_2->move(x,y);
}
这里只有点接受,就会打印出一下一句话,拒绝的话,按键就会随机移动造成点不到的现象。
对于窗口信息来说果widget作为⼀个窗⼝(带有标题栏,最⼩化,,最⼤化,关闭按钮),那么在计算尺⼨和坐标的时候就有两种算法.包含window frame和不包含window frame
其中frameGeometry是带window frame(窗口包含标题栏,最小化,最大化等),
geometry是不带window frame(也就是不包含标题栏,最小化,最大化等)
简单来说,frameGeometry
是窗口在屏幕上的总体占位,而 geometry
(是在客户端)是窗口内部。
为了更好的理解geometry和frameGeometry的区别
在界⾯上放置⼀个按钮
在按钮的slot函数中,编写代码
void Widget::on_pushButton_clicked()
{
QRect rect1 = this->geometry();
QRect rect2 = this->frameGeometry();
qDebug() << rect1;
qDebug() << rect2;
}
在构造函数中,也添加同样的代码
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
QRect rect1 = this->geometry();
QRect rect2 = this->frameGeometry();
qDebug() << rect1;
qDebug() << rect2;
}
执⾏程序,可以看到,构造函数中,打印出的geometry和frameGeometry是相同的.
但是在点击按钮时,打印的geometry和frameGeometry则存在差异.
在构造函数中
- 构造函数执行时:此时窗口尚未显示,它的位置和尺寸可能还没有被窗口管理器完全处理。因此,
geometry()
和frameGeometry()
返回相同的值,通常是因为窗口还没有被分配一个框架(标题栏和边框)。在这个阶段,窗口的位置和大小仅仅是你在代码中设置的,或者是由 Qt 的默认布局决定的(如果没有明确设置)。在按钮点击事件中
- 点击按钮执行时:此时窗口已经被完全创建并显示出来,窗口管理器已经应用了框架,这包括标题栏和边框等。这时,
geometry()
返回的是窗口内容区域的大小和位置,而frameGeometry()
返回的是包括窗口框架的整体大小和位置。因此,两者出现差异是因为窗口框架被包括在内。如何理解这些差异?
geometry():返回窗口的客户区(内容显示区)的几何信息,不包括窗口的边框和标题栏。
frameGeometry():返回包括窗口边框和标题栏在内的整个窗口的几何信息。
这种设计允许开发者能够精确控制窗口内容的布局,同时也能够处理涉及整个窗口尺寸和位置的操作,如窗口的拖动和调整大小。
最佳实践
初始化和布局:通常,最好在窗口显示后(例如在
show()
或showMaximized()
调用之后)查询和操作窗口的几何属性,这样可以确保窗口管理器已经应用了所有的框架和布局设置。- 事件处理:在处理如点击等事件时,根据需要查询
geometry()
或frameGeometry()
,以获取最准确的窗口状态信息。
2.3、windowTitle
这个控件非常简单,就是获取控件的窗口标题
API | 说明 |
windowTitle() | 获取到控件的窗⼝标题. |
setWindowTitle(const QString&title) | 设置控件的窗⼝标题. |
代码⽰例:设置窗⼝标题
修改widget.cpp
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
// 设置窗⼝标题
this->setWindowTitle("这是标题");
}
执⾏效果
2.4、windIcon
这个控件是获取控件的图标
API | 说明 |
windowIcon() | 获取到控件的窗⼝图标.返回QIcon对象. |
setWindowIcon(const QIcon&icon) | 设置控件的窗⼝图标. |
那这个有什么用呢,其实上面说的和我将在下面为大家分享的控件无非是为了让用户界面变的更好看。比如这里我们可以通过这个windowIconAPI将窗口界面改的更加好看,比如下面我们通过调用将控件的图标变成了一朵花。
这朵花,其实是一个资源,他要被系统调用 ,肯定要知道他的路径在那里。
对于路径可以分为相对路径和绝对路径。
绝对路径: 以盘符(windows)或者以 / (Linux)开头的路径.
相对路径: 以 . (表⽰当前路径)或者以 .. (表⽰当前路径上级路径)开头的路径.其中 . 经常也
会省略.相对路径的前提是需要明确"当前⼯作⽬录".
实际开发中,我们⼀般不会在代码中通过绝对路径引⼊图⽚.因为我们⽆法保证程序发布后,⽤
户的电脑上也有同样的路径。
所以我们在开发的过程中,往往会引入相对路径。则需要确保代码中的相对路径写法和图⽚实际所在的路径匹配(⽐如代码中写作"./image/rose.jpg",就需要在当前⼯作⽬录中创建image⽬录,并把rose.jpg放进去).
在qt中为了保证:
- 你要使用的图片的路径是在目标用户机器上存在的
- 保证改不图不会被用户随意删除
引入了一个qrc机制。
qrc⽂件是⼀种XML格式的资源配置⽂件,它⽤XML记录硬盘上的⽂件和对应的随意指定的资
源名称.应⽤程序通过资源名称来访问这些资源.
在Qt开发中,可以通过将资源⽂件添加到项⽬中来⽅便地访问和管理这些资源.这些资源⽂件
可以位于qrc⽂件所在⽬录的同级或其⼦⽬录下
在构建程序的过程中,Qt会把资源⽂件的⼆进制数据转成cpp代码,编译到exe中.从⽽使依赖的资源变得"路径⽆关".
代码⽰例:通过qrc管理图⽚作为图标
右键项⽬,创建⼀个QtResourceFile(qrc⽂件),⽂件名随意起(不要带中⽂),此处叫做resource.qrc
在qrc编辑器中,添加前缀.
所谓的前缀,可以理解成"⽬录".这个前缀决定了后续我们如何在代码中访问资源
在资源编辑器中,点击 add Files 添加资源⽂件.此处我们需要添加的是device.jpg
注意:添加的⽂件必须是在qrc⽂件的同级⽬录,或者同级⽬录的⼦⽬录中.因此我们需要把之前D盘中的device.jpg复制到上述⽬录中
添加完毕后,可以在资源编辑器中看到添加好的⽂件
编辑widget.cpp
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
this->setWindowTitle("标题");
//创建图标对象
QIcon icon(":device.jpg");
//设置图标
this->setWindowIcon(icon);
//获取当前路径
QString currentDir = QDir::currentPath();
//设置工作目录到lable中
ui->label->setText(currentDir);
}
接下来,我们可以进⼊到项⽬的构建⽬录,可以看到,⽬录中多了⼀个 qrc_resource.cpp ⽂件.直接打开这个⽂件,可以看到类似如下代码:
上述代码其实就是通过unsigned char 数组,把device.jpg每个字节都记录下来.这些代码会被编译到exe中.后续⽆论exe被复制到哪个⽬录下,都确保能够访问到该图⽚资源.
对qrc机制总结
优点:确保了图⽚,字体,声⾳等资源能够真正做到"⽬录⽆关",⽆论如何都不会出现资源丢失的情况。
缺点:不适合管理体积⼤的资源.如果资源⽐较⼤(⽐如是⼏个MB的⽂件),或者资源特别多,⽣成的最终的exe体积就会⽐较⼤,程序运⾏消耗的内存也会增⼤,程序编译的时间也会显著增加.
2.5、windowOpacity
Opacity的英文:
所以这个控件是用来调节控件透明度的。
API | 说明 |
windowOpacity() | 获取到控件的不透明数值.返回float,取值为0.0->1.0其中0.0表⽰全透明,1.0表⽰完全不透明. |
setWindowOpacity(flo atn) | 设置控件的不透明数值. |
代码⽰例:调整窗⼝透明度
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);
}
执⾏程序,可以看到,点击了⼏下-之后,就可以透过窗⼝看到后⾯的猫猫头了.点击+⼜会逐渐恢复