无法将信号绑定到我的 Qt 应用程序中的插槽

Can't bind signal to slot in my Qt application

我是 Qt 的新手,我有一个非常简单的演示应用程序。它只包含一个 QLineEdit 小部件,我想在 QLineEdit.[=17= 中按 ctrl+p 时调用函数 test() ]

下面是相关文件。

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QShortcut>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    QShortcut *s = new QShortcut(QKeySequence("Ctrl+P"), ui->lineEdit);
    connect(s, SIGNAL(activated()), ui->lineEdit, SLOT(test()));
}

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

void test(){
    qDebug() << "test() triggered!" << endl;
}

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
    void test();

private:
    Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H

当我编译应用程序时,我在调试面板中看到以下消息,应用程序没有响应 ctrl+p

QObject::connect: No such slot QLineEdit::test() in ..\ShortcutIssueDemo\mainwindow.cpp:13
QObject::connect:  (receiver name: 'lineEdit')

它有什么问题?

你有两个误解:

  • 连接表示发射信号的对象、信号、槽所属的对象与槽之间的link。在你的情况下,很明显插槽“slot”所属的对象是这个。

  • 如果要使用旧语法 (SIGNAL & SLOT),则必须将“test”声明为插槽。

所以对于上面的问题,有两种可能的解决方案:

  1. 更改为:
connect(s, SIGNAL(activated()), this, SLOT(test()));
public slots:
    void test();
  1. 或使用新语法:
connect(s, &QShortcut::activated, this, &MainWindow::test);

在两种解决方案之间,第二种更好,因为它会在 compile-time 中指示错误,而不是在 run-time 中指示错误。

默认情况下,快捷方式的上下文是Qt::WindowShortcut,也就是说,当按下组合键并且window有焦点时,它会触发,如果只有当QLineEdit有焦点时,那么你必须将上下文更改为 Qt::WidgetShortcut:

s->setContext(Qt::WidgetShortcut);

您收到错误消息,指出没有这样的插槽...

请注意,您没有将 test() 标记为 slot,因此在 <mainwindow.h> 中,替换

void test();

来自

public slots: void test();

并且插槽 test() 属于主窗口而不是 s,因此使用 this 而不是 s