Bien, una solución consiste en restablecer las banderas de la ventana en la barra de herramientas cuando se muestra por primera vez y está flotando. Rastreé esto al ver lo que sucede una vez que se suelta una barra de herramientas después de arrastrarla (pero no se conecta a la ventana principal). (Se llama setWindowState()
y todo lo que hace en esta situación es ocultar la barra de herramientas, llame a updateWindowFlags()
y mostrarlo de nuevo).
Esto podría manejarse desde el QMainWindow::showEvent()
o desde el eventFilter
instalado en el QToolBar
. Creo que es más simple que el primero.
ACTUALIZAR :este problema ocurre cada vez que se muestra la barra de herramientas por primera vez, incluso si no se inicia la aplicación, p. desde el menú de vista alternar por el usuario una vez que se inicia la aplicación. Actualicé el código a continuación para solucionar ese problema también. Y vea las notas a continuación sobre otro problema con la minimización de la ventana principal.
Agregué esto al MainWindow
clase del 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.
También noté otro problema con la barra de herramientas inicialmente flotante. Cuando se minimiza la ventana principal, la barra de herramientas no se oculta sino que permanece donde estaba en la pantalla. Independientemente de lo que esté en la barra de herramientas (por ejemplo, sin cuadro combinado, solo QActions). Esta solución también podría solucionar ese problema (consulte el comentario del código), pero solo la segunda vez que se minimiza la ventana. Necesita una mejor solución para la primera minimización.
¿Pueden otros confirmar esto? Potencialmente, es un problema mayor que el combo editable y me sorprendería que nadie lo notara antes.
Supongo que esto debería archivarse como un error de Qt de cualquier manera.
ACTUALIZACIÓN2 :Esta versión también soluciona el problema de minimización. Supongo que pasa algo después del QMainWindow::showEvent()
eso cambia el comportamiento de la barra de herramientas. Lo que explica por qué la solución anterior funciona solo después de la primera minimización. Así que programar la "corrección" de la barra de herramientas para más adelante también soluciona eso.
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;
};
AÑADIDO :A QToolBar
subclase que aplica la solución por sí sola, no se necesita nada especial en el QMainWindow
. La corrección de minimización solo funciona cuando adjustToolbar()
la función está en cola o si restoreState()
solo se llama después de show()
(ver comentarios de código).
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
};
ACTUALIZAR3 :El problema de minimización también existe con QDockWidget
flotante si el QMainWindow
el estado se restaura antes de que se muestre. De hecho, con las versiones "antiguas" de Qt, el widget flotante no aparece en absoluto (no con <=5.9.5 pero sí con>=5.12.4, no hay nada intermedio para probar ATM). Entonces, el enfoque adecuado es show()
la ventana principal primero y luego restoreState()
. Desafortunadamente, esto no parece funcionar para QToolBar
.
ACTUALIZACIÓN4 :Archivado como QTBUG-78293