【问题标题】:QDockWidget::restoreGeometry not working correctly when QMainWindow is maximizedQDockWidget::restoreGeometry 在 QMainWindow 最大化时无法正常工作
【发布时间】:2017-10-15 19:04:13
【问题描述】:

我有多个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 未最大化时确实有效,但当它最大化时,小部件无法正确恢复。

this image 中,我已经在关闭之前安排了我的小部件。 (已链接,因为内联图像会太大)

this image 中,我重新加载了我的应用程序,但小部件的几何图形加载不正确。

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

我已向自己证明设置已正确保存并再次恢复,但不知何故无法正常工作

关闭应用;保存状态:

save: 01d9d0cb000200000000053f000000640000077f000001a00000053f000000640000077f000001a000000000000000000780

打开应用;恢复状态:(这里的十六进制数据与保存的完全一致)

rest: 01d9d0cb000200000000053f000000640000077f000001a00000053f000000640000077f000001a000000000000000000780

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

save: 01d9d0cb000200000000053f000000640000077f0000014e0000053f000000640000077f0000014e00000000000000000780
                                                    ^                               ^

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

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

我在 Ubuntu 16.04 上使用 Qt 5.5。

【问题讨论】:

    标签: c++ qt qmainwindow qdockwidget


    【解决方案1】:

    这是 Qt 中的一个错误。具体来说,QTBUG-46620 可能还有QTBUG-16252

    QTBUG-46620 的错误报告详细介绍了一种解决方法,您应该尝试一下。首先,确保在关闭应用程序时保存主窗口几何图形和主窗口状态(请注意,您不必单独保存每个停靠窗口的几何图形):

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

    然后,按如下方式恢复几何:

    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());
    

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

    【讨论】:

    • 谢谢,第一个建议效果很好!事实上,唯一需要改变的是使用geometrysetGeometry 而不是saveGeometry / restoreGeometry
    • 我在 ubuntu 20.04 和 python 3.6 下也有同样的问题。此答案中的解决方法对我不起作用,但是如果我添加一个具有我喜欢的大小的虚拟停靠小部件,并通过单次 QTimer 操作删除,则停靠小部件的大小不会再次更改。另外,还有一个resizeDocks方法,不过据我了解这个方法是用来设置同一区域docks的相对大小,而不是设置不同区域docks的大小
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-07-17
    • 2021-12-26
    • 2021-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多