2

の 1 つで問題に直面していQDockWidgetます。私はいくつかのQWidgetアイテムを持っていますQDockwidgetが、時々見えないことがあります。

内容に応じてリサイズしてほしいのですが…出現QDockWidget時だけでなく、消滅時も…QWidgets

これまでのところ、さらに表示されるとQDockWidgetサイズが自動的に変更QWidgetsされますが、それらを非表示にすると、QDockWidget以前のサイズのままです...

役立つアイデアはありますか?

前もって感謝します!

4

2 に答える 2

6

ドックエリアのサイズの制御に関して、長年にわたってさまざまな投稿がありQDockWidgetました。QMainWindow私もこの問題に苦労しており、部分的でやや不十分な解決策しか達成できませんでした. 主な問題 (しゃれを許すなら) は、QMainWindowドック領域を管理する作業を行う のコンテキストからドッキング メカニズムを把握できないことです。レイアウト管理 (サイズ ポリシーとサイズ ヒント コントロール) を使用しようとしても効果がありません。QMainWindowドック領域のサイズを変更すると、独自の処理が行われます。

まず、私が得た限られた成功:

QMainWindowサブクラス ( MW) とQDockWidgetサブクラス( )から始めDWます。にはDWがありQWidgetQHBoxLayoutsetWidgetにありDWます。このレイアウトには 2 つのウィジェット (パネルと呼びます) があり、これらのパネルの 1 つはコンテキストに応じて表示または非表示にすることを意図してDWいます。構築後の他のパネルのsizeHintは、(適切なマージン間隔と共に) の「ベース サイズ」を設定するために使用されます。パネルDWの構築されたsizeHint幅は、必要に応じてベース サイズの増分を提供する可視性を変更します。DW実装は次のとおりです。を提供panel_visiblesetVisible をパネルに適用sizeHintし、インクリメント値によって の値を変更することによって、変数パネルを有効または無効にするために使用されるメソッド。とそのパネルのサイズ ポリシーは [DW最小] に設定されています。

との信号はスロットに接続されMWます。ここで、が false で、 または のいずれかを報告すると、有効サイズを変更するためにが呼び出されます (上記の条件が満たされない場合は、もちろん が呼び出されます)。、およびを呼び出しても、ドック領域のサイズには影響しません。ただし、が呼び出された場合、ドック領域は正しくサイズ変更されます (いいえまたは必要ありません)。これは、をフローティング (タイトル バーをドラッグまたはダブルクリック) してから再ドッキング (タイトル バーをダブルクリックまたはドラッグしてサイド ドック領域に戻す) したときに、必要に応じて機能します。ここまでは順調ですね。DW dockLocationChangedtopLevelChangedDW_resizeDW isVisibleisWindowMW::dockWidgetAreaLeftDockWidgetAreaRightDockWidgeAreaDW::panel_visible(false)DWDW::panel_visible(true)DW::resizeupdateGeometryupdateMWDW::setMaximumSize(DW::sizeHint())updateGeometryupdateDW

今キャッチ:

MWドック領域を所定のDWサイズに合わせるようにを強制したら、固定サイズの制約から解放する必要があります。これにより、ユーザーは、 によって提供されるスピット ハンドルをドック領域と中央領域DWの間にドラッグしてドック領域のサイズを変更できます。MW明らかな答えは、制約DW::setMaximumSize(0xFFFFFF, 0xFFFFFF)を「解放」するように呼び出すことです。DWはい。ただし、バックグラウンドで実行されるペイントの最適化の更新によって 2 つのサイズ変更イベントが結合され、その結果、最初のドック縮小アクションが失われます。2 つの呼び出しの間にqApp->sendPostedEvents()andを配置することで、この最適化効果が回避されます。ドック領域はサイズに合わせて解放されたままになるため、ユーザーはドック領域のサイズを変更できます ... 場合によっては.qApp->flush()setMaxmimumSizeDW

このソリューションは、タイトル バーDWをダブルクリックして がフローティング状態からドッキング状態になった場合には機能しますが、 がのサイド ドックにドラッグされた場合には機能しません。たとえば、ユーザーが左側のドックから右側のドックにドラッグすると、右側のドック領域のサイズが期待どおりに変更されません。受信ドック領域は、片側から別の側へのドラッグ中に生成されるフローティングのサイズのままです。受信ドック領域ののタイトル バーがダブルクリックされ (再びフローティング状態になる)、再度ダブルクリックされた (同じドック領域に戻る) 場合、が意図したとおりにドック領域に収まるようになりました。綿密な検査で - を監視することにより- ドック領域が意図したサイズになると、DWDWMWDWDWDWMWMW::paintEventflush()直後に apaintEventが続き、DWレポートが意図したサイズを持ち、setMaximumSize制約を解除する2 番目の後にDWaが意図しpaintEventたサイズで発生しDWます。しかし、DWがドック領域にドラッグされると、flush()すぐにレポートが意図したサイズのpaintEvent場所に続きますが、この場合、2 番目の後に 2 つの があり、驚くべきことに以前の浮動サイズになっています!DWsetMaximumSizepaintEventDW

DWサイズが正しく設定された後、この説明のつかないサイズのオーバーライドを防ぐ方法をまだ見つけていません。スロットにつながる信号が発信される前から が保持していたサイズ情報から、スロット処理が戻ったMW後にによって追加のサイズ変更イベントが生成されていることは明らかです。を監視すると、サイズがスロット コードで設定されていたサイズからフローティングしていたときのサイズに戻る が返された後に発生する Resize イベントが実際に明らかになります。タイル バーをダブルクリックしてフローティングからサイド ドックに戻す場合、スロットが戻った後に追加の Resize イベントは発生しません。DW_resizeMWMW::eventFilterDW_resizeDWDWDWDW_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 の新しいバージョンで対処されているのでしょうか? おそらく、誰かがここで何が起こっているのかについてより深い洞察を持ち、簡単な解決策を提供できますか?

于 2011-05-13T05:54:05.813 に答える
0

私は同じ問題を抱えています。不可解にrestoreState()2回置くことで解決しました。
Qt 4.7.0 を使用しています。

void MainWnd::showEvent(QShowEvent *se){
QMainWindow::showEvent(se);

static bool first = true;

if (first){
   restoreState(...);
   restoreState(...);
   first = false;
}
}
于 2012-02-09T13:42:22.147 に答える