【问题标题】:Qt Resizing a QMainWindow with a SplitterQt 使用拆分器调整 QMainWindow 的大小
【发布时间】:2011-11-21 16:38:10
【问题描述】:

我有一个 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;
}

【问题讨论】:

    标签: c++ qt resize qsplitter


    【解决方案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() );
    

    再次显示您的小部件时,您需要再次调整尺寸政策。

    【讨论】:

    • 谢谢,问题解决了!感谢您指出 QTimer::singleShot 方法,它会派上用场!
    猜你喜欢
    • 1970-01-01
    • 2018-10-29
    • 2013-11-15
    • 2012-10-01
    • 2023-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多