【Qt】常用控件(二)QWidget的geometry属性,geometry,setGeometry
小编个人主页详情—请点击小编个人gitee代码仓库—请点击Qt系列专栏—请点击倘若命中无此运孤身亦可登昆仑送给屏幕面前的读者朋友们和小编自己!目录前言一、QWidget的geometry理论讲解geometrysetGeometry二、移动控件的实现三、随机按钮的实现版本一版本二总结前言【Qt】常用控件一控件概述QWidget的enabled属性isEnabledsetEnabled——书接上文 详情请点击——本文由小编为大家介绍——【Qt】常用控件二QWidget的geometry属性geometrysetGeometry一、QWidget的geometry理论讲解那么我们接下来学习QWidget的geometry属性首先我们来看geometry的汉语意思是几何其实单纯让我们来看几何这个词还是有点抽象的难以理解的那么如上图geometry的值是[(0, 0), 800 x 600]所以在Qt中对应的我们可以将几何理解为四个属性的统称即x, y, width, height即对应汉语是横坐标纵坐标宽度高度所以这样就好理解了那么我们看如上是一个Widget窗口的界面其中有一个子控件QPushButton即QPushButton的父对象/父元素是Widget所以我们学习了Qt坐标系的认识 详情请点击——之后我们来观察x和y的起始位置其实就是当前控件对应父元素/父对象/父控件的原点即左上角位置那么我们通过控制QPushButton的geometry属性例如控制横坐标x和纵坐标y可以控制当前控件QPushButton的位置控制宽度width和高度height就可以控制当前控件的尺寸所以我们就可以得出通过geometry属性就可以控制一个控件的位置和尺寸geometry那么关于QWidget的geometry属性Qt提供了两个函数分别是geometry和setGeometry下面我们来逐一认识一下首先是geometry用于获取到控件的位置和尺寸返回结果是一个QRect那么其中的Rect其实就是Rectangle也就是矩形的缩写里面包含了x, y, width, height其中的xy是相对于父控件的左上角的原点位置那么这些的单位在Qt中都是像素关于像素的讲解小编在Qt坐标系的认识中进行了讲解 第八点Qt坐标系的认识中的第13小点进行的讲解详情请点击——那么其实Qt中对于几何上的概念也进行了一定的封装例如QPoint表示一个点QRect表示一个矩形而对于QPoint和QRect来讲属于是小对象里面的属性非常少占用空间也非常小所以进行拷贝的开销不大所以在C中使用这类的小对象通常会按照值拷贝的方式来传递参数setGeometrysetGeometry有两个重载分别是setGeometry(QRect)和setGeometry(x, y, width, height)可以用于设置控件的位置和尺寸可以直接设置一个QRect也可以分四个属性单独设置那么在实际使用中根据场景的不同我们可以选择不同的重载函数进行灵活调用小编那么我记得之前你还讲解过move那么和这里的setGeometry有什么区别吗move(x, y)仅仅是用于修改控件的位置而setGeometry既可以修改控件的位置又可以修改控件的尺寸二、移动控件的实现那么我们知道setGeometry可以移动控件的位置和尺寸那么我们就可以去实现一个基于上下左右按钮的界面实现移动控件的位置的GUI程序所以此时我们创建一个项目名为QWidget_3基类为QWidget派生类为Widget的项目所以此时我们点击ui文件进入Qt Designer然后依次拖拽五个Push Button按钮分别给按钮的文本显示中修改成targetupdownleftright然后将后四个按钮按照上图进行排布期望通过点击后四个按钮修改target按钮的geometry属性进而达到移动target按钮的效果其实我们知道我们拖拽了五个按钮那么按钮本身的名字objectName仍然是按照数字的方式进行命名的这样是不好的所以我们将objectName中值对应的数字修改为对应的含义进行命名即可如上图的左侧一列那么我们在修改属性的时候一定要双击选中我们想要修改的控件然后再进行修改以免修改到其它的控件身上那么接下来我们对于上下左右四个按钮对应都进行右击然后点击转到槽接下来选择无参的clicked然后Qt帮我们生成对应槽函数的声明和定义#ifndefWIDGET_H#defineWIDGET_H#includeQWidgetQT_BEGIN_NAMESPACEnamespaceUi{classWidget;}QT_END_NAMESPACEclassWidget:publicQWidget{Q_OBJECTpublic:Widget(QWidget*parentnullptr);~Widget();privateslots:voidon_pushButton_up_clicked();voidon_pushButton_down_clicked();voidon_pushButton_left_clicked();voidon_pushButton_right_clicked();private:Ui::Widget*ui;};#endif// WIDGET_H#includewidget.h#includeui_widget.h#includeQDebugWidget::Widget(QWidget*parent):QWidget(parent),ui(newUi::Widget){ui-setupUi(this);}Widget::~Widget(){deleteui;}voidWidget::on_pushButton_up_clicked(){QRect rectui-pushButton_target-geometry();qDebug()rect;rect.setY(rect.y()-10);ui-pushButton_target-setGeometry(rect);}voidWidget::on_pushButton_down_clicked(){QRect rectui-pushButton_target-geometry();qDebug()rect;rect.setY(rect.y()10);ui-pushButton_target-setGeometry(rect);}voidWidget::on_pushButton_left_clicked(){QRect rectui-pushButton_target-geometry();qDebug()rect;rect.setX(rect.x()-10);ui-pushButton_target-setGeometry(rect);}voidWidget::on_pushButton_right_clicked(){QRect rectui-pushButton_target-geometry();qDebug()rect;rect.setX(rect.x()10);ui-pushButton_target-setGeometry(rect);}所以对于四个按钮发出的clicked对应的槽函数那么对于up按钮对应的on_pushButton_up_clicked此时我们先使用geometry获取target按钮geometry对应的四个属性对应的QRect然后使用qDebug()打印QRect对象rect那么这里使用Qt内置的日志打印的宏qDebug()可以很好的兼容Qt的内置类型为什么呢因为Qt的内置日志打印的宏qDebug()重载了Qt内置类型对应的左移运算符所以这里使用qDebug()可以直接对Qt的内置类型进行打印相反由于C的cout没有重载Qt内置类型对应的左移运算符所以这里无法进行直接打印接下来在on_pushButton_up_clicked中我们要实现的是target按钮向上移动这里我们需要学习Qt坐标系的认识之后才能更好的理解Qt中坐标的移动 详情请点击——所以此时应该是将纵坐标减少这里我们以10个像素为基准进行减少那么我们应该是要在target按钮原有的纵坐标的基础上减少10所以我们该如何获取target按钮原有的纵坐标呢target按钮原有的纵坐标对应的值在geometry中此时geometry对应的值我们已经获取到了就在rect中那么我们知道我们要访问是其中的成员变量y但是其中的成员变量y是私有成员变量我们无法通过rect.y的形式进行访问所以我们该如何做呢其实Qt考虑了这一点它提供了y()接口可以让我们获取私有成员变量y的值并且可以使用setY()去进行修改私有成员变量的值所以此时我们使用y()的值进行减10像素然后使用setY()设置进rect中即可此时我们就完成了对纵坐标的减10那么接下来小编有问题了此时的上移target按钮的槽函数可以实现上移吗不可以一定不可以此时我们修改了target按钮对应的geometry属性中的纵坐标y了吗有的读者友友可能会想有啊我们不是修改了rect中的纵坐标y了吗是的修改的是rect中的纵坐标y那么我们想一下这个rect本质上是我们定义在自己栈帧上的局部变量呀那么是否影响target按钮对应的geometry呢不影响所以此时我们还需要调用setGeometry将修改后的rect设置进target按钮对应的geometry属性中那么同样的道理下移按钮就是让纵坐标y加10左移按钮就是让横坐标x减10右移按钮就是让横坐标x加10过程步骤都和上移按钮类似这里小编就不再过多赘述了运行结果如下那么程序运行后我们仔细来看首先按下上移下移左移右移之后确实实现了对应的target按钮的移动但是附带着整个target按钮的大小也随之调整了那么这究竟是为什么呢那么我们来看程序的输出我们移动的纵坐标y横坐标x的时候本质是在调整左上角的位置与之对应的高度和宽度也发生了改变那么我们想要的是按钮平移即按钮的位置发生改变尺寸不变即高度宽度不变所以我们该如何做呢那么我们直接在QRect对应的对象rect中使用setY和setX修改横坐标和纵坐标的时候与之对应的宽度和高度会随之发生改变就类似于右下角不变仅仅调整左上角的位置所以我们该如何做呢那么我们不修改QRect对应的对象不就好了那么使用setGeometry的第二个重载函数setGeomety(x, y, width, height)那么在参数中对横坐标x和纵坐标进行修改即可#includewidget.h#includeui_widget.h#includeQDebugWidget::Widget(QWidget*parent):QWidget(parent),ui(newUi::Widget){ui-setupUi(this);}Widget::~Widget(){deleteui;}voidWidget::on_pushButton_up_clicked(){QRect rectui-pushButton_target-geometry();qDebug()rect;// rect.setY(rect.y() - 10);// ui-pushButton_target-setGeometry(rect);ui-pushButton_target-setGeometry(rect.x(),rect.y()-10,rect.width(),rect.height());}voidWidget::on_pushButton_down_clicked(){QRect rectui-pushButton_target-geometry();qDebug()rect;// rect.setY(rect.y() 10);// ui-pushButton_target-setGeometry(rect);ui-pushButton_target-setGeometry(rect.x(),rect.y()10,rect.width(),rect.height());}voidWidget::on_pushButton_left_clicked(){QRect rectui-pushButton_target-geometry();qDebug()rect;// rect.setX(rect.x() - 10);// ui-pushButton_target-setGeometry(rect);ui-pushButton_target-setGeometry(rect.x()-10,rect.y(),rect.width(),rect.height());}voidWidget::on_pushButton_right_clicked(){QRect rectui-pushButton_target-geometry();qDebug()rect;// rect.setX(rect.x() 10);// ui-pushButton_target-setGeometry(rect);ui-pushButton_target-setGeometry(rect.x()10,rect.y(),rect.width(),rect.height());}如上我们直接在setGetmetry(x, y, width, height)的参数中对横坐标x和纵坐标y进行调整即可那么要获取QRect对象rect的宽度使用的是rect.width()要获取QRect对象rect的高度使用的是rect.height()运行结果如下所以如上此时我们使用上下左右按钮就可以在保证target按钮尺寸不变即宽度和高度不变的前提下去调整target按钮的位置即调整横坐标x和纵坐标y三、随机按钮的实现版本一那么在经过上面的学习后我们已经对于geometry及其对应的接口geometry和setGeometry已经有了一个比较好的理解了那么接下来我们来实现一个向兄弟借款的程序如何理解这个借款程序呢提供一个显示文本的标签提供一个接收按钮提供一个拒绝按钮我们不期望拒绝按钮被点击到所以如果我的好兄弟点击拒绝按钮那么拒绝按钮将会随机出现在窗口的其它位置所以接下来我们新建一个项目名为QWidget_4基类为QWidget派生类为Widget的项目此时我们点击ui文件进入Qt Designer中拖拽标签控件Label然后编辑要显示的文本输入兄弟兄弟借我5块钱好不好那么兄弟面临两个选择分别是接收和拒绝所以此时我们给兄弟提供两个按钮所以拖拽按钮控件Push Button那么第一个按钮修改显示的文本为欣然同意第二个按钮修改显示的文本为残忍拒绝接下来对于这两个按钮我们不使用Qt默认为我们生成的数字形式的objectName我们修改为如上图中的有实际意义的accept和object我们鼠标右击点击转到槽接下来点击无参的clicked即可让Qt为我们生成点击信号对应的槽函数的声明和定义#ifndefWIDGET_H#defineWIDGET_H#includeQWidgetQT_BEGIN_NAMESPACEnamespaceUi{classWidget;}QT_END_NAMESPACEclassWidget:publicQWidget{Q_OBJECTpublic:Widget(QWidget*parentnullptr);~Widget();privateslots:voidon_pushButton_accept_clicked();voidon_pushButton_reject_clicked();private:Ui::Widget*ui;};#endif// WIDGET_H#includewidget.h#includeui_widget.h#includecstdlib#includectimeWidget::Widget(QWidget*parent):QWidget(parent),ui(newUi::Widget){ui-setupUi(this);srand(time(nullptr));}Widget::~Widget(){deleteui;}voidWidget::on_pushButton_accept_clicked(){ui-label-setText(不愧是好兄弟这5块钱我就笑纳了嘿嘿(言外之意我不还了));}voidWidget::on_pushButton_reject_clicked(){intwidththis-geometry().width();intheightthis-geometry().height();intxrand()%width;intyrand()%height;ui-pushButton_reject-move(x,y);}那么首先我们在接收按钮的clicked信号对应的槽函数on_pushButton_accept_clicked中如果好兄弟点击了欣然接受按钮那么就代表此时同意借给我钱了那么此时我们就将标签的文本替换成不愧是好兄弟这5块钱我就笑纳了嘿嘿(言外之意我不还了)那么对于这个标签来讲虽然我们没有修改标签的objectName我们其实还是可以得知标签的objectName的值的那么在ui文件中双击标签那么就可以查看标签的属性了在属性中有一个objectName那么对应的值就是label了此时我们使用ui-label就可以访问到标签对象进行修改文本内容接下来就是要编写残忍拒绝按钮对应clicked点击信号对应的槽函数on_pushButton_reject_clicked那么首先搞清楚我们要修改的按钮是残忍拒绝按钮当兄弟点击了残忍拒绝按钮之后我们要移动的是残忍拒绝这个按钮那么要移动的范围是拒绝按钮的父控件对应的界面范围内我们可以当兄弟点击残忍拒绝按钮之后让残忍拒绝按钮出现在界面的任何位置注意这个界面是父控件Widget对应的界面范围但是我们不能让残忍拒绝出现在父控件Widget的界面范围以外所以我们要先获取父控件Widget即当前的this指针指向的就是Widget对象w所以此时我们使用this指针调用geometry就可以获取到父控件的geometry属性那么此时geometry方法中的宽度width()和高度height()就是父控件的界面范围所以我们使用width保存获得宽度使用height获得长度即可我们的横坐标x和纵坐标y不应该超出这个界面范围那么由于我们要实现的是当拒绝按钮被点击之后随机出现在父控件Widget的界面范围内所以随机二字就要求我们应该使用rand获取随机数rand是C标准库中的函数rand的作用就是生成一个随机的整数由于是随机所以这个整数有可能很小也有可能很大并且也有可能超出父控件的界面范围所以例如界面的width宽的像素大小是100所以对应的像素值是0到99正好100个像素点那么接下来我们生成的表示横坐标x的随机数就应该处于0到99这个范围内所以此时我们就使用rand取模width就可以得到我们想要的随机的不超过父控件Widget界面范围的横坐标x同理使用rand取模height就可以得到我们想要的随机的不超过父控件Widget界面范围的纵坐标y那么rand是使用了一系列数学手段生成的随机数随机数是基于一个随机数种子进行生成的默认这个随机数种子的值为0所以也就意味着如果我们不调整随机数种子那么调用rand生成的随机数仅仅是单次程序运行内是随机的但是两次程序运行生成的随机数都是相同的所以依旧意味着兄弟第一次玩完之后关闭那么兄弟第二个玩的时候按下残忍拒绝出现的位置依次和第一次相同这固然不是我们想要的所以此时我们需要使用srand设置随机数种子那么我们使用time获取秒级的时间戳这个时间戳是当前时间相对于1970年1月1日0时0分0秒的差值所以此时我们使用time传参nullptr就可以获取到当前的时间戳然后给srand进行传参就可以设置随机数种子那么什么时候设置这个随机数种子呢我们可以在Widget类的构造函数中进行设置随机数种子需要注意的是使用rand和srand需要包含头文件#include cstdlib使用time需要包含头文件#include ctime运行结果如下所以此时当兄弟点击残忍拒绝按钮的时候此时残忍拒绝按钮就会随机出现在界面的位置上好兄弟没办法只能点击欣然接受借给我们5块钱了版本二那么对于一次点击来讲鼠标按压鼠标松开期间鼠标位于按钮上算作一次点击那么按钮提供的信号不只有clicked点击那么按钮也提供了pressed按下也就是鼠标按下的时候就会触发这个pressed信号所以此时我们右击残忍拒绝然后点击转到槽选择pressed按下信号让Qt帮我们生成对应槽函数的声明和定义#ifndefWIDGET_H#defineWIDGET_H#includeQWidgetQT_BEGIN_NAMESPACEnamespaceUi{classWidget;}QT_END_NAMESPACEclassWidget:publicQWidget{Q_OBJECTpublic:Widget(QWidget*parentnullptr);~Widget();privateslots:voidon_pushButton_accept_clicked();voidon_pushButton_reject_clicked();voidon_pushButton_reject_pressed();private:Ui::Widget*ui;};#endif// WIDGET_H#includewidget.h#includeui_widget.h#includecstdlib#includectimeWidget::Widget(QWidget*parent):QWidget(parent),ui(newUi::Widget){ui-setupUi(this);srand(time(nullptr));}Widget::~Widget(){deleteui;}voidWidget::on_pushButton_accept_clicked(){ui-label-setText(不愧是好兄弟这5块钱我就笑纳了嘿嘿(言外之意我不还了));}voidWidget::on_pushButton_reject_clicked(){}voidWidget::on_pushButton_reject_pressed(){intwidththis-geometry().width();intheightthis-geometry().height();intxrand()%width;intyrand()%height;ui-pushButton_reject-move(x,y);}所以此时我们要进行的调整很简单那么只需要将残忍拒绝按钮对应的点击信号clicked对应的槽函数on_pushButton_reject_clicked中的代码放到残忍拒绝按钮对应的按下信号pressed对应的槽函数on_pushButton_reject_pressed中运行结果如下如上此时当鼠标光标位于残忍拒绝按钮上并且按下的时候此时就会触发按下信号pressed此时就会执行对应的槽函数on_pushButton_reject_pressed进而此时残忍拒绝按钮就会随机出现在界面的位置上好兄弟没办法只能点击欣然接受借给我们5块钱了那么此时我们再来看一下点击的过程按压按钮然后松开按钮期间鼠标位于按钮上那么我们思考一下Qt中有手段可以得知鼠标位于按钮上所以是否我们可以做到鼠标不点击只要挪到按钮上那么就让按钮随机移动呢其实是可以的这需要使用到Qt中的事件机制等到后面合适的时机小编会进行讲解Qt的事件机制进而去实现版本三即只要鼠标挪到按钮上就会让按钮随机移动关于随机按钮版本三的实现在第三点事件的处理中随机按钮版本三的实现中进行的讲解详情请点击——总结以上就是今天的博客内容啦,希望对读者朋友们有帮助水滴石穿坚持就是胜利读者朋友们可以点个关注点赞收藏加关注找到小编不迷路