通过循环创建弹出菜单 w.r.t 到参数时出现问题

An issue when creating a pop-up menu w.r.t to a parametr via loop

本文关键字:参数 问题 循环 创建 菜单      更新时间:2023-10-16

我正在尝试根据变量创建弹出菜单,如下所示:

    QMenu menu(widget);
    for(int i = 1; i <= kmean.getK(); i++)
    {
        stringstream ss;
        ss << i;
        string str = ss.str();
        string i_str = "Merge with " + str;
        QString i_Qstr = QString::fromStdString(i_str);
        menu.addAction(i_Qstr, this, SLOT(mergeWith1()));
    }
    menu.exec(position);

哪里:

kmean.get(K)返回一个int值,

mergeWith1() is some `SLOT()` which works fine

问题:

该循环仅在菜单上为 i=1 情况创建一个操作,并忽略 i 的其他值。

其他信息

当使用随意的int值(不转换)执行相同的循环时,一切正常。例如,如果我只循环menu.addAction(i, this, SLOT(...)))并且我的 K=4,将创建一个菜单,其中包含四个操作,分别命名为 1、2、3、4。

问题可能由什么引起

我认为问题出在转换部分,当我使用 stringstreami转换为 string 并在之后转换为QString.可能是价值以某种方式丢失了。我不确定。

问:

  • 如何使循环接受转换部分?
  • 我在转换部分做错了什么?
  1. 在Qt代码中,你不应该使用std::stringstreamstd::string。这毫无意义。

  2. 通过将菜单放在堆栈上为其提供父级,您会遇到崩溃错误。它将被双重销毁。

  3. 不要使用同步阻塞方法,如 exec() 。使用 popup() 异步显示菜单。

  4. 为了对动作做出反应,请将插槽连接到菜单的triggered(QAction*)信号。这样,您可以处理任意数量的自动生成的操作。

  5. 您可以使用 Qt 属性系统使用自定义属性标记操作。 毕竟,QAction是一个QObject,具有所有的好处。例如,您可以将索引存储在"索引"属性中。这是一个动态属性,是动态创建的。

下面是如何执行此操作的完整示例。

主.cpp

#include <QApplication>
#include <QAction>
#include <QMenu>
#include <QDebug>
#include <QPushButton>
struct KMean {
    int getK() const { return 3; }
};
class Widget : public QPushButton
{
    Q_OBJECT
    KMean kmean;
    Q_SLOT void triggered(QAction* an) {
        const QVariant index(an->property("index"));
        if (!index.isValid()) return;
        const int i = index.toInt();
        setText(QString("Clicked %1").arg(i));
    }
    Q_SLOT void on_clicked() {
        QMenu * menu = new QMenu();
        int last = kmean.getK();
        for(int i = 1; i <= last; i++)
        {
            QAction * action = new QAction(QString("Merge with %1").arg(i), menu);
            action->setProperty("index", i);
            menu->addAction(action);
        }
        connect(menu, SIGNAL(triggered(QAction*)), SLOT(triggered(QAction*)));
        menu->popup(mapToGlobal(rect().bottomRight()));
    }
public:
    Widget(QWidget *parent = 0) : QPushButton("Show Menu ...", parent) {
        connect(this, SIGNAL(clicked()), SLOT(on_clicked()));
    }
};
int main (int argc, char **argv)
{
    QApplication app(argc, argv);
    Widget w;
    w.show();
    return app.exec();
}
#include "main.moc"