web-dev-qa-db-ja.com

C ++はドッキングされたQtQDockWidgetをプログラムでサイズ変更しますか?

新しいC++/Qtプロジェクトに取り組み始めたところです。これは、MDIベースのIDEで、ファイルツリー、オブジェクトブラウザー、コンパイラ出力などのウィジェットがドッキングされています。これまでのところ、1つ問題があります。理解できません。プログラムでQDockWidgetを小さくする方法を説明します。たとえば、このスニペットは、下部のドックウィンドウ「ビルド情報」を作成します。

_m_compilerOutput = new QTextEdit;
m_compilerOutput->setReadOnly(true);
dock = new QDockWidget(tr("Build Information"), this);
dock->setWidget(m_compilerOutput);
addDockWidget(Qt::BottomDockWidgetArea, dock);
_

起動すると、私のプログラムは次のようになります(開発の初期段階を念頭に置いてください)。

Actual

ただし、次のように表示したいと思います。

Expected

私はこれを起こさせることができないようです。 QDockWidgetのQtリファレンスには次のように書かれています。

カスタムサイズのヒント、最小および最大サイズ、サイズポリシーは、子ウィジェットに実装する必要があります。 QDockWidgetはそれらを尊重し、フレームとタイトルを含むように独自の制約を調整します。サイズ制約は、ドッキングされているかどうかによって変わるため、QDockWidget自体に設定しないでください。

さて、これは、これを実行する1つの方法が、QTextEditをサブクラス化し、sizeHint()メソッドをオーバーライドすることであることを示唆しています。しかし、私はその目的のためだけにこれを行うことを望まず、またそれが実用的な解決策であると見つけることを試みたことがありません。

dock->resize(m_compilerOutput->width(), m_compilerOutput->minimumHeight())を呼び出し、各オプションを指定してm_compilerOutput->setSizePolicy()を呼び出してみました...これまでのところ、サイズに影響はありません。私が言ったように、私はsizeHint()を変更するためだけにサブクラスを作成するよりも、数行のコードで単純なソリューションを好むでしょう。すべての提案を歓迎します。

26
Zac

私はこれと同じプロセスを経たところです。ドックウィジェットとそれに含まれるウィジェットでresize()adjustSize()とその仲間の順列をあまりにも多く試した後、どれも機能しませんでしたが、結局QListViewをサブクラス化して追加しましたsizeHint()メソッド。

今ではそれは魅力のように機能します。

4
Charl Botha

私はそれを簡単にしました:ヘッダー:

private void setDockSize(QDockWidget *dock, int, int);
  public slots:
  void returnToOldMaxMinSizes();

ソース:

QSize oldMaxSize, oldMinSize;

void MainWindow::setDockSize(QDockWidget* dock, int setWidth,int setHeight)
{

    oldMaxSize=dock->maximumSize();
    oldMinSize=dock->minimumSize();

  if (setWidth>=0)
    if (dock->width()<setWidth)
        dock->setMinimumWidth(setWidth);
    else dock->setMaximumWidth(setWidth);
  if (setHeight>=0)
    if (dock->height()<setHeight)
        dock->setMinimumHeight(setHeight);
    else dock->setMaximumHeight(setHeight);

    QTimer::singleShot(1, this, SLOT(returnToOldMaxMinSizes()));
}

void MainWindow::returnToOldMaxMinSizes()
{
    ui->dockWidget->setMinimumSize(oldMinSize);
    ui->dockWidget->setMaximumSize(oldMaxSize);
}
7
semenvx

ドックウィジェットは、その子ウィジェットを考慮して、適切なサイズにサイズ変更されているようです。 QDockWidgetのドキュメントから(私の強調):

QDockWidgetは、setWidget()で設定された子ウィジェットのラッパーとして機能します。カスタムサイズのヒント、最小サイズと最大サイズ、およびサイズポリシーは子ウィジェットに実装する必要があります。 QDockWidgetはそれらを尊重し、フレームとタイトルを含むように独自の制約を調整します。サイズ制約は、ドッキングされているかどうかによって変わるため、QDockWidget自体に設定しないでください。ドッキングされたQDockWidgetには、フレームがなく、タイトルバーが小さくなっています。

次に、サイズを変更するには、子ウィジェットのサイズを変更する必要があります。

編集:サイズのヒントについて説明している場合、Qtのドキュメントは誤解を招くことがあります。多くの場合、ウィジェットによって自動的に実行されるか、プログラムで実行されるかに関係なく、あらゆる種類のサイズ変更を指します。

6
TreDubZedd

これは古い質問ですが、Qt 5.6でこれを処理するために QMainWindow :: resizeDocks 関数が導入されたことに言及したいと思います。

残念ながら、それは 私のユースケース (QMainWindows :: splitDockWidgetで分割された2つのQDockWidgets間でセパレーターを移動する)では機能しません

6
Alex Goldberg

あなたはこれを行うことができます:

