前言
在进行Qt
程序开发时,想在不同的地方获取主窗体QMainWindow
的geometry
或者frameGeometry
属性。
解决方案
- 将主窗体设计为单例;
- 将主窗体指针设置到需要用到主窗体的
geometry
属性的对象里; - 声明一个全局静态类型,当主窗体位置或者尺寸发生变化时,用于获取主窗体的
geometry
属性。
第一个更好实现些,创建主窗体类时,直接设计为单例,在需要的地方调用即可;
第二种显得比较冗余,不好管理对象;
第三种实现更灵活,调用也方便。
问题分析
根据QMainWindow
帮助手册可知,当窗体尺寸改变时,会触发resizeEvent()
事件,但是如果只在resizeEvent()
事件里,获取geometry
或者frameGeometry
属性,当窗体初始化显示、最大化、最小化和移动位置时,获取的geometry
信息是错误的。
- 初次加载时,如下代码所示:
void MainWindow::resizeEvent(QResizeEvent *e)
{
qDebug().noquote() << this->geometry();
QMainWindow::resizeEvent(e);
}
初次启动程序,结果如下:
但整个窗体显示一般会在屏幕中央区域,所以说得到的geometry
的信息是错误的。
- 最大化时,输出信息:
- 很明显也不对,因为最大化,
x()
和y()
应该是(0, 0)
;反之,双击还原窗体尺寸,得到的geometry
也是不对的。 - 移动位置,没有打印,因为移动位置,尺寸没变化,所以不会进入
resizeEvent()
事件。
继续翻阅文档,发现还有changeEvent(QEvent *e)
和moveEvent(QMoveEvent *e)
事件,当窗体改变或者移动时触发以上两个事件。
将以上三个事件结合,得到的geometry
或者frameGeometry
属性就是正确的。
具体示例代码
void MainWindow::resizeEvent(QResizeEvent *e)
{
qDebug().noquote() << this->frameGeometry();
s_frameGeometry = this->frameGeometry();
QMainWindow::resizeEvent(e);
}
void MainWindow::changeEvent(QEvent *e)
{
qDebug().noquote()<< this->frameGeometry();
s_frameGeometry = this->frameGeometry();
QMainWindow::changeEvent(e);
}
void MainWindow::moveEvent(QMoveEvent *e)
{
qDebug().noquote()<< this->frameGeometry();
s_frameGeometry = this->frameGeometry();
QMainWindow::moveEvent(e);
}
当使用时,在调用的地方调用全部变量frameGeometry
即可
启动程序,输出信息如下: