无法将信号绑定到我的 Qt 应用程序中的插槽
Can't bind signal to slot in my Qt application
我是 Qt 的新手,我有一个非常简单的演示应用程序。它只包含一个 QLineEdit
小部件,我想在 QLineEdit
.[=17= 中按 ctrl+p 时调用函数 test()
]
下面是相关文件。
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')
它有什么问题?
你有两个误解:
连接表示发射信号的对象、信号、槽所属的对象与槽之间的link。在你的情况下,很明显插槽“slot”所属的对象是这个。
如果要使用旧语法 (SIGNAL & SLOT),则必须将“test”声明为插槽。
所以对于上面的问题,有两种可能的解决方案:
- 更改为:
connect(s, SIGNAL(activated()), this, SLOT(test()));
public slots:
void test();
- 或使用新语法:
connect(s, &QShortcut::activated, this, &MainWindow::test);
在两种解决方案之间,第二种更好,因为它会在 compile-time 中指示错误,而不是在 run-time 中指示错误。
默认情况下,快捷方式的上下文是Qt::WindowShortcut,也就是说,当按下组合键并且window有焦点时,它会触发,如果只有当QLineEdit有焦点时,那么你必须将上下文更改为 Qt::WidgetShortcut:
s->setContext(Qt::WidgetShortcut);
您收到错误消息,指出没有这样的插槽...
请注意,您没有将 test()
标记为 slot
,因此在 <mainwindow.h>
中,替换
void test();
来自
public slots: void test();
并且插槽 test()
属于主窗口而不是 s
,因此使用 this
而不是 s
我是 Qt 的新手,我有一个非常简单的演示应用程序。它只包含一个 下面是相关文件。 当我编译应用程序时,我在调试面板中看到以下消息,应用程序没有响应 ctrl+p。 它有什么问题?QLineEdit
小部件,我想在 QLineEdit
.[=17= 中按 ctrl+p 时调用函数 test()
]
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
QObject::connect: No such slot QLineEdit::test() in ..\ShortcutIssueDemo\mainwindow.cpp:13
QObject::connect: (receiver name: 'lineEdit')
你有两个误解:
连接表示发射信号的对象、信号、槽所属的对象与槽之间的link。在你的情况下,很明显插槽“slot”所属的对象是这个。
如果要使用旧语法 (SIGNAL & SLOT),则必须将“test”声明为插槽。
所以对于上面的问题,有两种可能的解决方案:
- 更改为:
connect(s, SIGNAL(activated()), this, SLOT(test()));
public slots:
void test();
- 或使用新语法:
connect(s, &QShortcut::activated, this, &MainWindow::test);
在两种解决方案之间,第二种更好,因为它会在 compile-time 中指示错误,而不是在 run-time 中指示错误。
默认情况下,快捷方式的上下文是Qt::WindowShortcut,也就是说,当按下组合键并且window有焦点时,它会触发,如果只有当QLineEdit有焦点时,那么你必须将上下文更改为 Qt::WidgetShortcut:
s->setContext(Qt::WidgetShortcut);
您收到错误消息,指出没有这样的插槽...
请注意,您没有将 test()
标记为 slot
,因此在 <mainwindow.h>
中,替换
void test();
来自
public slots: void test();
并且插槽 test()
属于主窗口而不是 s
,因此使用 this
而不是 s