GNU/Linux >> Belajar Linux >  >> Linux

Masalah dalam memulihkan bilah alat mengambang untuk QMainWindow

Oke, solusinya adalah mengatur ulang bendera jendela pada bilah alat saat pertama kali ditampilkan dan mengambang. Saya melacaknya dengan melihat apa yang terjadi setelah bilah alat dijatuhkan setelah diseret (tetapi tidak dicolokkan ke jendela utama). (Ini memanggil setWindowState() dan yang dilakukan dalam situasi ini hanyalah menyembunyikan bilah alat, panggil updateWindowFlags() , dan tampilkan lagi).

Ini dapat ditangani dari QMainWindow::showEvent() atau dari eventFilter diinstal ke QToolBar . Saya pikir ini lebih sederhana dari yang pertama.

PERBARUI :Masalah ini sebenarnya terjadi setiap kali bilah alat pertama kali ditampilkan meskipun tidak saat memulai aplikasi, mis. dari menu tampilan beralih oleh pengguna setelah aplikasi dimulai. Saya memperbarui kode di bawah ini untuk memperbaiki masalah itu juga. Dan lihat catatan di bawah tentang masalah lain dengan meminimalkan jendela utama.

Saya menambahkan ini ke MainWindow kelas dari 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.

Saya juga melihat masalah lain dengan bilah alat yang awalnya mengambang. Saat jendela utama diminimalkan, bilah alat tidak disembunyikan tetapi tetap berada di tempatnya di layar. Terlepas dari apa yang ada di bilah alat (mis. Tidak ada kotak kombo, hanya QActions). Solusi ini juga dapat menyelesaikan masalah itu (lihat komentar kode), tetapi hanya untuk yang kedua kalinya jendela diminimalkan. Membutuhkan solusi yang lebih baik untuk meminimalkan pertama.

Dapatkah orang lain mengonfirmasi hal ini? Berpotensi masalah yang lebih besar daripada kombo yang dapat diedit dan saya akan terkejut jika tidak ada yang menyadarinya sebelumnya.

Saya kira ini harus diajukan sebagai bug Qt.

PEMBARUAN2 :Versi ini juga memperbaiki masalah perkecil. Saya kira sesuatu terjadi setelah QMainWindow::showEvent() yang mengubah perilaku bilah alat. Yang menjelaskan mengapa solusi di atas hanya berfungsi setelah pengurangan pertama. Jadi penjadwalan "perbaikan" bilah alat untuk nanti juga akan mengatasinya.

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

TAMBAH :A QToolBar subkelas yang menerapkan solusinya sendiri, tidak ada hal khusus yang diperlukan di QMainWindow . Perbaikan perkecil masih hanya berfungsi saat adjustToolbar() fungsi diantrikan atau jika restoreState() hanya dipanggil setelah show() (lihat komentar kode).

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

PEMBARUAN3 :Masalah meminimalkan juga ada dengan QDockWidget mengambang jika QMainWindow negara dipulihkan sebelum ditampilkan. Faktanya dengan versi Qt "lama", widget mengambang tidak muncul sama sekali (tidak dengan <=5.9.5 tetapi muncul dengan>=5.12.4, tidak memiliki apa pun di antaranya untuk mencoba ATM). Jadi pendekatan yang tepat adalah show() jendela utama terlebih dahulu lalu lalu restoreState() . Sayangnya ini sepertinya tidak berfungsi untuk QToolBar .

PEMBARUAN4 :Diajukan sebagai QTBUG-78293


Linux
  1. Mengumumkan Kali untuk Vagrant

  2. Memeriksa variabel lingkungan

  3. Bersarang untuk loop

  1. Memahami YAML untuk Ansible

  2. YAML untuk pemula

  3. DNF untuk pengguna APT

  1. Kesalahan:validasi md5 gagal untuk PyYAML-3.11.zip kemungkinan masalah unduhan? [Larutan]

  2. Periksa database untuk korupsi

  3. jpegoptim untuk pengoptimalan gambar