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.
#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;
}
#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?
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:
connect(s, SIGNAL(activated()), this, SLOT(test()));
public slots:
void test();
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);