OK, eine Problemumgehung besteht darin, die Fensterflags auf der Symbolleiste zurückzusetzen, wenn sie zum ersten Mal angezeigt wird und schwebt. Ich habe dies aufgespürt, indem ich gesehen habe, was passiert, wenn eine Symbolleiste nach dem Ziehen (aber nicht im Hauptfenster) abgelegt wird. (Es ruft setWindowState()
auf und alles, was in dieser Situation tut, ist die Symbolleiste zu verstecken, rufen Sie updateWindowFlags()
auf , und zeigen Sie es erneut).
Dies könnte von QMainWindow::showEvent()
aus gehandhabt werden oder von der eventFilter
auf dem QToolBar
installiert . Ich denke, es ist einfacher als das erstere.
AKTUALISIEREN :Dieses Problem tritt tatsächlich auf, wenn die Symbolleiste zum ersten Mal angezeigt wird, auch wenn dies nicht beim Start der App der Fall ist, z. aus dem Toggle-View-Menü durch den Benutzer, sobald die App gestartet wird. Ich habe den folgenden Code aktualisiert, um dieses Problem ebenfalls zu beheben. Und siehe Hinweise unten zu einem weiteren Problem beim Minimieren des Hauptfensters.
Ich habe dies zu MainWindow
hinzugefügt Klasse vom 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.
Mir ist auch ein weiteres Problem aufgefallen mit der anfänglich schwebenden Symbolleiste. Wenn das Hauptfenster minimiert wird, wird die Symbolleiste nicht ausgeblendet, sondern bleibt dort, wo sie auf dem Bildschirm war. Unabhängig davon, was sich in der Symbolleiste befindet (z. B. kein Kombinationsfeld, nur QActions). Diese Problemumgehung könnte dieses Problem auch irgendwie beheben (siehe Codekommentar), aber nur das zweite Mal, wenn das Fenster minimiert wird. Benötigt eine bessere Problemumgehung für die erste Minimierung.
Können andere das bestätigen? Möglicherweise ein größeres Problem als die bearbeitbare Kombination, und ich wäre überrascht, wenn es vorher niemandem aufgefallen wäre.
Ich schätze, das sollte so oder so als Qt-Fehler abgelegt werden.
UPDATE2 :Diese Version behebt auch das Minimierungsproblem. Ich vermute, dass nach dem QMainWindow::showEvent()
etwas passiert das ändert, wie sich die Symbolleiste verhält. Das erklärt, warum der obige Workaround erst nach dem 1. Minimieren funktioniert. Das Einplanen des Symbolleisten-"Fix" für später funktioniert also auch darum.
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;
};
Hinzugefügt :A QToolBar
Unterklasse, die die Problemumgehung selbst anwendet, nichts Besonderes in QMainWindow
erforderlich . Der Fix zum Minimieren funktioniert immer noch nur, wenn adjustToolbar()
Funktion ist in der Warteschlange oder wenn restoreState()
wird nur nach show()
aufgerufen (siehe Codekommentare).
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 :Das Minimierungsproblem besteht auch bei Floating QDockWidget
wenn die QMainWindow
Zustand wird wiederhergestellt, bevor er angezeigt wird. Tatsächlich wird bei "älteren" Qt-Versionen das Floating-Widget überhaupt nicht angezeigt (nicht bei <=5.9.5, aber bei>=5.12.4, dazwischen gibt es nichts, um ATM auszuprobieren). Der richtige Ansatz ist also show()
zuerst das Hauptfenster und dann restoreState()
. Leider scheint dies für QToolBar
nicht zu funktionieren .
UPDATE4 :Abgelegt als QTBUG-78293