Сброс QMenu для принятия нового набора QActions
Я хочу сбросить / воссоздать пользовательское контекстное меню. Я использую 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, если я щелкну на нем правой кнопкой мыши, я получу "Ошибка нарушения доступа". Отладка, и 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
,
1 ответ
Сделать меню общим для всех Item
экземпляров.
В заголовке класса Item:
private:
static QMenu* m_menu;
static QAction * m_actionTitle;
static std::vector<std::string> m_defaults;
В классе Item 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
метод:
m_actionTitle = m_menu->addAction("Note");
m_actionTitle->setEnabled(false);
m_menu->addSeparator();
Наконец, есть статический метод для удаления (единственного и единственного) экземпляра меню. В заголовочном файле:
static void dismissMenu();
В cpp:
void Item::dismissMenu()
{
delete m_menu;
}
Вы можете вызвать этот метод перед выходом, после QApplication::exec
возвращает:
Item::dismissMenu();