一条警告信息"没有匹配信号"执行我的申请时

时间:2017-06-04 16:31:57

标签: c++ qt qt5 signals-slots

执行我的应用程序时会出现一些警告消息:
QMetaObject::connectSlotsByName: No matching signal for on_actionUndo_triggered()QMetaObject::connectSlotsByName: No matching signal for on_actionRedo_triggered()

我已将规则void on_objectName_signalName(signalParameters);实施到我创建的信号和广告位,并且我不知道为什么会出现这些消息,请注意信号和广告位正常工作。

声明:

class Widget : public QWidget {
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

private:
    Ui::Widget *ui;
    QAction *actionUndo;
    QAction *actionRedo;

private slots:
    void on_actionUndo_triggered();
    void on_actionRedo_triggered();
};

定义:

Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget) {
    ui->setupUi(this);   
    QVBoxLayout *layout = new QVBoxLayout(this);
    QMenuBar *menuBar = new QMenuBar();
    QMenu *editMenu = new QMenu("&Edit");
    menuBar->addMenu(editMenu);

    this->actionUndo = new QAction("&Undo", editMenu);
    this->actionUndo->setShortcut(QKeySequence::Undo);
    QObject::connect(this->actionUndo, SIGNAL(triggered()), this, SLOT(on_actionUndo_triggered()));

    this->actionRedo = new QAction("&Redo", editMenu);
    this->actionRedo->setShortcut(QKeySequence::Redo);
    QObject::connect(this->actionRedo, SIGNAL(triggered()), this, SLOT(on_actionRedo_triggered()));

    editMenu->addAction(this->actionUndo);
    editMenu->addAction(this->actionRedo);

    this->layout()->setMenuBar(menuBar);
}

Widget::~Widget() {
    delete ui;
}


void Widget::on_actionUndo_triggered() {

}

void Widget::on_actionRedo_triggered() {

}

1 个答案:

答案 0 :(得分:2)

出现警告是因为在函数setupUi中调用函数connectSlotsByName

void setupUi(QWidget *Widget)
{
    [...]
    QMetaObject::connectSlotsByName(Widget);
}

根据文件:

  

void QMetaObject :: connectSlotsByName(QObject * object)

     

以递归方式搜索给定对象的所有子对象,以及   将来自它们的匹配信号连接到跟随的对象的插槽   以下表格:

     

void on_<object name>_<signal name>(<signal parameters>);

然后此函数查找对象actionUndoactionRedo并找不到它们,因为它们未创建,一个简单的解决方案是在setupUi之前创建它们并使用setObjectName传递名称:

actionUndo = new QAction("&Undo", this);
actionUndo->setObjectName("actionUndo");
actionRedo = new QAction("&Redo", this);
actionRedo->setObjectName("actionRedo");
ui->setupUi(this);

使用此配置,您将不再需要建立连接,即您不需要实现下一行。

QObject::connect(this->actionUndo, SIGNAL(triggered()), this, SLOT(on_actionUndo_triggered()));
QObject::connect(this->actionRedo, SIGNAL(triggered()), this, SLOT(on_actionRedo_triggered()));

完整代码:

<强>·H

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

private slots:
    void on_actionUndo_triggered();
    void on_actionRedo_triggered();

private:
    Ui::Widget *ui;
    QAction *actionUndo;
    QAction *actionRedo;
};

<强>的.cpp

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    actionUndo = new QAction("&Undo", this);
    actionUndo->setObjectName("actionUndo");
    actionUndo->setShortcut(QKeySequence::Undo);

    actionRedo = new QAction("&Redo", this);
    actionRedo->setObjectName("actionRedo");
    actionRedo->setShortcut(QKeySequence::Redo);

    ui->setupUi(this);

    setLayout(new QVBoxLayout);

    QMenuBar *menuBar = new QMenuBar(this);
    QMenu *editMenu = new QMenu("&Edit");

    menuBar->addMenu(editMenu);
    editMenu->addAction(actionUndo);
    editMenu->addAction(actionRedo);

    layout()->setMenuBar(menuBar);

}

Widget::~Widget()
{
    delete ui;
}


void Widget::on_actionUndo_triggered()
{
    qDebug()<<"undo";
}

void Widget::on_actionRedo_triggered()
{
    qDebug()<<"redo";
}