1

我有一个 QMainWindow:

  • 水平拆分器中的两个小部件。“m_liner”在右侧
    • 两个小部件的最小尺寸为 300 像素。
  • 隐藏/显示右侧小部件 m_liner 的复选框。

我希望整个 QMainWindow在显示小部件时展开,并在隐藏时缩小。下面的代码执行此操作,除了:

  • 如果两个小部件都显示,则最小窗口大小为 600 像素。
  • 将窗口缩小到这个最小尺寸。
  • 取消选中该框以隐藏右侧小部件。
  • 程序隐藏右侧小部件。
  • 程序调用 this->resize(300, height);
  • 窗口最终是 600 像素宽(两个小部件都可见的最小尺寸),而不是大约 300 像素(只有左侧小部件的最小尺寸)。
  • 稍后,我可以使用鼠标或其他按钮将窗口大小调整为 300 像素。但它不会在复选框事件中调整为 300,即使我多次调用 resize 也是如此。

有谁知道如何解决这个问题?

下面是关键代码,如果您需要,我有一个完整的项目可用:

void MainWindow::on_checkBox_stateChanged(int val)
{
std::cout << "-------------------- Checkbox clicked "  << val << std::endl;
bool visible = val;
QWidget * m_liner = ui->textEdit_2;
QSplitter * m_splitter = ui->splitter;

int linerWidth = m_liner->width();
if (linerWidth <= 0) linerWidth = m_lastLinerWidth;
if (linerWidth <= 0) linerWidth = m_liner->sizeHint().width();
// Account for the splitter handle
linerWidth += m_splitter->handleWidth() - 4;

std::cout << "Frame width starts at " << this->width() << std::endl;
std::cout << "Right Panel width is " << m_liner->width() << std::endl;

//  this->setUpdatesEnabled(false);
if (visible && !m_liner->isVisible())
{
  // Expand the window to include the Right Panel
  int w = this->width() + linerWidth;
  m_liner->setVisible(true);
  QList<int> sizes = m_splitter->sizes();
  if (sizes[1] == 0)
  {
    sizes[1] = linerWidth;
    m_splitter->setSizes(sizes);
  }
  this->resize(w, this->height());
}
else if (!visible && m_liner->isVisible())
{
  // Shrink the window to exclude the Right Panel
  int w = this->width() - linerWidth;
  std::cout << "Shrinking to " << w << std::endl;
  m_lastLinerWidth = m_liner->width();
  m_liner->setVisible(false);
  m_splitter->setStretchFactor(1, 0);
  this->resize(w, this->height());
  m_splitter->resize(w, this->height());
  this->update();
  this->resize(w, this->height());
}
else
{
  // Toggle the visibility of the liner
  m_liner->setVisible(visible);
}
this->setUpdatesEnabled(true);
std::cout << "Frame width of " << this->width() << std::endl;
}
4

1 回答 1

1

在我看来,在它识别出您可以调整主窗口大小之前,需要传播一些内部 Qt 事件。如果是这种情况,那么我可以想到两个潜在的解决方案:

使用排队的单次计时器调用将窗口大小调整为 300 像素的代码:

m_liner->hide();
QTimer::singleShot( 0, this, SLOT(resizeTo300px()) );

或者,在隐藏小部件后,您可以尝试调用 processEvents()(此函数具有潜在危险的副作用,因此请谨慎使用):

m_liner->hide();
QApplication::processEvents();
resize( w, height() );

另一个可能的解决方案是将小部件的水平尺寸策略设置为在隐藏时忽略:

m_liner->hide();
m_liner->setSizePolicy( QSizePolicy::Ignored, QSizePolicy::Preferred );
resize( w, height() );

When showing your widget again, you'd need to adjust the size policy again.

于 2011-11-22T00:31:12.283 回答