Janik Zikovsky
Janik Zikovsky

Reputation: 3256

Qt Resizing a QMainWindow with a Splitter

I have a QMainWindow with:

I want the overall QMainWindow to expand when showing the widget, and shrink when hiding. The code below does this except:

Does anyone have an idea how to solve this?

Critical bit of code follows, I have a full project available if you need it:

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

Upvotes: 1

Views: 2593

Answers (1)

Chris
Chris

Reputation: 17535

Sounds to me like there are some internal Qt events that need to get propagated before it recognizes that you can resize the main window. If this is the case then I can think of two potential solutions:

Use a queued single shot timer to call the code that resizes your window down to 300px:

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

or, after you hide your widget you can try a call to processEvents() (this function has potentially dangerous side effects, so use with caution):

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

Another potential solution would be to set the horizontal size policy of your widget to ignored when hiding it:

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.

Upvotes: 1

Related Questions