重置 QMenu 以接受新的 QAction 集
Reset QMenu to accept new set of QActions
我希望reset/recreate 自定义上下文菜单。我正在使用 QMenu 和 QAction(成员变量)来实现这一点。
QMenu* m_menu;
QAction* m_actionTitle;
我的插槽是这样连接的:
connect(m_ui->actionLoad_Definition_File, &QAction::triggered, m_Item.get(),
&Item::loadDefinitionFilesFromMenu);
工作部分:
在我的构造函数中,我设置了如下内容:
Item::Item(QWidget* parent)
{
// Connect context menu
this->setContextMenuPolicy(Qt::CustomContextMenu);
connect(this, SIGNAL(customContextMenuRequested(const QPoint&)),
this, SLOT(showContextMenu(const QPoint&)));
}
/* virtual */ void Item::showContextMenu(const QPoint& pos)
{
// Obtain global position
QPoint globalPos = mapToGlobal(pos);
// Change the first menu entry to show the range
m_actionTitle->setText(QString::number(m_from) + " - " +
QString::number(m_to)); //Access Violation error
QAction* action = m_menu->exec(globalPos);
if (action != NULL)
{
if (action->text() == "something")
{
// Remove the item
m_view->removeItem(this);
}
else
{
// Display the text
setText(action->text());
setColor(action->text());
setToolTip(action->text());
m_edit.setText(action->text());
m_view->arrange();
}
}
}
我想要的:
我想重置 m_menu
它的所有操作并向其中推送新操作。所以,每当我右键单击时,新的上下文菜单就会出现。
问题:
创建 QToolButton 后,如果我右键单击它,我得到 "Access Violation Error"。调试它,m_menu 和 m_actionTitle 都超出范围或被简单地销毁。不确定为什么会这样。
到目前为止我做了什么:
void Item::loadDefinitionFilesFromMenu()
{
//Clear the vector of existing values
m_defaults.clear();
//Clear the menu of actions
m_menu->clear();
QString file = QFileDialog::getOpenFileName(nullptr, "Choose a definition file", QString(),
QString("(*.ad)"));
if (!file.isNull())
{
MLParser ml;
std::map<std::string, std::string> base = ml.readDefinitions(file.toStdString());
for (auto const& gestureValues : base)
{
m_defaults.push_back(gestureValues.first); // string (key)
}
m_menu = new QMenu(this);
m_actionTitle = new QAction("Note", m_menu);
m_actionTitle->setEnabled(false);
m_menu->addAction(m_actionTitle);
m_menu->addSeparator();
for (std::vector<std::string>::iterator it = m_defaults.begin();
it != m_defaults.end();
++it)
{
m_menu->addAction(QString::fromStdString(*it)); //works ok
}
m_menu->addSeparator();
}
}
我想在整个程序中重复使用 m_menu
,但我无法将其重置并接受新的操作集。我在这里遗漏了什么吗?
编辑 1:
删除了构造函数中的 QMenu
和 QAction
。仅在 loadDefinitionFilesFromMenu
.
内
使所有 Item
个实例共享菜单。
项目 class header:
private:
static QMenu* m_menu;
static QAction * m_actionTitle;
static std::vector<std::string> m_defaults;
在项目 class cpp 中,定义之后和方法定义之前:
QMenu* Item::m_menu = 0;
QAction * Item::m_actionTitle = 0;
std::vector<std::string> Item::m_defaults;
菜单只实例化一次,在Item
构造函数中:
if(m_menu == 0)
{
m_menu = new QMenu();
// load defaults here
}
无需再次实例化菜单:从 loadDefinitionFilesFromMenu
中删除此行:
m_menu = new QMenu(this);
关于你的m_actionTitle
指针:不要给它分配一个新的QAction
,让它保存addAction
方法的return值:
m_actionTitle = m_menu->addAction("Note");
m_actionTitle->setEnabled(false);
m_menu->addSeparator();
最后,有一个静态方法来删除(唯一的)菜单实例。在 header 文件中:
static void dismissMenu();
在 cpp 中:
void Item::dismissMenu()
{
delete m_menu;
}
可以在退出前调用此方法,在QApplication::exec
returns:
之后
Item::dismissMenu();
我希望reset/recreate 自定义上下文菜单。我正在使用 QMenu 和 QAction(成员变量)来实现这一点。
QMenu* m_menu;
QAction* m_actionTitle;
我的插槽是这样连接的:
connect(m_ui->actionLoad_Definition_File, &QAction::triggered, m_Item.get(),
&Item::loadDefinitionFilesFromMenu);
工作部分:
在我的构造函数中,我设置了如下内容:
Item::Item(QWidget* parent)
{
// Connect context menu
this->setContextMenuPolicy(Qt::CustomContextMenu);
connect(this, SIGNAL(customContextMenuRequested(const QPoint&)),
this, SLOT(showContextMenu(const QPoint&)));
}
/* virtual */ void Item::showContextMenu(const QPoint& pos)
{
// Obtain global position
QPoint globalPos = mapToGlobal(pos);
// Change the first menu entry to show the range
m_actionTitle->setText(QString::number(m_from) + " - " +
QString::number(m_to)); //Access Violation error
QAction* action = m_menu->exec(globalPos);
if (action != NULL)
{
if (action->text() == "something")
{
// Remove the item
m_view->removeItem(this);
}
else
{
// Display the text
setText(action->text());
setColor(action->text());
setToolTip(action->text());
m_edit.setText(action->text());
m_view->arrange();
}
}
}
我想要的:
我想重置 m_menu
它的所有操作并向其中推送新操作。所以,每当我右键单击时,新的上下文菜单就会出现。
问题:
创建 QToolButton 后,如果我右键单击它,我得到 "Access Violation Error"。调试它,m_menu 和 m_actionTitle 都超出范围或被简单地销毁。不确定为什么会这样。
到目前为止我做了什么:
void Item::loadDefinitionFilesFromMenu()
{
//Clear the vector of existing values
m_defaults.clear();
//Clear the menu of actions
m_menu->clear();
QString file = QFileDialog::getOpenFileName(nullptr, "Choose a definition file", QString(),
QString("(*.ad)"));
if (!file.isNull())
{
MLParser ml;
std::map<std::string, std::string> base = ml.readDefinitions(file.toStdString());
for (auto const& gestureValues : base)
{
m_defaults.push_back(gestureValues.first); // string (key)
}
m_menu = new QMenu(this);
m_actionTitle = new QAction("Note", m_menu);
m_actionTitle->setEnabled(false);
m_menu->addAction(m_actionTitle);
m_menu->addSeparator();
for (std::vector<std::string>::iterator it = m_defaults.begin();
it != m_defaults.end();
++it)
{
m_menu->addAction(QString::fromStdString(*it)); //works ok
}
m_menu->addSeparator();
}
}
我想在整个程序中重复使用 m_menu
,但我无法将其重置并接受新的操作集。我在这里遗漏了什么吗?
编辑 1:
删除了构造函数中的 QMenu
和 QAction
。仅在 loadDefinitionFilesFromMenu
.
使所有 Item
个实例共享菜单。
项目 class header:
private:
static QMenu* m_menu;
static QAction * m_actionTitle;
static std::vector<std::string> m_defaults;
在项目 class cpp 中,定义之后和方法定义之前:
QMenu* Item::m_menu = 0;
QAction * Item::m_actionTitle = 0;
std::vector<std::string> Item::m_defaults;
菜单只实例化一次,在Item
构造函数中:
if(m_menu == 0)
{
m_menu = new QMenu();
// load defaults here
}
无需再次实例化菜单:从 loadDefinitionFilesFromMenu
中删除此行:
m_menu = new QMenu(this);
关于你的m_actionTitle
指针:不要给它分配一个新的QAction
,让它保存addAction
方法的return值:
m_actionTitle = m_menu->addAction("Note");
m_actionTitle->setEnabled(false);
m_menu->addSeparator();
最后,有一个静态方法来删除(唯一的)菜单实例。在 header 文件中:
static void dismissMenu();
在 cpp 中:
void Item::dismissMenu()
{
delete m_menu;
}
可以在退出前调用此方法,在QApplication::exec
returns:
Item::dismissMenu();