一、控件的核心属性
1.enable属性
表示一个控件是否可用,可以用isEnabled()接口获取到当前控件的可用状态,同时来提供了setEnabled()接口设置控件是否可用,传递的参数为true和false。
isEnabled();
setEnabled(bool);
Demo:通过一个按钮来改变另一个按钮的可用状态
使用QtDesigner,拖拽两个Push Button,两个objectName一个叫testButton,另一个叫changeButton,分别编写点击事件的槽函数。
void Widget::on_testButton_clicked()
{
qDebug() << "测试按钮被点击了";
}
void Widget::on_changeButton_clicked()
{
//获取按钮状态
bool flag = ui->testButton->isEnabled();
//改变按钮状态
if(flag)
ui->testButton->setEnabled(false);
else
ui->testButton->setEnabled(true);
}
2.geometry属性
内部有四个属性x:横坐标、y:纵坐标、width:宽度、height:高度。对应有三个接口,第一个geometry()接口获取到该控件的位置和尺寸也就是上面的四个属性,会返回一个QRect结构体对象,内部封装着这四个属性。setGeometry()接口可以用来设置这四个属性。
geometry();
setGeometry(QRect);
setGeometry(int x, int y, int width, int height);
setX(); setY();
Demo:用四个按钮实现一个控件的移动
使用QtDesigner,拖拽5个Push Button,其中四个作为方向键,一个作为被操作的按钮。
void Widget::on_pushButton_up_clicked()
{
QRect rect = ui->pushButton_target->geometry();
ui->pushButton_target->setGeometry(rect.x(), rect.y() - 5, rect.width(), rect.height());
}
void Widget::on_pushButton_left_clicked()
{
QRect rect = ui->pushButton_target->geometry();
ui->pushButton_target->setGeometry(rect.x() - 5, rect.y(), rect.width(), rect.height());
}
void Widget::on_pushButton_down_clicked()
{
QRect rect = ui->pushButton_target->geometry();
ui->pushButton_target->setGeometry(rect.x(), rect.y() + 5, rect.width(), rect.height());
}
void Widget::on_pushButton_right_clicked()
{
QRect rect = ui->pushButton_target->geometry();
ui->pushButton_target->setGeometry(rect.x() + 5, rect.y(), rect.width(), rect.height());
}
控件中对于宽度和高度的如果不显示的设置的话,是用右下角的两个数据,减去左上角的两个数据的出来的,也就是说如果我们获取了一个QRect对象后,只更改x的值,那么无法做到移动,而是右下角的数据减去左上角的数据而使得控件的宽度变大或者变小了,所以说如果想要做到移动的话,就需要修改x,y的同时,设置width和height让其保持不变。
Demo2:请假程序
分为同意和不同意两个按钮,如果点击不同意的话,那么不同意的按钮会一直变化位置。
//同意槽函数
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 random_x = rand() % width;
int random_y = rand() % height;
QRect rect = ui->pushButton_2->geometry();
ui->pushButton_2->setGeometry(random_x, random_y, rect.width(), rect.height());
}
Window frame影响
Window frame是系统窗口框架,是系统自带的东西,会对我们形成的窗口进行包装,那我们geometry内部的x,y属性是相对于哪里的距离呢?位置1还是位置2?
再Qt中,这两种方案都是存在的,Qt中关于位置尺寸提供了很多中API接口,有的API就以Widget本体左上角为原点,也就是不考虑Window frame,我们上述使用的geometry系列他就是不考虑系统窗口框架的。那么也有的API例如frameGeometry、setFrameGeometry系列就考虑系统窗口框架。
但是在我们编写好了代码之后,发现为什么两个系列的接口打印出来的值怎么是一样的呢?因为我们实在构造函数里写的,当前项目还在构造阶段,还没有被加入到Window frame中,所以说两个系列的接口打印出来的内容是一样的。我们要把打印放到构造完项目之后的操作中,可以设计为按钮触发打印。
3.WindowTitle属性
用来设置窗口标题的属性,但是并不是所有的控件都可以设置该属性,该属性只能针对顶层窗口这样的QWidget控件才会有效,设置到非顶层窗口是没有任何效果的,也不会报错。
windowTitle(); 获取控件的窗口标题
setWindowTitle(const QString& title); 设置控件的窗口标题
4.WindowIcon属性
表示一个窗口的图标属性,根WindowTitle一样,只能设置在顶层的控件,设置在其他的控件中没有任何效果,也不会报错。
windowIcon(); 获得控件的窗口图标,返回Icon对象
setWindowIcon(const QIcon& icon); 设置控件的窗口图标
QIcon也是不支持对象树机制,所以不能给QIcon指定父对象。
在创建QIcon对象的时候,直接在栈上创建就可以了,之间我们创建的各种控件以及对象都是在堆上new出来的,主要是因为要确保当前控件或者对象的生命周期是足够的,new出来之后放到对象树中,让对象树去管理释放对象。但是对于QIcon来说,本身是一个比较小的对象,而且创建出来赋值到某个QWidget控件里面后,QIcon本身释不释放,是不影响图标最终的呈现效果的,所以可以在栈上创建,赋值给控件后,直接销毁即可。
对于QIcon对象的赋值:路径是一个QString字符串,C++中对于反斜杠 ‘ \ ’ 是由特殊意义的,属于转义字符,所以我们书写路径的时候需要双反斜杠来表示一个反斜杠。也可以使用一个正斜杠直接表示路径之间的分隔符。
C++11中引入了raw string用来解决上述的问题,字符串里面不包含任何的转义字符,也就是该字符串内部的所有字符都不会进行转义了。r(D:\hello\world\haha);
还有一个最重要的问题在于,我们引入的图片使用的是绝对路径,但是我们做的程序需要放到用户的电脑上,但是用户电脑上的路径肯定跟开发者的不一样,所以很可能找不到资源。相比于使用绝对路径,相对路径的方式会是个很好的解决办法。但是相对路径的情况也可能出问题,用户可能不小心将资源删除了。
qrc机制
Qt中引入了qrc机制就可以保证上述的两个问题,一个是确保资源的路径在主机上存在,另一个是资源不会被用户轻易的弄丢。实现的原理就是给Qt项目引入了一个额外的以.qrc为后缀的xml文件,这个xml文件可以把要使用的图片资源导入进来,并在xml中进行记录。Qt在编译项目的时候,就会根据qrc中描述的图片信息,提取图片二进制数据转换为C++代码,最终编译到exe可执行程序内部。
如何使用呢?创建一个Qt中的Qt Resource file文件,创建好之后就自动生成了一个qrc文件。之后先创建一个前缀Prefix,但是这个前缀可以理解为虚拟的目录,可能不是真实存在的,Qt自己为了方便访问到图片资源,自己抽象出来的。之后就可以将图片资源导入到虚拟目录下了,注意图片资源在添加前必须在qrc同级或子目录下才可以添加。
当代码中需要使用qrc中管理的文件时,就需要在路径上带有冒号 + 前缀 + 文件名即可。之后我们在debug下查看时,就看不到图片资源了,与之对应的是生成了一个qrc_xxxx.cpp文件了,该文件内部是把图片的二进制数据提取了出来,之后都编译在exe文件里面了。
5.WindowOpacity属性
对于控件透明度的属性。
windowOpacity(); 获取控件的不透明度,0.0表示全透明,1.0表示完全不透明
setWindowOpacity(float n); 设置控件的不透明度
Demo:通过按钮控制控件的透明度
//增加不透明度
void Widget::on_pushButton_up_clicked()
{
//获取控件的不透明度
float opacity = this->windowOpacity();
if(opacity >= 1.0)
return;
//设置控件的不透明度
opacity += 0.1;
this->setWindowOpacity(opacity);
}
//减少不透明度
void Widget::on_pushButton_down_clicked()
{
//获取控件的不透明度
float opacity = this->windowOpacity();
if(opacity <= 0.0)
return;
//设置控件的不透明度
opacity -= 0.1;
this->setWindowOpacity(opacity);
}
6.cursor属性
用于鼠标悬停控件上时的形状的定义属性,可以使用接口,也可以使用Qt Designer中设置。Qt中内置了很多的光标形状,使用了一个enum类型保存在enum CursorShape内部。当然也可以自定义光标的形状。
cursor(); 获取到当前widget的cursor属性,返回会QCursor对象
setCursor(const QCursor& cursor); 设置当前widget的cursor属性
QGuiApplication::setOverrideCursor(const QCursor& cursor); 设置全局的光标形状,会 覆盖所有setCursor设置的内容(是程序的全局,不是系统级别的)
QPixmap类是一个图片类,可以用来保存一个图片文件,它内部有丰富的对图片进行操作的接口,例如scaled功能上来说就是图片的缩放,但是他是生成一个副本,返回的值才是真正我们想要的。同时该类也不支持对象树机制。光标点击默认的生效位置是在图标的最左上角,我们称之为热点,如果想让热点位置偏移,可以在构造QCursor对象时进行设置。下面的案例就是(10,10)的位置才是真正点击的位置了。
7.font属性
用于表示控件内部字体信息的属性,例如字体、大小、颜色等等,也可以在Qt Designer中查看和修改是比较方便的。
font(); 获取当前Widget的字体信息,返回QFont对象
setFont(const QFont& font); 设置当前Widget的字体信息
QFont类内部的属性:family字体家族;pointSize字体大小;weight字体粗细范围在0~99,数值越大那么字体越粗;bold是否加粗,如果是true的话相当于字体大小的75,而false相当于字体大小的50; italic是否倾斜;underline是否带有下划线;strikeOut是否带有删除线。他们这些属性对应的设置接口都是在前面加set。