Не могу привязать сигнал к слоту в моем приложении Qt
Я новичок в Qt, и у меня есть очень простое демонстрационное приложение. Он просто включаетQLineEdit
виджет, и я хочу вызвать функцию test()
когда я нажимаю ctrl+p наQLineEdit
.
Ниже приведены связанные файлы.
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')
Что с этим не так?
2 ответа
У вас есть 2 заблуждения:
Соединение указывает на связь между объектом, излучающим сигнал, сигналом, объектом, которому принадлежит слот, и слотом. В вашем случае очевидно, что объект, которому принадлежит слот "слот", является следующим.
Если должен использоваться старый синтаксис (SIGNAL & SLOT), то "test" должен быть объявлен как слот.
Итак, для вышеуказанного есть 2 возможных решения:
- Изменить на:
connect(s, SIGNAL(activated()), this, SLOT(test()));
public slots:
void test();
- Или используйте новый синтаксис:
connect(s, &QShortcut::activated, this, &MainWindow::test);
Между обоими решениями второе лучше, поскольку оно будет указывать на ошибки во время компиляции, а не на тихие ошибки во время выполнения.
По умолчанию контекстом ярлыка является Qt::WindowShortcut, то есть он срабатывает, когда нажата комбинация клавиш и окно имеет фокус, если только когда QLineEdit имеет фокус, тогда вам нужно изменить контекст на Qt::WidgetShortcut:
s->setContext(Qt::WidgetShortcut);
Вы получили сообщение об ошибке, что такого слота нет...
Обратите внимание, что вы не отметили test()
как slot
, следовательно, в <mainwindow.h>
заменить
void test();
по
public slots: void test();
И слот test()
принадлежит главному окну, а не s
, поэтому используйте this
вместо того s