> 文章列表 > (二十三)槽函数的书写规则导致槽函数触发2次的问题

(二十三)槽函数的书写规则导致槽函数触发2次的问题

(二十三)槽函数的书写规则导致槽函数触发2次的问题

在创建QT的信号和槽时,经常无意间保留着QT书写槽函数的习惯,或者在QT设计界面直接右键【转到槽】去创建槽函数,但是后期需要用到disconnect时,又重新写了一遍connect函数,那么你会发现实际槽函数执行了2遍。

首先来看下这种QT的槽函数书写习惯:void on__();
例如,我创建了一个lineEdit,并且给这个控件的oeject name命名为lineEdit,那么这个lineEdit的textChanged信号对应的默认槽函数就是:
void on_lineEdit_textChanged(QString text);
那么这种命名方式有什么问题呢?首先看下这个代码:

void MainWindow::on_lineEdit_textChanged(QString text)
{count ++;//一个自增的int值qDebug() << count;ui->label->setText(text);//一个label来显示text变化
}

很明显这个命名规则是符合QT命名规则的,那么我们此时不去创建connect,仅仅去emit一个signal会发生什么呢?

emit ui->lineEdit->textChanged("test");

(二十三)槽函数的书写规则导致槽函数触发2次的问题
可以明显看到label的test发生了变化。

我们再做一个实验,新增一个connect去试下槽函数执行了几次:

connect(ui->lineEdit, &QLineEdit::textChanged, this, &MainWindow::on_lineEdit_textChanged);

(二十三)槽函数的书写规则导致槽函数触发2次的问题
可以看到实际槽函数执行了2遍,这就不符合我们的实际需求了。

我们来看下为什么呢?点击进去ui_文件中,你可以看到这一句函数:

QMetaObject::connectSlotsByName(MainWindow);

QT对此做了解释:
Searches recursively for all child objects of the given object, and connects matching signals from them to slots of object that follow the following form:
void on_();
Let’s assume our object has a child object of type QPushButton with the object name button1. The slot to catch the button’s clicked() signal would be:
void on_button1_clicked();
递归搜索给定对象的所有子对象,并将来自这些子对象的匹配信号连接到遵循以下形式的对象槽
可以看到QT会去搜索所有的对象,并且把这些子对象的信号连接到符合void on
_()形式的槽函数上,并且这种连接是自动的!!!!
难怪我们自己connect以后,槽函数会执行2遍,因为QT帮助我们自动connect了一次。

为了避免这种方式的错误,那么我们最好在写槽函数的时候,不要遵守QT的槽函数明明方式,最简单的就是不要加on_;或者如果想用QT自带的信号槽,那就不要多于的去connect。