Qt5WinExtras Cra sh при завершении работы приложения - PullRequest
0 голосов
/ 29 апреля 2020

Я использую 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();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...