爱悠闲 > 关于Qt窗口保持宽高比的研究

关于Qt窗口保持宽高比的研究

分类: C++  |  标签: qt,widget,布局  |  作者: chlk118 相关  |  发布日期 : 2015-07-13  |  热度 : 325°

近日,工作中需Qt的普通窗口保持一定的宽高比(1366*768),本来以为是一件很简单的事情,结果几经波折,终于完成一个稍微满意的答案,在此分享一下解决过程。

首先,想到Qt本身应该已经提供此功能的,故而首先在Qt Assistant中的查找此种方法。找到Qt中的一个enum Qt::AspectRatioMode,官方解释This enum type defines what happens to the aspect ratio when scaling an rectangle。刚找到时甚慰,想着QWidget中设置一下此属性即可解决,但结果怎么也没找到可以设置此属性的地方,煞是苦闷!



紧接着,寻求谷歌的帮助,找到一些使用重写heightForWidth函数的方法,于是使用之。重写结果为

int QSpectRatio::heightForWidth(int width)

{

return 768.0 * width / 1366.0;

}

使用此方法时有两点注意事项:

1、必须在窗口的QSizePolicy中设置setHeightForWidth(true);

2、使用此方法的窗口不能是顶层窗口,因此你需要把你实现此方法的Widget放在另外窗口的布局中,如果,你的此窗口就是顶层窗口,那么只能在main函数中,声明一个widget,并使用布局,最后在把此窗口放在新声明的widget中,heightForWidth方法才能生效。

实现此方法后,当你改变宽度时,高度确实会随之变化,且比例仍保持在1366*768,但当你改变高度时,窗口就变形了(无法保持在1366*768委屈,革命尚未成功,我仍需努力啊!



这时,不得不重写resizeEvent事件了,我的想法是在此事件中,重新计算出width和height的值,使之保持在我需要的1366*768,然后调用resize(int width, int heigth)函数,使窗口重绘。但遇到了两个问题:

1、计算width和height使之保持在1366*768好麻烦啊,我总是没算对,我算法这么差抓狂

2、调用完resize之后,立马就重新触发resizeEvent事件了,写不好就循环了,更甚至无限循环尴尬

又失败了。。。。。。


最后,只能出绝招了,去掉QWidget的Frame,自己控制所有事件,我就不信搞不定你!

首先,在构造函数中设置去除Frame的方法setWindowFlags(Qt::FramelessWindowHint);

其次,重新实现mouseMoveEvent(QMouseEvent* event)方法,注意若要使此方法生效,需要设置属性setMouseTracking(true),否则只能在鼠标点击时才能触发此事件,当鼠标只是移动的时候是永远无法触发mouseMoveEvent事件的。触发此事件时,判断鼠标的位置,若鼠标在窗口的右边(我的判断右边标准是鼠标离窗口最外的距离小于8个像素)则设置鼠标状态为Qt::SizeHorCursor即;若鼠标在窗口的下边(我的判断右边标准是鼠标离窗口最外的距离小于8个像素)则设置鼠标状态为Qt::SizeVerCursor 即,否则鼠标状态就为标准的Qt::ArrowCursor即了。

第三,重新实现mousePressEvent(QMouseEvent* event),判断状态若是自己需要的(即鼠标在右边和下边时)并且又是左键单击事件则记录此状态,如右边记录为状态一,下边记录为状态二。

第四,回过头来,继续改造mouseMoveEvent(QMouseEvent* event)方法,判断在第三步中记录的状态,如果是状态一,则

QRect rt = geometry();
QPoint pt = event->globalPos();
int w = pt.x() - rt.x();
int height = 768.0 * w / 1366.0;
resize(w, height);

即获取当前窗口宽高,并依据宽度重新计算高度,并resize之;

如果是状态二,则

QRect rt = geometry();
QPoint pt = event->globalPos();
int height = pt.y() - rt.y();
int width = 1366 * height / 768.0;
resize(width, height);

即获取当前窗口宽高,并依据度重新计算度,并resize之;

第五,也就是最后一步,需要重新实现mouseReleaseEvent(QMouseEvent* event)方法,在此方法中是重新设置第三步中记录的状态使用的,即当鼠标单击释放后,需要重置这些状态,否则后果自负大笑

至此,不论是右边的拖动还是下边的拖动,窗口都能顺畅的一直保持在1366*768的比例了,当然还差了鼠标状态Qt::SizeFDiagCursor即时的状态了,之后在在增加吧。


好了,所有的就这些了。

最后,感谢一下谢老师的指导大笑

版权声明:本文为博主原创文章,未经博主允许不得转载。