Qt Изменение размера QMainWindow с помощью Splitter - PullRequest
1 голос
/ 21 ноября 2011

У меня есть QMainWindow с:

  • Два виджета в горизонтальном разделителе. "m_liner" находится на правой стороне
    • Оба виджета имеют минимальный размер, скажем, 300 пикселей.
  • Флажок для скрытия / отображения правого виджета m_liner.

Я хочу, чтобы общее окно QMainWindow раскрывалось при отображении виджета, а уменьшалось при скрытии. Код ниже делает это за исключением:

  • Если отображаются оба виджета, минимальный размер окна составляет 600 пикселей.
  • Уменьшите окно до наименьшего размера.
  • Снимите флажок, чтобы скрыть виджет справа.
  • Программа скрывает виджет справа.
  • Программа вызывает this-> resize (300, height);
  • Окно заканчивается шириной 600 пикселей (минимальный размер с видимыми обоими виджетами) вместо 300 (минимальный размер только с левым виджетом).
  • Позже я могу изменить размер окна до 300 пикселей с помощью мыши или другой кнопки. Но это не изменит размер до 300 в событии флажка, даже если я вызову изменение размера несколько раз.

У кого-нибудь есть идеи, как это решить?

Далее следует критический фрагмент кода, у меня есть полный проект, если он вам нужен:

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;
}

1 Ответ

1 голос
/ 22 ноября 2011

Звучит так, будто есть некоторые внутренние события Qt, которые необходимо распространить, прежде чем он узнает, что вы можете изменить размер главного окна.Если это так, то я могу подумать о двух возможных решениях:

Использование таймера одиночного броска в очереди для вызова кода, который изменяет размер вашего окна до 300px:

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

При повторном отображении виджета вам нужно будет снова настроить политику размеров.

...