Details
-
Bug
-
Resolution: Cannot Reproduce
-
Not Evaluated
-
None
-
5.12.6, 5.12.8
-
None
-
I am using Qt 5.12.8 on Windows SDK 10.0.17763.0
Description
My application is crashing during exit and the stack trace indicates an issue with deleting the QWinExtra. Seems like a double delete is occurring. The QWindow has already been deleted when the QWinThumbnailToolBarPrivate::hasHandle() checks for the handle.
Is there something special I need to do to properly destruct the QWinThumbnailToolBar?
Crash Report:
Exception thrown: read access violation. d was 0xFFFFFFFFFFFFFF7F.
Stack Trace:
Qt5Guid.dll!QWindow::handle() Line 1929 C++ Qt5WinExtrasd.dll!QWinThumbnailToolBarPrivate::hasHandle() Line 460 C++ Qt5WinExtrasd.dll!QWinThumbnailToolBarPrivate::handle() Line 465 C++ Qt5WinExtrasd.dll!QWinThumbnailToolBarPrivate::nativeEventFilter(const QByteArray & __formal, void * message, long * result) Line 549 C++ Qt5Cored.dll!QAbstractEventDispatcher::filterNativeEvent(const QByteArray & eventType, void * message, long * result) Line 484 C++ [External Code] Qt5Guid.dll!QWindowPrivate::destroy() Line 1914 C++ Qt5Guid.dll!QWindow::destroy() Line 1864 C++ Qt5Widgetsd.dll!QWidgetPrivate::deleteTLSysExtra() Line 1891 C++ Qt5Widgetsd.dll!QWidget::destroy(bool destroyWindow, bool destroySubWindows) Line 12515 C++ Qt5Widgetsd.dll!QApplication::~QApplication() Line 798 C++
My Implementation:
I have a simple subclass of QDialog called DDialog with the following implementation:
Dialog.h
#pragma once #include <QDialog> #include <QWinThumbnailToolBar> #include <QWinThumbnailToolButton> class DDialog : public QDialog { Q_OBJECT public: DDialog(QWidget *parent = Q_NULLPTR); virtual ~DDialog(); void SetupWinThumbnailToolbar(); protected slots: void ToggleKeepDialogLockedOnTop(); protected: QWinThumbnailToolBar* m_pThumbnailToolbar; QWinThumbnailToolButton* m_pLockOnTopToolButton; };
Dialog.cpp
#include "Dialog.h" DDialog::DDialog(QWidget* parent) : QDialog(parent), m_pThumbnailToolbar(nullptr), m_pLockOnTopToolButton(nullptr) {} void DDialog::ToggleKeepDialogLockedOnTop() { if (windowFlags() & Qt::WindowStaysOnTopHint) { setWindowFlags(windowFlags() & ~Qt::WindowStaysOnTopHint); m_pLockOnTopToolButton->setToolTip("Enable Window Lock"); m_pLockOnTopToolButton->setIcon(QIcon(":/appbase/Resources/window_unlocked.png")); } else { setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint); m_pLockOnTopToolButton->setToolTip("Disable Window Lock"); m_pLockOnTopToolButton->setIcon(QIcon(":/appbase/Resources/window_locked.png")); } // https://doc.qt.io/qt-5/qwidget.html#windowFlags-prop // Per Qt Documentation, setWindowFlags causes for the widget to be hidden // for this reason it needs to be shown again show(); } DDialog::~DDialog() { close(); } void DDialog::SetupWinThumbnailToolbar() { if (windowHandle() && !m_pThumbnailToolbar) { m_pThumbnailToolbar = new QWinThumbnailToolBar(this); m_pThumbnailToolbar->setWindow(windowHandle()); m_pLockOnTopToolButton = new QWinThumbnailToolButton(m_pThumbnailToolbar); m_pLockOnTopToolButton->setToolTip("Enable Window Lock"); m_pLockOnTopToolButton->setIcon(QIcon(":/appbase/Resources/window_unlocked.png")); m_pLockOnTopToolButton->setDismissOnClick(true); connect(m_pLockOnTopToolButton, &QWinThumbnailToolButton::clicked, this, &DDialog::ToggleKeepDialogLockedOnTop); m_pThumbnailToolbar->addButton(m_pLockOnTopToolButton); } }
How I am calling it:
int main(int argc, char *argv[]) { QApplication a(argc, argv); QMainWindow* pMainWindow = new QMainWindow; QObject::connect(&a, &QApplication::aboutToQuit, pMainWindow, &QObject::deleteLater); DDialog* pDialog1 = new DDialog(pMainWindow); DDialog* pDialog2 = new DDialog(pMainWindow); pMainWindow->show(); pDialog1->show(); pDialog1->SetupWinThumbnailToolbar(); pDialog2->show(); pDialog2->SetupWinThumbnailToolbar(); return a.exec(); }