QTextEditの最大の高さを設定します。

m_compilerOutput = new QTextEdit;
m_compilerOutput->setMaximumHeight(100);

次に、メインウィンドウの show event で、古いサイズまたは何か高いサイズに戻します。

void MainWindow::showEvent(QShowEvent *)
{
   m_compilerOutput->setMaximumHeight(10000);
}

必要なのはそれだけです。

2
thuga

ドックウィジェット内のQTextEditresize()を呼び出してみましたか?ドックウィジェットの最大サイズと最小サイズを一時的に希望のサイズに設定してから、元の値に戻すこともできます。

2
Kitsune

DockWidgetsがドッキングされている場合、サイズは親によって制御されます。このような場合は、QMainWindow::resizeDocks関数を使用できます。

フローティングの場合、サイズは子によって決定されます。子のサイズを変更目的を達成するため。

1
momo

QDockWidget::widget()(つまり、QDockWidgetが管理しているウィジェット)でサイズ変更を使用したテストは、期待どおりに一貫して機能しません。

QDockWidgetサブクラス(DW)で、2つのウィジェット(左パネルと右パネル)を持つQWidgetを持つQHBoxLayoutが追加されました、すべてのサイズポリシーが_QSizePolicy::Minimum_に設定されている場合、DWでは通常両方のパネルウィジェットが表示されます。 DWがサイドドックに配置されると、DWのQMainWindow信号を処理するアプリケーション(dockLocationChanged)スロットが左側のパネルを非表示にし、DW->widget()のサイズを右側のサイズに変更します。 -パネル。 DWがプログラムで下部のドック領域に移動されると、leftPanelが表示され、DWがメインウィンドウの幅全体に表示されます(もちろん)。次に、DWがプログラムでサイドドック領域に移動されると、左側のパネルが非表示になり、DWのサイズが変更されます。これは意図したとおりに機能します。ただし、DWを下部ドック領域から側面ドック領域にドラッグすると、左側のパネルが非表示になり、以前のようにサイズ変更が適用されますが、プログラムで再配置が行われる場合のようにDWのサイズが変更されません。 DWとメインウィンドウの中央領域の間でスプリッターハンドルをドラッグすることにより、DWのサイズを手動で変更できます。メインウィンドウの中央領域はQWidgetであり、QHBoxLayoutがあり、サイズポリシーは_QSizePolicy::Expanding_であることに注意してください。

DWのサイズが変更された後、メインウィンドウでadjustSizeを呼び出しても効果はありません。これは、DWがsizeHintを再実装して、左側のパネルが表示されているかどうかに応じて最小サイズを返すにもかかわらずです。

QDockWidgetのサイズを制御する方法に何かが欠けている(レイアウト管理システムの各部分間のすべての相互作用を理解するのが難しいことを考えると、おそらくそうです)、またはQMainWindowは、与えられているレイアウト命令を無視またはオーバーライドしています。 QDockWidget再配置操作中にイベントストリームを詳しく調べると、後者が示唆されます。dockLocationChanged信号を処理するスロットがサイズ変更作業を完了し、イベントループに戻った後、QMainWindowは、ユーザーの再配置が行われると、影響を受けるQDockWidgetに追加のサイズ変更操作を適用し、ドックサイズを制御しようとするアプリケーションロジックを元に戻します。 QMainWindow...で何かがおかしいようです。

1
user674263

MainWindowが最大化されたときのドックウィジェットのサイズ変更の問題は、QTBUG-16252( https://bugreports.qt.io/browse/QTBUG-16252 )で説明されています。

別の回避策を見つけました。 Windows7のQT5.4.1minGWで動作します。一部のウィジェット状態の復元操作は、QApplicationイベントループに密接に関連しているようです。

DockWidgetのサイズは、次の条件が満たされた場合にのみ正しく復元されます。

  1. restoreGeometry()は、QApplication :: exec()に入る前に呼び出されます(たとえば、MainWindowクラスのコンストラクターで)

  2. restoreState()はexec()の後に呼び出されます(例:QTimer経由)

これが私のコードです:

int main(int argc, char *argv[])
{
    QApplication application(argc, argv);

    //...

    MainWindow mainWindow;
    mainWindow.show();

    return application.exec();
}

MainWindow::MainWindow(...) 
{
    ui->setupUi(this);

    //...
    QTimer* nt = new QTimer(this);

    nt->setSingleShot(true);
    nt->setInterval( 100 );

    connect(nt, SIGNAL(timeout()), SLOT(restoreWidgetSettings()));
    nt->connect(nt, SIGNAL(timeout()), SLOT(deleteLater()));

    nt->start();

    restoreWidgetSettings(true);
}

void MainWindow::restoreWidgetSettings(bool geometryOnly) {

    //...
    QByteArray geometry = getSettings();

    restoreGeometry(geometry);

    if(geometryOnly)
        return;

    //... //create dock widgets here

    restoreState(mainWindowState);

}
0
vrogach