ドックエリアのサイズの制御に関して、長年にわたってさまざまな投稿がありQDockWidget
ました。QMainWindow
私もこの問題に苦労しており、部分的でやや不十分な解決策しか達成できませんでした. 主な問題 (しゃれを許すなら) は、QMainWindow
ドック領域を管理する作業を行う のコンテキストからドッキング メカニズムを把握できないことです。レイアウト管理 (サイズ ポリシーとサイズ ヒント コントロール) を使用しようとしても効果がありません。QMainWindow
ドック領域のサイズを変更すると、独自の処理が行われます。
まず、私が得た限られた成功:
QMainWindow
サブクラス ( MW
) とQDockWidget
サブクラス( )から始めDW
ます。にはDW
がありQWidget
、QHBoxLayout
はsetWidget
にありDW
ます。このレイアウトには 2 つのウィジェット (パネルと呼びます) があり、これらのパネルの 1 つはコンテキストに応じて表示または非表示にすることを意図してDW
います。構築後の他のパネルのsizeHint
は、(適切なマージン間隔と共に) の「ベース サイズ」を設定するために使用されます。パネルDW
の構築されたsizeHint
幅は、必要に応じてベース サイズの増分を提供する可視性を変更します。DW
実装は次のとおりです。を提供panel_visible
setVisible をパネルに適用sizeHint
し、インクリメント値によって の値を変更することによって、変数パネルを有効または無効にするために使用されるメソッド。とそのパネルのサイズ ポリシーは [DW
最小] に設定されています。
との信号はスロットに接続されMW
ます。ここで、が false で、 または のいずれかを報告すると、有効サイズを変更するためにが呼び出されます (上記の条件が満たされない場合は、もちろん が呼び出されます)。、およびを呼び出しても、ドック領域のサイズには影響しません。ただし、が呼び出された場合、ドック領域は正しくサイズ変更されます (いいえまたは必要ありません)。これは、をフローティング (タイトル バーをドラッグまたはダブルクリック) してから再ドッキング (タイトル バーをダブルクリックまたはドラッグしてサイド ドック領域に戻す) したときに、必要に応じて機能します。ここまでは順調ですね。DW
dockLocationChanged
topLevelChanged
DW_resize
DW
isVisible
isWindow
MW::dockWidgetArea
LeftDockWidgetArea
RightDockWidgeArea
DW::panel_visible(false)
DW
DW::panel_visible(true)
DW::resize
updateGeometry
update
MW
DW::setMaximumSize(DW::sizeHint())
updateGeometry
update
DW
今キャッチ:
MW
ドック領域を所定のDW
サイズに合わせるようにを強制したら、固定サイズの制約から解放する必要があります。これにより、ユーザーは、 によって提供されるスピット ハンドルをドック領域と中央領域DW
の間にドラッグしてドック領域のサイズを変更できます。MW
明らかな答えは、制約DW::setMaximumSize(0xFFFFFF, 0xFFFFFF)
を「解放」するように呼び出すことです。DW
はい。ただし、バックグラウンドで実行されるペイントの最適化の更新によって 2 つのサイズ変更イベントが結合され、その結果、最初のドック縮小アクションが失われます。2 つの呼び出しの間にqApp->sendPostedEvents()
andを配置することで、この最適化効果が回避されます。ドック領域はサイズに合わせて解放されたままになるため、ユーザーはドック領域のサイズを変更できます ... 場合によっては.qApp->flush()
setMaxmimumSize
DW
このソリューションは、タイトル バーDW
をダブルクリックして がフローティング状態からドッキング状態になった場合には機能しますが、 がのサイド ドックにドラッグされた場合には機能しません。たとえば、ユーザーが左側のドックから右側のドックにドラッグすると、右側のドック領域のサイズが期待どおりに変更されません。受信ドック領域は、片側から別の側へのドラッグ中に生成されるフローティングのサイズのままです。受信ドック領域ののタイトル バーがダブルクリックされ (再びフローティング状態になる)、再度ダブルクリックされた (同じドック領域に戻る) 場合、が意図したとおりにドック領域に収まるようになりました。綿密な検査で - を監視することにより- ドック領域が意図したサイズになると、DW
DW
MW
DW
DW
DW
MW
MW::paintEvent
flush()
直後に apaintEvent
が続き、DW
レポートが意図したサイズを持ち、setMaximumSize
制約を解除する2 番目の後にDW
aが意図しpaintEvent
たサイズで発生しDW
ます。しかし、DW
がドック領域にドラッグされると、flush()
すぐにレポートが意図したサイズのpaintEvent
場所に続きますが、この場合、2 番目の後に 2 つの があり、驚くべきことに以前の浮動サイズになっています!DW
setMaximumSize
paintEvent
DW
DW
サイズが正しく設定された後、この説明のつかないサイズのオーバーライドを防ぐ方法をまだ見つけていません。スロットにつながる信号が発信される前から が保持していたサイズ情報から、スロット処理が戻ったMW
後にによって追加のサイズ変更イベントが生成されていることは明らかです。を監視すると、サイズがスロット コードで設定されていたサイズからフローティングしていたときのサイズに戻る が返された後に発生する Resize イベントが実際に明らかになります。タイル バーをダブルクリックしてフローティングからサイド ドックに戻す場合、スロットが戻った後に追加の Resize イベントは発生しません。DW_resize
MW
MW::eventFilter
DW_resize
DW
DW
DW
DW_resize
したがって、課題は、 がスロットDW
で正しくサイズ変更された後に、予期しないサイズ変更の復帰が発生しないようにする方法です。DW_resize
おそらく、いくつかの強制DW::resizeEvent
がこの問題を回避するでしょう....
もちろん、Qt 開発者がQMainWindow
ドック管理アクティビティ (特にドック領域のサイジング) および/またはドック領域管理に使用するウィジェットへのアクセスを API で完全に制御できるように、Qt 開発者がアプリケーション開発者に提供することをお勧めします。
現在、Linux、OS X、および MS/Windows で Qt 4.6.2 を使用しています。上記のデバッグ レポートは、Intel OS X 10.6.7 システムで実行されました。結果はプラットフォームによって多少異なりますが、基本的な問題は同じです。おそらく、これらQMainWindow
/のQDockWidget
問題は Qt の新しいバージョンで対処されているのでしょうか? おそらく、誰かがここで何が起こっているのかについてより深い洞察を持ち、簡単な解決策を提供できますか?