我允许自定义上下文菜单显示在表格上。这是使用接受目标小部件和坐标的通用函数生成菜单的方式:
#include <QMenu>
void MainWindow::makeContextMenu(const QPoint& pos, QWidget* target)
{
QMenu *menu = new QMenu(this);
menu->addAction(new QAction("Action 1", menu));
menu->addAction(new QAction("Action 2", menu));
menu->addAction(new QAction("Action 3", menu));
// Notify window about clicking
QObject::connect(menu, &QMenu::triggered, this, &MainWindow::menuClicked);
// If this is a scroll area, map coordinates to real app coordinates
if(QAbstractScrollArea* area = dynamic_cast<QAbstractScrollArea*>(target))
menu->popup(area->viewport()->mapToGlobal(pos));
else
menu->popup(pos);
}
问题是QMenu* menu
永远不会被破坏并从内存中删除。即使隐藏了MainWindow
的孩子,它也会一直存在。
我该怎么办?我可以将菜单设置为自行删除吗?或者我应该重复使用相同的菜单实例,还是将其保存到同一个指针中?
答案 0 :(得分:3)
在您的代码中,似乎应该在此事件发生后删除menu
?
// Notify window about clicking
QObject::connect(menu, &QMenu::triggered, this, &MainWindow::menuClicked);
我可以将菜单设置为自行删除吗?
是的,您可以像这样拥有对象delete itself:
// Notify window about clicking
QObject::connect(menu, &QMenu::triggered, this, &MainWindow::menuClicked);
QObject::connect(menu, &QMenu::triggered, menu, &QMenu::deleteLater);
如果您担心要调用这些广告位的顺序,请参阅this
或者我应该重复使用相同的菜单实例,也可以将其保存到同一菜单中 指针?
嗯,你可以做点什么
//Your constructor
MainWindow::MainWindow(....)
{
menu = nullptr;
....
}
//Make context Menu
void MainWindow::makeContextMenu(const QPoint& pos, QWidget* target)
{
if(menu)
delete menu;
menu = new QMenu(this);
....
}
对于MainWindow::~MainWindow()
析构函数,它会处理menu
的清理工作。由于MainWindow
(QObject
派生类)automatically deletes所有孩子
最后,您可以将menu
作为MainWindow
的成员,只要您需要对menu
采取新的操作,就可以使用QMenu::clear
删除所有现有的行动。
//Your constructor
MainWindow::MainWindow(....)
{
menu = new QMenu(this);
....
}
void MainWindow::makeContextMenu(const QPoint& pos, QWidget* target)
{
menu->clear();
//QMenu *menu = new QMenu(this);
menu->addAction(new QAction("Action 1", menu));
menu->addAction(new QAction("Action 2", menu));
menu->addAction(new QAction("Action 3", menu));
// Notify window about clicking
QObject::connect(menu, &QMenu::triggered, this, &MainWindow::menuClicked);
// If this is a scroll area, map coordinates to real app coordinates
if(QAbstractScrollArea* area = dynamic_cast<QAbstractScrollArea*>(target))
menu->popup(area->viewport()->mapToGlobal(pos));
else
menu->popup(pos);
}
答案 1 :(得分:1)
不必太复杂。就是这样了:
$ cat foo.jsonnet
local foo = import "foo.libsonnet";
[ foo["foo1"], foo["foo2"] ]
$ cat foo.libsonnet
{
foo1: "bar1",
foo2: "bar2",
}
$ jsonnet foo.jsonnet
[
"bar1",
"bar2"
]
这样,当QMenu关闭时,一旦再次进入事件循环,该类即被删除。而且,是否触发了操作或仅关闭弹出窗口都没有关系。
要证明我的答案,您可以通过检查菜单的创建时间以及是否使用相同的地址触发了“已删除”消息来对其进行自我测试:
menu->setAttribute(Qt::WA_DeleteOnClose);
答案 2 :(得分:0)
隐藏时可以删除QMenu
。我为此目的设计了事件过滤器类:
#ifndef DELETEONHIDEFILTER_H
#define DELETEONHIDEFILTER_H
#include <QObject>
#include <QEvent>
class DeleteOnHideFilter : public QObject
{
Q_OBJECT
public:
explicit DeleteOnHideFilter(QObject *parent = 0) : QObject(parent) {}
protected slots:
bool eventFilter(QObject *obj, QEvent *event) override {
if(event->type() == QEvent::Hide) {
obj->deleteLater();
}
return false;
}
};
#endif // DELETEONHIDEFILTER_H
它也可以用于其他物体。