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