调用restoreState()后如何恢复QDockWidget的正常缩放功能?
解决QMainWindow restoreState()破坏QDockWidget缩放的问题
核心思路是跳过restoreState()对目标QDockWidget的尺寸恢复,下面提供两种可行的实现方式:
方法一:过滤窗口状态中的目标QDockWidget信息
Qt的saveState()保存的字节流包含所有停靠部件的状态数据,我们可以读取后过滤掉目标QDockWidget的部分,再用过滤后的状态恢复:
QByteArray savedState = qsettings.value("windowState", saveState()).toByteArray(); QDataStream readStream(&savedState, QIODevice::ReadOnly); // 读取Qt版本号(restoreState会校验该版本,必须保留) quint32 version; readStream >> version; QByteArray filteredState; QDataStream writeStream(&filteredState, QIODevice::WriteOnly); writeStream << version; // 遍历所有部件状态,跳过目标dock while (!readStream.atEnd()) { QString objName; QByteArray stateData; readStream >> objName >> stateData; if (objName != ui->dockWidget_left->objectName()) { writeStream << objName << stateData; } } // 用过滤后的状态恢复窗口 restoreState(filteredState); // 手动触发尺寸计算,确保dock处于正确大小 ui->dockWidget_left->widget()->adjustSize(); onTreeExpansionsChanged(nullptr); // 调用你的缩放逻辑
方法二:移除并重新添加QDockWidget清除内部约束
如果过滤状态太麻烦,也可以先恢复整体状态,再通过移除重新添加的方式清除Qt内部记录的尺寸约束:
// 先保存dock的原始停靠区域和可见性 Qt::DockWidgetArea originalArea = dockWidgetArea(ui->dockWidget_left); bool wasVisible = ui->dockWidget_left->isVisible(); // 恢复整体窗口状态 restoreState(qsettings.value("windowState", saveState()).toByteArray()); // 移除并重新添加dock,清除内部尺寸缓存 removeDockWidget(ui->dockWidget_left); addDockWidget(originalArea, ui->dockWidget_left); ui->dockWidget_left->setVisible(wasVisible); // 强制触发尺寸调整 ui->dockWidget_left->widget()->adjustSize(); onTreeExpansionsChanged(nullptr);
针对你的代码的额外修正建议
- 你的
onTreeExpansionsChanged函数里有笔误:newSize0应该是newSizeCol0,修正后才能保证逻辑正确。 - 把QDockWidget的尺寸策略改成
Preferred,避免限制自动缩放:
ui->dockWidget_left->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
- 在计算完总宽度后,调用
m_tree->adjustSize()让布局重新计算:
int newTotalSize = newSizeCol0 + sectionSize1 + sectionSize2; m_tree->setMinimumWidth(newTotalSize * 1.05); m_tree->adjustSize();
内容的提问来源于stack exchange,提问作者Tyler Shellberg
相关产品推荐
相关产品推荐

