Я использую Qt 5.12.8 для Windows SDK 10.0.17763.0
Мое приложение падает при выходе, и трассировка стека указывает на проблему с удалением QWinExtra
. Похоже, происходит двойное удаление. QWindow
уже был удален, когда QWinThumbnailToolBarPrivate::hasHandle()
проверяет дескриптор.
Есть ли что-то особенное, что мне нужно сделать, чтобы должным образом уничтожить проблему QWinThumbnailToolBar
?
:
Возникло исключение: нарушение прав чтения.
d было 0xFFFFFFFFFFFFFF7F.
QPlatformWindow *QWindow::handle() const
{
Q_D(const QWindow);
return d->platformWindow;
}
Трассировка стека ниже:
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++
Моя реализация
У меня есть простой подкласс QDialog
, называемый DDialog
, со следующей реализацией:
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);
}
}
Как это называется
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
DDialog* pDialog1 = new DDialog;
QObject::connect(&a, &QApplication::aboutToQuit, pDialog1, &QObject::deleteLater);
pDialog1->show();
pDialog1->SetupWinThumbnailToolbar();
DDialog* pDialog2 = new DDialog;
QObject::connect(&a, &QApplication::aboutToQuit, pDialog2, &QObject::deleteLater);
pDialog2->show();
pDialog2->SetupWinThumbnailToolbar();
return a.exec();
}