GNU/Linux >> Tutoriels Linux >  >> Linux

Problème de restauration de la barre d'outils flottante pour QMainWindow

OK, une solution de contournement consiste à réinitialiser les drapeaux de la fenêtre sur la barre d'outils lorsqu'elle est affichée pour la première fois et flottante. J'ai suivi cela en voyant ce qui se passe une fois qu'une barre d'outils est supprimée après avoir été glissée (mais pas connectée à la fenêtre principale). (Il appelle setWindowState() et tout ce qui fait dans cette situation est de masquer la barre d'outils, appelez updateWindowFlags() , et l'afficher à nouveau).

Cela pourrait être géré à partir du QMainWindow::showEvent() ou du eventFilter installé sur le QToolBar . Je pense que c'est plus simple de l'ancien.

MISE À JOUR  :Ce problème se produit chaque fois que la barre d'outils est affichée pour la première fois, même si ce n'est pas au démarrage de l'application, par ex. à partir du menu d'affichage à bascule par l'utilisateur une fois l'application démarrée. J'ai également mis à jour le code ci-dessous pour résoudre ce problème. Et consultez les notes ci-dessous concernant un autre problème lié à la réduction de la fenêtre principale.

J'ai ajouté ceci au MainWindow classe du 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.

J'ai également remarqué un autre problème avec la barre d'outils initialement flottante. Lorsque la fenêtre principale est réduite, la barre d'outils n'est pas masquée mais reste là où elle était à l'écran. Indépendamment de ce qui se trouve dans la barre d'outils (par exemple, pas de zone de liste déroulante, juste QActions). Cette solution de contournement pourrait également résoudre ce problème (voir le commentaire du code), mais uniquement la deuxième fois que la fenêtre est réduite. Nécessite une meilleure solution de contournement pour la première réduction.

D'autres personnes peuvent-elles le confirmer ? Potentiellement un problème plus important que le combo modifiable et je serais surpris si personne ne le remarquait auparavant.

Je suppose que cela devrait être classé comme un bogue Qt de toute façon.

MISE À JOUR2 :Cette version corrige également le problème de minimisation. Je suppose que quelque chose se passe après le QMainWindow::showEvent() qui modifie le comportement de la barre d'outils. Ce qui explique pourquoi la solution de contournement ci-dessus ne fonctionne qu'après la 1ère réduction. Donc, planifier le "correctif" de la barre d'outils pour plus tard fonctionne également autour de cela.

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;
};

AJOUTÉ :Un QToolBar sous-classe qui applique la solution de contournement seule, rien de spécial n'est nécessaire dans le QMainWindow . Le correctif de réduction ne fonctionne toujours que lorsque le adjustToolbar() la fonction est en file d'attente ou si restoreState() n'est appelé qu'après show() (voir les commentaires du code).

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
};

MISE À JOUR3  :Le problème de minimisation existe également avec le flottant QDockWidget si le QMainWindow l'état est restauré avant d'être affiché. En fait, avec les "anciennes" versions de Qt, le widget flottant ne s'affiche pas du tout (pas avec <=5.9.5 mais avec>=5.12.4, il n'y a rien entre les deux pour essayer ATM). La bonne approche consiste donc à show() la fenêtre principale d'abord et puis restoreState() . Malheureusement, cela ne semble pas fonctionner pour QToolBar .

MISE À JOUR4 :Archivé sous QTBUG-78293


Linux
  1. Vérifier la base de données pour la corruption

  2. Annonce de Kali pour Vagrant

  3. Vérification des variables d'environnement

  4. Installer tkinter pour Python

  5. outil de type teamviewer pour ssh?

4 distributions Linux pour les jeux

Une introduction à bpftrace pour Linux

Choisir une imprimante pour Linux

Bash pour la boucle

Conseils d'utilisation de l'écran

Zorin OS pour les débutants Linux