OK、回避策は、ツールバーが最初に表示されてフローティングしているときに、ツールバーのウィンドウ フラグをリセットすることです。ツールバーがドラッグされた後にドロップされるとどうなるかを確認することで、これを追跡しました(ただし、メインウィンドウには接続されていません)。 (setWindowState()
を呼び出します) この状況で行うことは、ツールバーを非表示にして updateWindowFlags()
を呼び出すことだけです 、もう一度表示します)。
これは QMainWindow::showEvent()
から処理できます または eventFilter
から QToolBar
にインストール .前者よりは簡単だと思います。
更新 :この問題は、アプリの起動時でなくても、ツールバーが最初に表示されるたびに実際に発生します。アプリが起動したら、ユーザーがトグル ビュー メニューから。以下のコードを更新して、その問題も修正しました。また、メイン ウィンドウの最小化に関する別の問題については、以下のメモを参照してください。
これを MainWindow
に追加しました MCVE のクラス:
protected:
void showEvent(QShowEvent *e) override {
QMainWindow::showEvent(e);
#ifdef Q_OS_LINUX
if (lToolbar->isFloating()
// remove the next condition and the toolsbar will get hidden the 2nd time main window is minimized.
&& lToolbar->windowFlags().testFlag(Qt::X11BypassWindowManagerHint)
) {
const bool vis = !lToolbar->isHidden();
qDebug() << lToolbar->isFloating() << vis << lToolbar->windowFlags();
lToolbar->hide();
lToolbar->setWindowFlag(Qt::X11BypassWindowManagerHint, false);
if (vis)
lToolbar->show();
#endif
}
QToolBar* lToolbar; // Use this in MainWindow constructor to save the instance pointer.
別の問題にも気付きました 最初はフローティング ツールバーを使用します。メイン ウィンドウが最小化されている場合、ツールバーは非表示にならず、画面上の元の場所にとどまります。ツールバーの内容に関係なく (例:コンボ ボックスなし、QActions のみ)。この回避策は、その問題に対処することもできますが (コード コメントを参照)、ウィンドウが最小化されるのは 2 回目だけです。最初の最小化のためのより良い回避策が必要です。
他の人はこれを確認できますか? 編集可能なコンボよりも大きな問題である可能性があり、これまで誰も気付かなかったとしたら驚くでしょう.
いずれにせよ、これは Qt のバグとして報告する必要があると思います。
UPDATE2 :このバージョンでは、最小化の問題も修正されています。 QMainWindow::showEvent()
の後に何かが起こると思います これにより、ツールバーの動作が変わります。これは、上記の回避策が最初の最小化後にのみ機能する理由を説明しています。したがって、後でツールバーの「修正」をスケジュールすると、それも回避できます。
class MainWindow : public QMainWindow
{
...
#ifdef Q_OS_LINUX
protected:
void showEvent(QShowEvent *e) override
{
QMainWindow::showEvent(e);
if (lToolbar->isFloating() && lToolbar->windowFlags().testFlag(Qt::X11BypassWindowManagerHint) ) {
// QMainWindow::show() after QMainWindow::restoreState() will break the minimizing again so we should delay calling adjustToolbar().
QMetaObject::invokeMethod(this, "adjustToolbar", Qt::QueuedConnection);
// If we're sure restoreState() is only called after show() then adjustToolbar() could be called here directly instead.
//adjustToolbar();
}
}
private slots:
void adjustToolbar() const
{
const bool vis = !lToolbar->isHidden();
qDebug() << lToolbar->isFloating() << vis << lToolbar->windowFlags();
lToolbar->hide();
lToolbar->setWindowFlag(Qt::X11BypassWindowManagerHint, false);
if (vis)
lToolbar->show();
}
#endif
private:
QToolBar* lToolbar;
};
追加 :QToolBar
QMainWindow
で特別なことは何も必要ありません。 .最小化の修正は、adjustToolbar()
の場合にのみ機能します。 関数がキューに入れられているまたは restoreState()
の場合 show()
の後にのみ呼び出されます (コードのコメントを参照してください)。
class ToolBar : public QToolBar
{
Q_OBJECT
public:
using QToolBar::QToolBar;
#ifdef Q_OS_LINUX
protected:
void showEvent(QShowEvent *e) override
{
QToolBar::showEvent(e);
if (isFloating() && windowFlags().testFlag(Qt::X11BypassWindowManagerHint) ) {
// QMainWindow::show() after QMainWindow::restoreState() will break the minimizing again so we should delay calling adjustToolbar().
QMetaObject::invokeMethod(this, "adjustToolbar", Qt::QueuedConnection);
// If we're sure restoreState() is only called after show() then adjustToolbar() could be called here directly instead.
//adjustToolbar();
}
}
private slots:
void adjustToolbar()
{
const bool vis = !isHidden();
hide();
setWindowFlag(Qt::X11BypassWindowManagerHint, false);
if (vis)
show();
}
#endif
};
UPDATE3 :最小化の問題は、フローティング QDockWidget
にも存在します もし QMainWindow
表示される前の状態が復元されます。実際、「古い」Qt バージョンでは、フローティング ウィジェットはまったく表示されません (<=5.9.5 では表示されませんが、>=5.12.4 では表示されます。その間に ATM を試す必要はありません)。したがって、適切なアプローチは show()
です 最初にメイン ウィンドウ、次に restoreState()
.残念ながら、これは QToolBar
では機能しないようです .
UPDATE4 :QTBUG-78293として提出