• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

QT信号槽与Delphi事件的对比

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

最近学QT,对信号槽机制感到有点新鲜:

QObject::connect(slider, SIGNAL(valueChanged(int)), lcd, SLOT(display(int)));

自己总结其原理,就是一句话:把两个对象的函数相关(往往是设置同一个值),而不用考虑两个对象之间的关系,而且可以一对多发信号。缺点是,事先要规定哪些函数可以信号,哪些函数是槽。而且执行内容貌似有点单调。

 

这一机制号称先进,但Delphi里其实也有,而且应该更强大,因为信号槽可以任意指定(不需要专门定义),至于信号本身,控件已经把常用的信号都给你定义好了,如果还不够则需要自己继承后增加,不过也很容易。而且没有反应速度慢一个数量级一说。而且设计时就可以Connect,动态增加/改变/Deconnect也行。设计的时候,其机制被存储在.dfm文件里:

object Edit1: TEdit
Left = 136
Top = 80
Width = 121
Height = 21
TabOrder = 0
Text = 'Edit1'
OnChange = Edit1Change
OnClick = Edit1Click
end

这是可视化设计的做法。如果忘了这么做,动态写语句也可以,而且就一句话:

    Edit1.OnClick := Button2Click (以OnClick事件为例,注意它不是OnMouseDown和OnMouseUp事件,但它们之间也有一定的联系。OnClick事件实际上是由OnMouseUp函数来执行的)

缺点是,必须要事先定义FOnClick这个事件,其类型是定义在TControl里的 FOnClick: TNotifyEvent; 也就是必须事先定义槽。至于信号无所谓,只要参数一致即可(我猜测,通过复杂的语法变幻,没准参数都不必一致)。定义了槽就可以随时动态插拔要执行的函数,真是方便:

procedure TControl.Click;
begin
if Assigned(FOnClick) then
FOnClick(Self);
end;

通过调用Click这个专门检查槽和执行槽的函数,达到触发槽的目的。但是还不够,触发前后肯定要做一堆事情,并且要加上条件判断才行,看这里:

procedure TControl.WMLButtonUp(var Message: TWMLButtonUp);
begin
inherited; // 怪异,为什么要先执行这个?会去执行DefaultHandler。答案可以到TForm和TEdit里去寻找
if csCaptureMouse in ControlStyle then MouseCapture := False;
if csClicked in ControlState then
begin
Exclude(FControlState, csClicked);
if PtInRect(ClientRect, SmallPointToPoint(Message.Pos)) then Click; // 判断落点,然后才触发;否则无效
end;
DoMouseUp(Message, mbLeft);
end;

但是到底谁来触发这个槽呢(第一驱动力)?Windows下说到底是要靠消息来触发,所以就很简单啦:

procedure WMLButtonUp(var Message: TWMLButtonUp); message WM_LBUTTONUP;


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
Delphi的ORM工具:InstantObjects初探发布时间:2022-07-18
下一篇:
delphiforandroid获取手机号发布时间:2022-07-18
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap