如何在调用restoreState()后恢复QDockWidget?

问题描述 投票:0回答:1

QT版本:2014年5月15日 系统:MSY2/UCRT64(最新)

我的 QMainWindow 左侧有一个 QDockWidget。

当用户与其交互时,该小部件会自动调整大小。

一开始效果很好,但如果用户关闭程序并重新启动它,突然扩展坞可以增长到它需要的新大小,但永远不会正确缩小。

当我们从 QSettings 恢复时,我已经找到了问题所在:

restoreState(qsettings.value("windowState", saveState()).toByteArray());

正如文档所说,这也会恢复 QDockWidgets 的状态。不幸的是,由于某种原因,它破坏了这个特定小部件的大小调整。

如何在restoreState()之前保存该特定停靠小部件的状态,然后撤消restoreState()所做的任何操作?

我尝试过以下方法:

  Qt::WindowStates dockState = ui->dockWidget_left->windowState();
  restoreState(qsettings.value("windowState", saveState()).toByteArray());
  ui->dockWidget_left->setWindowState(dockState);

但遗憾的是这似乎没有任何区别。

我还尝试查看restoreState()调用之前和之后的各种值,例如minimumWidth()、maximumWidth()、sizeHint()、baseSize()、width()和sizePolicy() - 但似乎没有受到影响通过电话。

为了更完整的上下文,整个结构如下所示:

一个 QVBoxLayout,其中包含一个 QWidget,其中包含一个 QTreeWidget,其中有一个 QHeaderView。

通过调整 QTreeWidget() 的最小宽度来增大和缩小。 QWidget 的大小类型为 Preferred,而 QDockWidget 使用 maximum 来尝试将其缩小到所需的最小值。

因为

ResizeMode::ResizeToContents()
在标题视图的第一列上无法正常工作,我创建了一个函数来手动计算其所需的大小并应用它。每次展开或折叠树上的元素时都会调用它。

即:

(树的构造函数内部)

{
  QHeaderView* h = m_tree->header();
  h->setSectionResizeMode(0, QHeaderView::ResizeMode::ResizeToContents);
  h->setSectionResizeMode(1, QHeaderView::ResizeMode::ResizeToContents);
  h->setSectionResizeMode(2, QHeaderView::ResizeMode::ResizeToContents);

  connect(m_tree, &QTreeWidget::itemExpanded, this, onTreeExpansionsChanged);
  connect(m_tree, &QTreeWidget::itemCollapsed, this, onTreeExpansionsChanged);
}

(以及调整大小的函数)

void MyTree::onTreeExpansionsChanged(QTreeWidgetItem* item)
{
  double dpiX = static_cast<double>(QPaintDevice::logicalDpiX());
  double scale = dpiX / 240.0;

  // Size offsets to account for the fact that
  // QHeaderView::ResizeMode::ResizeToContents() does not function 
  // properly on the first column - though it works fine on the others
  // These sizes represent the minimum size in pixels needed to prevent
  // that node from having its text cut-off when it's fully expanded.
  int emptyMinSize = (132 + 50) * scale;
  int node0Size = (166 + 75) * scale;
  int node1Size = (203 + 125) * scale;
  int node2Size = (399 + 125) * scale;
  int node3Size = (172 + 125) * scale;
  int node4Size = (515 + 150) * scale;
  int node5Size = (381 + 175) * scale;
  int node6Size = (167 + 125) * scale;
  int node7Size = (166 + 75) * scale;
  int node8Size = (166 + 450) * scale;

  QHeaderView* h = m_tree->header();

  h->resizeSections(QHeaderView::ResizeMode::ResizeToContents);
  int sectionSize0 = h->sectionSize(0);
  int sectionSize1 = h->sectionSize(1);
  int sectionSize2 = h->sectionSize(2);
  h->setSectionResizeMode(0, QHeaderView::ResizeMode::Fixed);

  int newSizeCol0 = sectionSize0;

  newSizeCol0 = std::max(emptyMinSize, newSizeCol0);

  if (node0->isExpanded())
    {
      newSizeCol0 = std::max(node0Size , newSize0);
    }
  if (node1->isExpanded())
    {
      newSizeCol0 = std::max(node1Size, newSizeCol0);
    }
  if (node2->isExpanded())
    {
      newSizeCol0 = std::max(node2Size, newSizeCol0);
    }
  if (node3->isExpanded())
    {
      newSizeCol0 = std::max(node3Size, newSizeCol0);
    }
  if (node4->isExpanded())
    {
      newSizeCol0 = std::max(node4Size, newSizeCol0);
    }
  if (node5->isExpanded())
    {
      newSizeCol0 = std::max(node5Size, newSizeCol0);
    }
  if (node6->isExpanded())
    {
      newSizeCol0 = std::max(node6Size, newSizeCol0);
    }
  if (node7->isExpanded())
    {
      newSizeCol0 = std::max(node7Size, newSizeCol0);
    }
  if (node8->isExpanded())
    {
      newSizeCol0 = std::max(node8Size, newSizeCol0);
    }

  int newTotalSize = newSize0 + sectionSize1 + sectionSize2;
  m_tree->setMinimumWidth(newTotalSize * 1.05);

  // All of the following do not help, commented out for now
  //m_tree->setMaximumWidth(newTotalSize * 1.10);
  //h->resizeSection(0, newSize0);
  //h->setMinimumWidth(newTotalSize * 1.05);
  //h->setMaximumWidth(newTotalSize * 1.10);
  //h->adjustSize();

  // m_mw->ui->dockWidget_contents->setMinimumWidth(newTotalSize * 1.1);
  // m_mw->ui->dockWidget_contents->setMaximumWidth(newTotalSize * 1.5);
  // m_mw->ui->dockWidget_contents->adjustSize();
}

关于如何撤消恢复状态()对特定停靠小部件所做的任何事情,有什么想法吗?

c++ qt qt5
1个回答
0
投票

调整停靠小部件本身(而不是其内容)的最大宽度最终起作用 - 没有其他因素解决它。我已将乘数更改为 DPI 缩放偏移,这看起来更好一些。

这是必要的,这有点烦人 - 因为 ResizeToContents 拒绝在树的第一列上正常工作,并且似乎没有办法有选择地撤消特定停靠小部件上的 restoreState() 的工作。但这不是一个大问题。

© www.soinside.com 2019 - 2024. All rights reserved.