一、控件概念
界面上各种元素、各种部分的统称(如按钮、输入框、下拉框、单选复选框...)
Qt作为GUI开发框架,内置了各种的常用控件,并支持自定义控件。
二、控件体系发展
1.没有完全的控件,需要使用绘图API手动绘制界面。
2.引入控件的概念,只有一些常用的控件,数量有限(按钮,输⼊框,单选框,复选框等),如html的原生控件。
3.拥有较为完整的控件体系,基本可以覆盖GUI开发的大部分场景。
例如早期的MFC,VB,C++Builder,Qt,Delphi,后来的AndroidSDK,JavaFX,前端的各种UI库等。
三、QWidget类
Qt的各种控件,均继承自QWidget,了解QWidget的属性和方法就了解了Qt控件的通用部分。
QtCreator代码中,选中控件类型,按F1查看文档。
核心属性
1.enabled
- 作用:表示控件是否可使用,true表示可用,false表示禁用。
禁用状态:不接收用户的输入事件,外观上往往是灰色的。
如果一个控件对象被禁用,那么该对象下的子元素也会被禁用。
- 相关API:
isEnabled() 获取控件状态 setEnabled() 设置控件状态
示例
通过其他按钮,控制该按钮的可用状态
拖拽添加按钮控件,右键转到槽定义
2.geometry
- 作用:位置和尺寸,x、y、width、height
坐标以父元素作为参考进行设置。
左手坐标系,横x,纵y。高为height,宽为width。
- 相关API:
geometry() 获取控件的位置和尺寸。返回结果为QRect。 setGeometry(QRect) 设置位置和尺寸 setGeometry(int x, int y, int width, int height) 设置位置和尺寸
- 示例
1.使用setGeometry(QRect),使用QRect来设置坐标和宽高
效果:改变矩形x,y时,宽高自动随之变化,移动了矩形的左上角位置,而右下角位置不变。
void Widget::on_pushButton_up_clicked()
{//1.获取geometryQRect rect=ui->pushButton_target->geometry();qDebug()<<rect;//2.设置geometryrect.setY(rect.y()-5);ui->pushButton_target->setGeometry(rect);}void Widget::on_pushButton_left_clicked()
{//1.获取geometryQRect rect=ui->pushButton_target->geometry();qDebug()<<rect;//2.设置geometryrect.setX(rect.x()-5);ui->pushButton_target->setGeometry(rect);}void Widget::on_pushButton_down_clicked()
{//1.获取geometryQRect rect=ui->pushButton_target->geometry();qDebug()<<rect;//2.设置geometryrect.setY(rect.y()+5);ui->pushButton_target->setGeometry(rect);}void Widget::on_pushButton_right_clicked()
{//1.获取geometryQRect rect=ui->pushButton_target->geometry();qDebug()<<rect;//2.设置geometryrect.setX(rect.x()+5);ui->pushButton_target->setGeometry(rect);}
2.使用setGeometry(int x, int y, int width, int height)
修改x,y时,宽高不会自动变化,实现平移的效果。
void Widget::on_pushButton_up_clicked()
{//1.获取geometryQRect rect=ui->pushButton_target->geometry();qDebug()<<rect;//2.设置geometry
// rect.setY(rect.y()-5);// ui->pushButton_target->setGeometry(rect);ui->pushButton_target->setGeometry(rect.x(),rect.y()-5,rect.width(),rect.height());}void Widget::on_pushButton_left_clicked()
{//1.获取geometryQRect rect=ui->pushButton_target->geometry();qDebug()<<rect;//2.设置geometry
// rect.setX(rect.x()-5);// ui->pushButton_target->setGeometry(rect);ui->pushButton_target->setGeometry(rect.x()-5,rect.y(),rect.width(),rect.height());}void Widget::on_pushButton_down_clicked()
{//1.获取geometryQRect rect=ui->pushButton_target->geometry();qDebug()<<rect;//2.设置geometry
// rect.setY(rect.y()+5);
// ui->pushButton_target->setGeometry(rect);ui->pushButton_target->setGeometry(rect.x(),rect.y()+5,rect.width(),rect.height());}void Widget::on_pushButton_right_clicked()
{//1.获取geometryQRect rect=ui->pushButton_target->geometry();qDebug()<<rect;//2.设置geometry
// rect.setX(rect.x()+5);// ui->pushButton_target->setGeometry(rect);ui->pushButton_target->setGeometry(rect.x()+5,rect.y(),rect.width(),rect.height());}void Widget::on_pushButton_target_clicked()
{}
3.告白程序
#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);srand(time(NULL));
}Widget::~Widget()
{delete ui;
}void Widget::on_pushButton_accept_clicked()
{ui->label->setText("今天开始是我们的第一天");
}void Widget::on_pushButton_regect_clicked()
{//点击即平移按钮到随机位置。限制在窗口内部//获取窗口尺寸大小QRect rect=this->geometry();int width=rect.width();int height=rect.height();int x=rand()%width;int y=rand()%height;//方法一:setGeometry
// QRect rect1=ui->pushButton_regect->geometry();// ui->pushButton_regect->setGeometry(x,y,rect1.width(),rect1.height());//方法2:moveui->pushButton_regect->move(x,y);}
注册pressed信号:鼠标点击,未释放时触发信号
void Widget::on_pushButton_regect_pressed()
{//点击即平移按钮到随机位置。限制在窗口内部//获取窗口尺寸大小QRect rect=this->geometry();int width=rect.width();int height=rect.height();int x=rand()%width;int y=rand()%height;//方法一:setGeometry
// QRect rect1=ui->pushButton_regect->geometry();// ui->pushButton_regect->setGeometry(x,y,rect1.width(),rect1.height());//方法2:moveui->pushButton_regect->move(x,y);}
需要鼠标挪动到按钮上,不点击,就触发信号的效果。需要学习Qt的事件机制,后面再学习。
window frame对坐标的影响
两种窗口坐标:包含window frame的和不包含windowframe的
windowframe就是带有标题栏,最小化,最⼤化,关闭按钮,的整个窗口。
不包含windowfram的窗口就是Widget控件本身。
Qt提供了包含和不包含windowframe的各种坐标API。
包含windowframe的坐标API:
x() | 获取x坐标 |
y() | 获取y坐标 |
frameGeometry() | 返回QRect对象。 QRect相当于QPoint和QSize的结合体 可以获取x,y,width,height 可以设置x,y,width,height |
pos() | 返回QPoint对象 可以获取x(),y(), 设置setX(),setY() |
move(int x,int y) | 移动控件 |
不包含windowframe的坐标API:
geometry() | 返回QRect对象 |
width() | 返回宽 |
height() | 返回高 |
rect() | 返回QRect对象 |
size() | 返回QSize对象 |
查看区别:
#include "widget.h"
#include "ui_widget.h"
#include<QPushButton>
#include<QDebug>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//widget对象构造函数中,获取到的两种坐标是一样的,widget还没有挂到windowframe上//需要在构造函数结束之后,然后挂到对象树上之后// QRect rect1=this->geometry();
// QRect rect2=this->frameGeometry();
// qDebug()<<rect1;
// qDebug()<<rect2;QPushButton* button=new QPushButton(this);button->setText("按钮");connect(button,&QPushButton::clicked,this,&Widget::handel);}Widget::~Widget()
{delete ui;
}void Widget::handel()
{QRect rect1=this->geometry();QRect rect2=this->frameGeometry();qDebug()<<rect1;qDebug()<<rect2;}
以整个屏幕的左上角为坐标原点
窗口含windowframe的坐标,x=559,y=172
不含windowframe的坐标,x=560,y=210
3.windowTitle
表示:窗口标题
API:
windowTitle() 获取控件的窗口标题 setWindowTitle(const QString& title) 设置控件窗口标题
set标题只对顶层窗口生效,但子控件调用时,没有产生效果,也不会报错。
4.windowIcon
表示:窗口图标
API:
windowIcon() 获取窗口图标,返回QIcon对象 setWindowIcon(const QIcon& icon) 设置窗口图标
只针对顶层窗口生效。
注意:
1.QIcon对象创建在栈上
QIcon icon(".\image\icon.png");//不在堆上开辟,图标在窗口创建后就设置到QWidget,图标对象释本身放不释放不影响图标的显示。
QIcon不支持对象树机制,并不能设置父节点。
2.路径不要包含转义字符
路径分割符使用 1./ 2.\\
\\是为了防止单反斜杠被识别成转义字符出现歧义
3.C++11引入 row string来解决上述问题
字符串里不包含转义字符(任何字符都不会进行转义)
使用:r("d:\ret.jpg")
4.图片路径问题
因为无法确保开发主机的图片路径和用户图片路径不一致
建议使用相对路径,将图片保存到项目目录下
但相对路径这样的方式,还需要在打包文件的时候,将exe程序,和图片按照一定的目录结构,打包发送给用户
引入QRC机制
||
\\//
QRC机制
Qt提供QRC机制 从根本上解决问题1.保证用户机存在图片路径 2.保证图片不会被用户删掉
为Qt项目引入一个xml文件(后缀为.qrc),在这个xml文件中导入图片资源。
后续编译时,将xml的资源提取,转换成二进制数据,保存到程序代码中。
这样所以图片不会被用户删掉了,缺点无法导入太大的文件。
如视频文件。
使用QRC示例:
二进制数据用数组保存,Qt抽象出虚拟的目录,来方便访问图片。
1)创建“前缀”Prefix
改成/。
2)点击Add Files,添加图片资源
3)要求图片必须保存在qrc文件的同级目录下,或同级的子目录里
4)导入成功效果
5)使用该图片:
QIcon(":/image/icon.png")
效果:
查看图片资源生成的代码:
build目录下的,debug目录中,新增