QT信号与槽的自动连接

信号与槽的自动连接

信号与槽可以通过使用手写代码显式的实现关联 ,也可以运用 QMetaObject 类规定的槽 函数命名范式来实现自动关联。

显式关联

首先我们来看一下,不使用“自动关联规则”的情形。 在下面这段代码里面,我们定义了一个对话框类,它有一个私有的槽 checkValues(), 它用来检验用户提供的值是否正确。 class ImageDialog : public QDialog, private Ui::ImageDialog { Q_OBJECT public: ImageDialog(QWidget *parent = 0); private slots: void checkValues(); }; 在这个对话框类的构造函数中,我们把 Cancel 按钮的 clicked()信号与对话框类的 reject()槽关联起来,把 OK 按钮的 clicked()信号与对话框类的 checkValues()槽关联起来, 这都是通过手写代码显式的实现的。 ImageDialog::ImageDialog(QWidget *parent)
QDialog(parent)
{
setupUi(this);
okButton->setAutoDefault(false);
cancelButton->setAutoDefault(false);

connect(okButton, SIGNAL(clicked()), this, SLOT(checkValues()));
}
void ImageDialog::checkValues()
{
if (nameLineEdit->text().isEmpty())
{
(void) QMessageBox::information(this, tr(“No Image Name”),
tr(“Please supply a name for the image.”), QMessageBox::Cancel);
}
else
{
accept();
}
}

自动关联

下面的例子演示了信号与槽自动关联的具体实现过程 。我们只需按照下面的标准格式定 义槽函数,这之后,uic 将会根据 QMetaObject 类制定的规则,生成界面实体类的 setupUi() 函数的内容,并完成信号与槽的关联,这一过程是隐藏在背后实现的,我们也无需过多关心。
void on__();
我们通过定义私有槽函数 on_okButton_clicked()即实现了 OK 按钮的 clicked()信号和槽的连接。+

class ImageDialog : public QDialog, private Ui::ImageDialog
{
Q_OBJECT
public:
ImageDialog(QWidget *parent = 0);
private slots:
void on_okButton_clicked();
};
信号与槽的自动连接机制提供了一种槽函数的命名范式,它简化了程序设计者的工作 ,使得用户界面设计变得有章可循并且充满乐趣。笔者建议读者朋友尽量采用这种方法来设 计 Qt 用户界面。

第一种, 普通的连接.
调用QObject::connect()即可. 如果是在某个自定义的继承自QObject的子类, 那么记得在类里面写Q_OBJECT宏. 如果忘写了的话貌似编译期也不会报错, 只是实际上没有链接成功而已. 好吧, IDE党可以无视这一点了……

第二种, 文艺的连接.
void on__();只要把槽函数的名字写成这种形式, 例如 void on_button_clicked(); 这样只要按下ObjectName为button的那个QPushButton, 就可以调用这个槽了. 连接的过程已经被自动完成了.

对于初学者来说, 可能看过文艺连接方法之后觉得此法甚是文艺, 结果纷纷效仿, 于是可能纷纷杯具, 症状如下: 明明已经把槽函数的名字中规中矩的写对了, 为神马信号和槽貌似完全木有链接上?

这个杯具哥的代码可能是这样的:
在自定义的widget中一个私有成员是QPushButton* button;然后widget的一个slot名字是
void on_button_clicked();并在这个slot中实现了这个button的相关功能.
编译神马的看起来完全木有问题, 但是运行时狂点这个button也不见任何效果……

好吧, 首先得承认这个杯具哥就是楼主自己……
goooogle了一番, 其实原因还是很简单的, 仔细看看on__(), on后面需要的是object name哈, QPushButton* button; button是变量名啊, object name是QObject的一个属性, 和变量名木有半毛钱关系………
button->setObjectName(“button”); 在构造函数中button分配了内存后面填上这句. 但是问题木有完全解决, 还要在构造函数中加上QMetaObject::connectSlotsByName(this);显式调用connectSlotsByName()才可以.

总结起来就是这样的:
文艺的连接适用于使用designer的情况, 用designer画出来的控件神马的都是自带Object Name的. 于是直接把对应的槽写成on__()形式, 就可以省去若干个connect().
但是如果不使用designer, 又要connectSlotsByName, 就得手动设置object name, 然后再显式调用connectSlotsByName()…..看起来真的好2B…….

所以, 不用designer的话, 看起来还是老老实实的connect的好……

  • 7
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值