php button只能点击一次,[紧急求助]一个pushButton,我点击一次,却提交了两次,百思不得其解...

没有。但这个是设计器做的事

QT自动连接信号与槽

查看Qt4的一些示例项目的时候,使用设计器打开其UI文件,在文件中竟然找不到signal和slot的连接。但是最终的程序,slot却又能准确的响应信号。打开通过ui文件自动生成的c++文件,其中也找不到connect语句,到底是怎么一回事?

经过逐语句的分析。终于发现连接的原因就在于setUi函数的最后一句

QMetaObject::connectSlotsByName(MainWindow);

找到该静态函数

void QMetaObject::connectSlotsByName(QObject *o)

{

if (!o)

return;

const QMetaObject *mo = o->metaObject();

Q_ASSERT(mo);

const QObjectList list = qFindChildren(o, QString());

for (int i = 0; i < mo->methodCount(); ++i) {

/*

slot是方法的名字,在以下的内容中,会把它分成三部分(依次判断该方法是否满足这三部分的条件):

第一部分:on_

第二部分:子对象名

第三部分:信号名

*/

const char *slot = mo->method(i).signature();

Q_ASSERT(slot);

//以下一行用来判断slot的前三位是否是on_,如果不是,就跳过这个方法。

if (slot[0] != 'o' || slot[1] != 'n' || slot[2] != '_')

continue;

bool foundIt = false;

//遍历子对象。

for(int j = 0; j < list.count(); ++j) {

const QObject *co = list.at(j);

//得到子对象名。

QByteArray objName = co->objectName().toAscii();

int len = objName.length();

//要求slot跳过前3位(on_)后,接下来的子字符串和子对象名相同,并且接着该子字符串又是一个_

//如果达不到这个要求,continue

if (!len || qstrncmp(slot + 3, objName.data(), len) || slot[len+3] != '_')

continue;

const QMetaObject *smo = co->metaObject();

int sigIndex = smo->indexOfMethod(slot + len + 4);

if (sigIndex < 0) { // search for compatible signals

int slotlen = qstrlen(slot + len + 4) - 1;

//搜索该子对象所能引发的信号

for (int k = 0; k < co->metaObject()->methodCount(); ++k) {

//方法类型如果符合要求

if (smo->method(k).methodType() != QMetaMethod::Signal)

continue;

//如果slot最后的子字符串和信号名相同

if (!qstrncmp(smo->method(k).signature(), slot + len + 4, slotlen)) {

sigIndex = k;

break;

}

}

}

if (sigIndex < 0)

continue;

//连接操作

if (QMetaObject::connect(co, sigIndex, o, i)) {

foundIt = true;

break;

}

}

//连接成功

if (foundIt) {

// we found our slot, now skip all overloads

while (mo->method(i + 1).attributes() & QMetaMethod::Cloned)

++i;

}

//连接失败

else if (!(mo->method(i).attributes() & QMetaMethod::Cloned)) {

qWarning("QMetaObject::connectSlotsByName: No matching signal for %s", slot);

}

}

}

得出此结论:自动生成的文件中,该函数总会存在setUi函数的最后一句。

该函数的作用就是寻找setUi的唯一指针参数MainWindow所指向对象的成员函数,

该成员函数的名字如果满足以下条件,就做连接操作。

函数名规则:on_子对象名_信号名

函数签名(即返回值与参数要符合slot要求)

所以,我们可以这样做:在qt设计器中添加按纽或者菜单项或者按纽项后,不用在设计器中手动做连接操作。

我们只要在主窗口类中添加符合条件的成员函数即可。

函数名规则:on_子对象名_信号名

函数签名(即返回值与参数要符合slot要求)

例如:

在设计器中添加一个菜单项,其对应的action为actionNew

那么在主窗口类中添加以下的函数

public slots:

void on_actionNew_triggered();

当切换这个菜单时,会自动执行上面的成员函数。

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/myuml/archive/2009/06/10/4259079.aspx

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值