Can't bind signal to slot in my Qt application

280 Views Asked by At

I'm new to Qt and I have a very simple demo app. It just include a QLineEdit widget and I want to invoke a function test() when I press ctrl+p in the QLineEdit.

Below are the related files.

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

When I compile the application, I saw below messages in the debug panel and the application didn't respond to ctrl+p.

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

What's the problem with it?

2

There are 2 best solutions below

5
On BEST ANSWER

You have 2 misconceptions:

  • The connection indicates the link between the object that emits the signal, the signal, the object to which the slot belongs and the slot. In your case it is obvious that the object to which the slot "slot" belongs is this.

  • If the old syntax (SIGNAL & SLOT) is to be used then "test" must be declared as slot.

So for the above there are 2 possible solutions:

  1. Change to :
connect(s, SIGNAL(activated()), this, SLOT(test()));
public slots:
    void test();
  1. Or use new syntax:
connect(s, &QShortcut::activated, this, &MainWindow::test);

Between both solutions, the second one is better since it will indicate errors in compile-time instead of silent errors in run-time.

By default, the context of the shortcut is Qt::WindowShortcut, that is, it will fire when the key combination is pressed and the window has focus, if only when QLineEdit has focus then you have to change the context to Qt::WidgetShortcut:

s->setContext(Qt::WidgetShortcut);
1
On

You have received the error message saying there is no such slot...

Note that u haven't marked test() as slot, hence in <mainwindow.h>, replace

void test();

by

public slots: void test();

And the slot test() belongs to the mainwindow not to s, hence use this instead of s