0

我是 Qt 新手,我有一个非常简单的演示应用程序。它只包含一个QLineEdit小部件,我想在test()按下.ctrl+pQLineEdit

下面是相关文件。

主窗口.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;
}

主窗口.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')

它有什么问题?

4

2 回答 2

4

你有两个误解:

  • 连接表示发出信号的对象、信号、槽所属的对象和槽之间的链接。在您的情况下,很明显插槽“插槽”所属的对象就是这个。

  • 如果要使用旧语法(SIGNAL & SLOT),则必须将“test”声明为 slot。

因此,对于上述情况,有两种可能的解决方案:

  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);
于 2020-08-16T22:33:24.190 回答
1

您收到了错误消息,说没有这样的插槽...

请注意,您没有标记test()slot,因此在<mainwindow.h>,替换

void test();

经过

public slots: void test();

并且该插槽test()不属于主窗口s,因此使用this而不是s

于 2020-08-16T22:33:56.887 回答