QMainWindow最大化时,QDockWidget :: restoreGeometry无法正常工作 [英] QDockWidget::restoreGeometry not working correctly when QMainWindow is maximized

查看:396
本文介绍了QMainWindow最大化时,QDockWidget :: restoreGeometry无法正常工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有许多QDockWidgets,全部都停在一个QMainWindow中.

我已经覆盖了showEvent,并将事件传递给基类后,我正在还原停靠小部件的几何形状

void DockWidget::showEvent(QShowEvent* ev) 
{
    QDockWidget::showEvent(ev);

    QByteArray byte_array = settings_.value(id + ".geometry").toByteArray();

    LOG("rest: %s", QString(byte_array.toHex()));

    QDockWidget::restoreGeometry(byte_array);
}


在我的QMainWindow::closeEvent中,我为每个停靠小部件都呼叫saveSettings

void MainWindow::closeEvent(QCloseEvent* ev) 
{
    QList<DockWidget*> dock_widgets = findChildren<DockWidget*>();

    for (DockWidget* dock_widget : dock_widgets)
        dock_widget->saveSettings();

    QMainWindow::closeEvent(ev);
}


在我的停靠小部件的saveSettings函数中,将saveGeometry的结果写入磁盘:

void DockWidget::saveSettings()
{
    QByteArray byte_array = QDockWidget::saveGeometry();

    LOG("save: %s", QString(byte_array.toHex()));

    settings_.setValue(id + ".geometry", byte_array);
    settings_.sync();
}


QMainWindow未最大化时,此起作用,而当最大化QMainWindow时,窗口小部件无法正确还原.

此图片中,我在关闭之前就已经整理好了小部件. (已链接,因为内联图像会太大)

此图像中,我重新加载了我的应用,并且窗口小部件的几何图形未正确加载./p>

您可以在上面的函数中看到我记录了要保存和加载的几何字符串.

我已经向我证明了设置已正确保存并再次恢复,但是由于某种原因它无法正常工作

关闭应用;保存状态:

save: 01d9d0cb000200000000053f000000640000077f000001a00000053f000000640000077f000001a000000000000000000780

打开应用;恢复状态:(此处的十六进制数据与保存的十六进制数据完全匹配)

rest: 01d9d0cb000200000000053f000000640000077f000001a00000053f000000640000077f000001a000000000000000000780

什么都没碰到,再次关闭应用程序:(十六进制数据现在有所不同,因为几何形状不同,请参见下面的标记)

save: 01d9d0cb000200000000053f000000640000077f0000014e0000053f000000640000077f0000014e00000000000000000780
                                                    ^                               ^

当窗口未最大化时,不会发生这种情况.

这是Qt中的错误,还是我没有正确使用该功能?

我正在Ubuntu 16.04上使用Qt 5.5.

解决方案

这是Qt中的错误.具体来说, QTBUG-46620 可能还包括

然后,按如下所示还原几何图形:

restoreGeometry(settings.value("geometry").toByteArray());
if (isMaximized())
{
    setGeometry( QApplication::desktop()->availableGeometry(this) );
}
restoreState(settings.value("windowState").toByteArray());

如果您在上述解决方法上遇到问题,则可能还必须保存窗口的最大化状态:

void MainWindow::closeEvent(QCloseEvent* ev)
{
     settings_.setValue("geometry", saveGeometry());
     settings_.setValue("state", saveState());
     settings_.setValue("maximized", isMaximized());
}

然后还原如下:

restoreGeometry(settings.value("geometry").toByteArray());
if (settings.value("maximized").toBool())
{
    showMaximized();
    setGeometry( QApplication::desktop()->availableGeometry(this) );
}
restoreState(settings.value("windowState").toByteArray());

请注意,这些变通办法可能会导致在某些平台上生成一些警告消息.

I have a number of QDockWidgets, all docked in a single QMainWindow.

I have overridden the showEvent, and after passing the event on to the base class I am restoring the dock widget's geometry

void DockWidget::showEvent(QShowEvent* ev) 
{
    QDockWidget::showEvent(ev);

    QByteArray byte_array = settings_.value(id + ".geometry").toByteArray();

    LOG("rest: %s", QString(byte_array.toHex()));

    QDockWidget::restoreGeometry(byte_array);
}


In my QMainWindow::closeEvent I am calling saveSettings for each of my dock widgets

void MainWindow::closeEvent(QCloseEvent* ev) 
{
    QList<DockWidget*> dock_widgets = findChildren<DockWidget*>();

    for (DockWidget* dock_widget : dock_widgets)
        dock_widget->saveSettings();

    QMainWindow::closeEvent(ev);
}


In my dock widget's saveSettings function I write the result of saveGeometry to disk:

void DockWidget::saveSettings()
{
    QByteArray byte_array = QDockWidget::saveGeometry();

    LOG("save: %s", QString(byte_array.toHex()));

    settings_.setValue(id + ".geometry", byte_array);
    settings_.sync();
}


Whilst this does work when my QMainWindow is not maximized, when it is maximized the widgets aren't restored correctly.

In this image I have arranged my widgets just prior to closing. (linked because inline the image will be too large)

In this image I reload my app and the widgets' geometry is incorrectly loaded.

You can see in my functions above I log the geometry string being saved and loaded.

I have proven to myself that the settings are correctly saved and restored again, but somehow it's not working correctly

close the app; save the state:

save: 01d9d0cb000200000000053f000000640000077f000001a00000053f000000640000077f000001a000000000000000000780

open the app; restore the state: (the hex data here matches the saved one exactly)

rest: 01d9d0cb000200000000053f000000640000077f000001a00000053f000000640000077f000001a000000000000000000780

close the app again, having touched nothing: (the hex data is different now, as the geometry is different, see marks below)

save: 01d9d0cb000200000000053f000000640000077f0000014e0000053f000000640000077f0000014e00000000000000000780
                                                    ^                               ^

This doesn't happen when the window is not maximized.

Is this a bug in Qt, or am I not using the functionality correctly?

I am using Qt 5.5 on Ubuntu 16.04.

解决方案

This is a bug in Qt. Specifically, QTBUG-46620 and possibly also QTBUG-16252.

The bug report for QTBUG-46620 details a work-around, which you should try. To begin with, ensure that the main window geometry and main window state are saved when you close the application (note that you should not have to save the geometry of each dock window separately):

void MainWindow::closeEvent(QCloseEvent* ev)
{
     settings_.setValue("geometry", saveGeometry());
     settings_.setValue("state", saveState());
}

Then, restore the geometry as follows:

restoreGeometry(settings.value("geometry").toByteArray());
if (isMaximized())
{
    setGeometry( QApplication::desktop()->availableGeometry(this) );
}
restoreState(settings.value("windowState").toByteArray());

If the you have trouble with the above work-around, you may also have to save the maximized state of the window:

void MainWindow::closeEvent(QCloseEvent* ev)
{
     settings_.setValue("geometry", saveGeometry());
     settings_.setValue("state", saveState());
     settings_.setValue("maximized", isMaximized());
}

Then restore as follows:

restoreGeometry(settings.value("geometry").toByteArray());
if (settings.value("maximized").toBool())
{
    showMaximized();
    setGeometry( QApplication::desktop()->availableGeometry(this) );
}
restoreState(settings.value("windowState").toByteArray());

Note that these work-arounds may cause some warning messages to be generated on some platforms.

这篇关于QMainWindow最大化时,QDockWidget :: restoreGeometry无法正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