一、回调函数
回调函数就是一个通过函数指针调用的函数。A类将一个函数的地址作为参数传给B类的一个函数,此时A类就不用关心这个函数的执行了。当B类里面触发了某个特定的条件,B类调用这个回调函数,进行响应。
二、回调函数的例子
(1)主窗体
//MainWindow.h
public:
//静态方法的回调函数
static void setPos(MainWindow *m, const QPointF &r);
void setLinePos(const QPointF &r);
//MainWindow.cpp------------------------------------------------------
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
//widget提升为了子部件
//把对象实例的指针或引用做为参数传给子部件。就能找到主窗口中的控件。
ui->widget->setCallbackFunc(this, setPos);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::setPos(MainWindow *m, const QPointF &r)
{
//静态函数中,没有this指针,因此需要传当前对象,否则无法拿到lineEdit控件
m->setLinePos(r);
}
void MainWindow::setLinePos(const QPointF &r)
{
ui->lineEdit1->setText(QString::number(r.x()));
ui->lineEdit2->setText(QString::number(r.y()));
}
(2)子部件
//Call.h
public:
explicit Call(QWidget *parent = nullptr);
~Call();
void setCallbackFunc(MainWindow *m, void(*func) (MainWindow *m, const QPointF &point));
protected:
void paintEvent(QPaintEvent *event);
void keyPressEvent(QKeyEvent *event);
private:
void(*m_callbackFunc)(MainWindow *m, const QPointF &point);
MainWindow *m_m;
//Call.cpp-----------------------------------------------------
Call::Call(QWidget *parent)
:QWidget(parent)
{
setFocusPolicy(Qt::StrongFocus);
}
Call::~Call()
{
}
void Call::setCallbackFunc(MainWindow *m,void(*func) (MainWindow *m, const QPointF &point))
{
//保存回调函数地址,以及主窗口对象
m_m = m;
m_callbackFunc = func;
}
void Call::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event);
//想要绘图生效,painter必须关联到画图设备,当前代码中画图设备为this(当前窗口)
QPainter painter(this);
painter.setPen(Qt::white);
painter.setBrush(Qt::red);
painter.drawRect(0, 0, 50, 50);
}
void Call::keyPressEvent(QKeyEvent *event)
{
//获取键盘事件,事件触发后,进行移动
switch(event->key())
{
case Qt::Key_Up:
move(this->x(), this->y() - 20);
break;
case Qt::Key_Down:
move(this->x(), this->y() + 20);
break;
case Qt::Key_Left:
move(this->x() - 20, this->y());
break;
case Qt::Key_Right:
move(this->x() + 20, this->y());
break;
default:
break;
}
//子部件调用回调函数,将此时的部件坐标告诉对应的主窗口
m_callbackFunc(m_m, this->pos());
}
三、回调函数为什么需要加static?
在类中封装回调函数,回调函数必须要加上static关键字,这样this指针就不能用了,类中静态函数只能访问类的静态成员,不能访问类中的非静态成员,静态函数属于这个类,而不再仅仅属于具体的对象,类的静态函数中没有默认的this指针。但是为什么要这要做呢?
//1.例如一个回调函数被要求声明为以下形式(正确格式):
void CALLBACK function();
//2.如果这个函数在类ObjClass里面,编译器会为其添加一个this指针,
//用于指向调用该函数的对象。所以编译出来的代码是这种形式:
void CALLBACK ObjClass::function(ObjClass* this);
函数参数列表与被要求声明的形式不一致。就比如说,主窗口中回调函数中有this指针,但是子部件调用的时候可没有。没有了this,而我们也恰巧需要使用主窗口中的控件,我们可以把对象实例的指针或引用做为参数传给子部件。
参考各位大佬的文章,再次感谢!
百度百科:回调函数
喜欢吃冰棍de谷利文君:Qt错误:Painter not active
菌丶:类中的回调函数要加static的原因
云端的蜗牛:C++回调函数必须为静态函数的原因
lesliefish:在Qt中使用回调函数替代信号槽
来源:CSDN
作者:daboluo520
链接:https://blog.csdn.net/guorong520/article/details/103685871