1

私は QMainWindow を持っています:

  • 水平スプリッターの 2 つのウィジェット。右側が「m_liner」
    • 両方のウィジェットの最小サイズは、たとえば 300 ピクセルです。
  • 右側のウィジェット m_liner を非表示/表示するためのチェックボックス。

ウィジェットを表示するときはQMainWindow 全体を拡大し、非表示にするときは縮小します。以下のコードは、以下を除いてこれを行います。

  • 両方のウィジェットが表示されている場合、ウィンドウの最小サイズは 600 ピクセルです。
  • ウィンドウをこの最小サイズに縮小します。
  • 右側のウィジェットを非表示にするには、ボックスのチェックを外します。
  • プログラムは右側のウィジェットを非表示にします。
  • プログラムはこれを呼び出します->resize(300, height);
  • ウィンドウは、約 300 ピクセル (左側のウィジェットのみの最小サイズ) ではなく、最終的に 600 ピクセル幅 (両方のウィジェットが表示される最小サイズ) になります。
  • 後で、マウスまたは別のボタンを使用して、ウィンドウのサイズを 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;
}
4

1 に答える 1

1

メインウィンドウのサイズを変更できることを認識する前に、伝播する必要がある内部Qtイベントがいくつかあるように思えます。この場合、2 つの解決策が考えられます。

キューに入れられたシングル ショット タイマーを使用して、ウィンドウのサイズを 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() );

ウィジェットを再度表示するときは、サイズ ポリシーを再度調整する必要があります。

于 2011-11-22T00:31:12.283 に答える