c++qtqshortcut

Can't bind signal to slot in my Qt application


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?


Solution

  • You have 2 misconceptions:

    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);