重置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:

在构造函数中删除了QMenuQAction。仅在loadDefinitionFilesFromMenu内部。

在所有Item实例中共享菜单。

在项目类标题中:

private:
    static QMenu* m_menu;
    static QAction * m_actionTitle;
    static std::vector<std::string> m_defaults;

在"定义"one_answers"定义之前"定义之前,在项目类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();

最新更新