Exception when passing pointer to QMenu
-
Hi,
I have a base class for
QTreeView
(H5TreeView
) where I add context menu when pressing on header. This base class has oneQAction
. I want that all subclasses fromH5TreeView
had opportunity to add theirQActions
.
Here is the code forH5TreeView
:
h5treeview.h:#ifndef H5TREEVIEW_H #define H5TREEVIEW_H #include <QTreeView> class H5TreeView : public QTreeView { Q_OBJECT public: H5TreeView(QWidget *parent = nullptr); protected: /// /// \brief for subclasses to add actions /// \param menu add actions here /// virtual void fillHdrMenu(QMenu* menu); private: void hdrMenuRequested(QPoint pos); }; #endif // H5TREEVIEW_H
h5treeview.cpp:
#include "h5treeview.h" #include "h5proxymodel.h" #include <QHeaderView> #include <QMenu> #include <QAction> H5TreeView::H5TreeView(QWidget *parent): QTreeView(parent) { setSortingEnabled(true); setContextMenuPolicy(Qt::CustomContextMenu); header()->setContextMenuPolicy(Qt::CustomContextMenu); connect(header(), &QTreeView::customContextMenuRequested, this, &H5TreeView::hdrMenuRequested); } void H5TreeView::fillHdrMenu(QMenu* menu){ } void H5TreeView::hdrMenuRequested(QPoint pos){ QMenu *menu = new QMenu(this); QAction *checkedOnlyAct = menu->addAction("Display checked only"); checkedOnlyAct->setCheckable(true); H5ProxyModel *proxyModel = qobject_cast<H5ProxyModel*>(model()); if (proxyModel) checkedOnlyAct->setChecked(proxyModel->isShowCheckedOnly()); else checkedOnlyAct->setDisabled(true); connect(checkedOnlyAct, &QAction::toggled, proxyModel, &H5ProxyModel::setShowCheckedItemsOnly); menu->addSeparator(); /* HERE I INVOKE THAT METHOD FOR SUBCLASSES TO ADD ACTIONS TO QMENU */ /* without it the app works fine */ fillHdrMenu(menu); menu->popup(header()->mapToGlobal(pos)); }
As you can see it has
void H5TreeView::fillHdrMenu(QMenu* menu)
that all inheritors have. Even my inheritor leavevoid H5SeisTreeView::fillHdrMenu(QMenu* menu)
empty I get the exception:
Please explain what is going wrong...
-
@Please_Help_me_D
Hi
Yes if QMenu has no parent it never is deleted and hence a leak.
So if you call hdrMenuRequested many times, you will leak a QMenu which might not be good.You could use
https://doc.qt.io/qt-5/qmenu.html#exec
which is blocking and then delete after.menu->exec(header()->mapToGlobal(pos));
menu->deletelater(); -
@Please_Help_me_D said in Exception when passing pointer to QMenu:
Please explain what is going wrong...
take a look at the backtrace to see where in your code you call it.
-
@Christian-Ehrlicher said in Exception when passing pointer to QMenu:
take a look at the backtrace to see where in your code you call it.
I'm sorry, I didn't understand what does it mean. What is a "backtrace"?
I callfillHdrMenu(QMenu* menu)
only insidehdrMenuRequested(QPoint pos)
of baseH5TreeView
class -
@Please_Help_me_D said in Exception when passing pointer to QMenu:
What is a "backtrace"?
https://doc.qt.io/qtcreator/creator-debug-mode.html#viewing-call-stack-trace
-
@Christian-Ehrlicher thank you for information
qwindowsd
is it? This file is not from my project. Actually all the files from that dim grey list are not from my project :) -
I'm pretty sure it has nothing to do with the code you show us above. Please make sure that your build dir is clean and do a full rebuild. If it still happens please provide a minimal, compilable example so we can take a look.
-
@Christian-Ehrlicher there is no such exception in test project.
I understand that you can't help me now but one last thing: I get this exception only when I close the application. Do you have some ideas where to look?If possible can you translate what assembler code means at the line 117024 from picture above? Can I get information about what pointer gives me such exception?
-
@Christian-Ehrlicher I 've found the problem!
All beacause of that I used to set parent for QMenu:
QMenu *menu = new QMenu(this);
As I have few TreeViews each in custom dockWidget that lead to CDockWidgets are destroyed in some order and thus when I close the app it somehow used to lead to an exception (parent
this
is destroyed thus menu is also destroyed but TreeView tries to send it... I think something like that).Now I create
QMenu
without parent but will this lead to memory leak? -
@Please_Help_me_D
Hi
Yes if QMenu has no parent it never is deleted and hence a leak.
So if you call hdrMenuRequested many times, you will leak a QMenu which might not be good.You could use
https://doc.qt.io/qt-5/qmenu.html#exec
which is blocking and then delete after.menu->exec(header()->mapToGlobal(pos));
menu->deletelater();