Не могу привязать сигнал к слоту в моем приложении 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 возможных решения:

  1. Изменить на:
connect(s, SIGNAL(activated()), this, SLOT(test()));
public slots:
    void test();
  1. Или используйте новый синтаксис:
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

Другие вопросы по тегам