QWidget Geometry 保存与恢复

来源:互联网 发布:好听的网络歌曲 编辑:程序博客网 时间:2024/05/29 03:09

QWidget Geometry 保存与恢复

保存到bytearray时用 saveGeometry,从bytearray中恢复时用 restoreGeometry。

那么 saveGeometry 是究竟保存了什么?恢复时又执行了什么操作呢。

Geometry

QWidget 中与获取 geometry 有关的函数有3个(manual中只介绍了前两个,而保存和恢复时用的是后两个):

  • geometry
inline const QRect &QWidget::geometry() const
{ return data->crect; }

其中 data 是其 QWidgetData 成员

  • frameGeometry
QRect QWidget::frameGeometry() const
{
 Q_D(const QWidget);
 if (isWindow() && ! (windowType() == Qt::Popup)) {
   QRect fs = d->frameStrut();
   return QRect(data->crect.x() - fs.left(),
                data->crect.y() - fs.top(),
                data->crect.width() + fs.left() + fs.right(),
                data->crect.height() + fs.top() + fs.bottom());
 }
 return data->crect;
}
  • normalGeometry
QRect QWidget::normalGeometry() const
{
 Q_D(const QWidget);
 if (!d->extra || !d->extra->topextra)
   return QRect();
 if (!isMaximized() && !isFullScreen())
   return geometry();
 return d->topData()->normalGeometry;
}

其中 d 是其 QWidgetPrivete 成员

3个函数中,前两个,Qt Manual中都有介绍,而第3个,文档中似乎没有涉及。

saveGeometry

看看保存了什么东西

const quint32 magicNumber = 0x1D9D0CB;
 quint16 majorVersion = 1;
 quint16 minorVersion = 0;
 stream << magicNumber
        << majorVersion
        << minorVersion
        << frameGeometry()
        << normalGeometry()
        << qint32(QApplication::desktop()->screenNumber(this))
        << quint8(windowState() & Qt::WindowMaximized)
        << quint8(windowState() & Qt::WindowFullScreen);

先是魔数和版本号,然后是 frameGeometry 和 normalGeometry,接着桌面号,最后是否最大化和全屏

restoreGeometry
  • 首先确保在屏幕的可视区域,如不在,进行调整
  • 如果是全屏或最大化:
if (maximized || fullScreen) {
 // set geomerty before setting the window state to make
 // sure the window is maximized to the right screen.
 setGeometry(restoredNormalGeometry);
 Qt::WindowStates ws = windowState();
 if (maximized)
     ws |= Qt::WindowMaximized;
 if (fullScreen)
     ws |= Qt::WindowFullScreen;
 setWindowState(ws);
 d_func()->topData()->normalGeometry = restoredNormalGeometry;
  • 如不是,移动到合适位置并设置窗体大小
} else {
 QPoint offset;
#ifdef Q_WS_X11
 if (isFullScreen())
 offset = d_func()->topData()->fullScreenOffset;
#endif
 setWindowState(windowState() & ~(Qt::WindowMaximized | Qt::WindowFullScreen));
 move(restoredFrameGeometry.topLeft() + offset);
resize(restoredNormalGeometry.size());
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

QByteArray data;

QDataStream stream(&data, QIODevice::WriteOnly);

stream << QMainWindowLayout::VersionMarker;