GNU/Linux >> Znalost Linux >  >> Linux

Problém při obnově plovoucího panelu nástrojů pro QMainWindow

OK, řešením je resetovat příznaky okna na panelu nástrojů, když je poprvé zobrazen a plovoucí. Sledoval jsem to tak, že jsem viděl, co se stane, když panel nástrojů po přetažení (ale není zapojen do hlavního okna) spadne. (Volá setWindowState() a vše, co v této situaci udělá, je skrýt panel nástrojů, zavolat updateWindowFlags() a ukažte jej znovu).

To lze vyřešit z QMainWindow::showEvent() nebo z eventFilter nainstalován na QToolBar . Myslím, že je to jednodušší než předchozí.

AKTUALIZACE :Tento problém ve skutečnosti nastává vždy, když je panel nástrojů poprvé zobrazen, i když ne při spuštění aplikace, např. z nabídky přepnout zobrazení uživatelem po spuštění aplikace. Aktualizoval jsem níže uvedený kód, abych tento problém také vyřešil. A viz poznámky níže o dalším problému s minimalizací hlavního okna.

Přidal jsem to do MainWindow třídy z 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.

Také jsem si všiml dalšího problému s původně plovoucím panelem nástrojů. Když je hlavní okno minimalizováno, panel nástrojů se neskryje, ale zůstane tam, kde byl na obrazovce. Bez ohledu na to, co je na panelu nástrojů (např. žádné pole se seznamem, pouze QActions). Toto zástupné řešení by také mohlo tento problém vyřešit (viz komentář ke kódu), ale pouze při druhém minimalizaci okna. Potřebuje lepší řešení pro první minimalizaci.

Mohou to potvrdit ostatní? Potenciálně větší problém než upravitelné kombo a byl bych překvapen, kdyby si toho předtím nikdo nevšiml.

Myslím, že by to mělo být v každém případě označeno jako chyba Qt.

AKTUALIZACE 2 :Tato verze také řeší problém s minimalizací. Myslím, že se něco stane po QMainWindow::showEvent() to změní chování panelu nástrojů. Což vysvětluje, proč výše uvedené řešení funguje pouze po 1. minimalizaci. Takže naplánování "opravy" panelu nástrojů na později to také obchází.

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

PŘIDÁNO :A QToolBar podtřída, která používá řešení sama o sobě, v QMainWindow není potřeba nic zvláštního . Oprava minimalizace stále funguje pouze při adjustToolbar() funkce je zařazena do fronty nebo pokud restoreState() je voláno pouze po show() (viz komentáře ke kódu).

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

AKTUALIZACE 3 :Problém s minimalizací existuje také u plovoucích QDockWidget pokud QMainWindow stav je obnoven, než se zobrazí. Ve skutečnosti se u "starších" verzí Qt plovoucí widget vůbec nezobrazuje (nezobrazuje se s <=5.9.5, ale ano s>=5.12.4, nemáte nic mezi tím, abyste vyzkoušeli ATM). Správný přístup je tedy show() nejprve hlavní okno a pak restoreState() . Bohužel se zdá, že to pro QToolBar nefunguje .

AKTUALIZACE 4 :Soubor jako QTBUG-78293


Linux
  1. Chyba:Ověření md5 se nezdařilo pro PyYAML-3.11.zip možný problém se stahováním? [Řešení]

  2. Zkontrolujte databázi, zda není poškozená

  3. Oznamuji Kali pro Vagranta

  1. jpegoptim pro optimalizaci obrazu

  2. Nainstalujte tkinter pro Python

  3. Co znamená 'cd -'?

  1. Pochopení YAML pro Ansible

  2. YAML pro začátečníky

  3. DNF pro uživatele APT