1.3.3 Qt:概念解析 -- 2017.11.8

HuRui 发布于 2017/11/08 15:46
查看:626|回复:2

    实践是检验真理的唯一标准,而概念是检验的充分条件...

伙伴编辑模式(Edit Buddy)

QLabel标签和伙伴(buddy)窗口部件包括一个标签(QLabel)和一个窗口部件,它们具有伙伴关系,即指当用户激活标签的快捷键时,鼠标/键盘的焦点将会转移到它的伙伴窗口部件上。只有QLabel标签对象才可以有伙伴窗口部件,也只有该QLabel对象具有快捷键时(在显示文本的某个字符前面添加一个前缀“&”,就可以定义快捷键),伙伴关系才有效,例如:

QLineEdit *ageLineEdit = new QLineEdit(this);

QLabel* ageLabel = new QLabel("age",this);

ageLabel->setBuddy(ageLineEdit);


代码定义了ageLabel标签的组合键为【Alt+A】,并将行编辑框ageLineEidt设为它的伙伴窗口部件。所以当用户按下组合键【Alt+A】时,焦点将会跳至行编辑框ageLineEidt中,Qt设计器提供了伙伴编辑模式,可通过鼠标拖曳快捷地建立标签QLabel和其他窗口部件的伙伴关系


1.信号和槽机制(Signal & Slot)

Qt提供了信号和槽机制用于完成界面操作的响应,是完成任意两个Qt对象之间的通信机制。其中,信号会在某个特定情况或动作下被触发,槽是等同于接收并处理信号的函数。 例如,若要将一个窗口部件的变化情况通知给另一个窗口部件,则一个窗口部件发送信号,另一个窗口部件的槽接收此信号并进行相应的操作,即可实现两个窗口部件之间的通信。每个Qt对象都包含若干个预定义的槽,当某一个特定事件发生时,一个信号被发送,与信号相关联的槽则会响应信号并完成相应的处理,当一个类被继承时,该类的信号和槽也同时被继承,也可以根据需要自定义信号和槽


1>信号与槽机制的连接方式

(1)一个信号可以与另一个信号相连,代码如下:

connect(Object1,SIGNAL1),Object2,SIGNAL(signal1));

表示Object1的信号1发送可以触发Object2的信号1发送


(2)同一个信号可以与多个槽相连,代码如下:

connect(Object1,SIGNAL2),Object2,SIGNAL(slot2));

connect(Object3,SIGANL2),Object3,SIGNAL(slot1));


(3)同一个槽可以响应多个信号,代码如下:

connect(Object1,SIGNAL(signal2),Object2,SIGNAL(slot2));

connect(Object3,SIGNAL(signal2),Object2,SIGNAL(slot2));

但是,常用的连接方式为:

connect(Object1,SIGNAL(signal1),Object2,SLOT(slot));

其中,signal为对象Object1的信号,slot为对象Object2的槽

SIGNAL()和SlOT()是Qt定义的两个宏,它们返回其参数的C语言风格的字符串(const char*),因此,下面关联信号和槽的两个语句是等同的:

connect(button,SIGNAL(clicked()),this,SLOT(showArea()));

connect(button,"clicked()",this,"showArea()");


2>信号与槽机制的优点

(1)类型安全。需要关联的信号和槽的签名必须是等同的,即信号的参数类型和参数个数与接收该信号的槽的参数类型和参数个数相同,不过,一个槽的参数个数是可以少于信号的参数个数的,但缺少的参数必须是信号参数的最后一个或几个参数,如果信号和槽的签名不符,编译器就会报错。

(2)松散耦合。信号和槽机制减弱了Qt对象的耦合度。激发信号的Qt对象无须知道是哪个对象的哪个槽需要接收它发出的信号,它只需做的是在适当的时间发送适当的信号就可以了,而不需要知道也不关心它的信号有没有被接收到,更不需要知道是哪个对象的哪个槽接收到了信号,同样,对象的槽也不知道是哪些信号关联了自己,而一旦管理信号和槽,Qt就保证了适合的槽得到了调用。即使关联的对象在运行时被删除,应用程序也不会崩溃一个类若要支持信号和槽,就必须从QObject或QObject的子类继承。注意,Qt信号和槽机制不支持对模板的使用


3>信号与槽机制的效率

信号和槽机制增强了对象间通信的灵活性,然而这也损失了一些性能。同回调函数相比,信号和槽机制运行速度有些慢,通常,通过传递一个信号来调用槽函数将会比直接调用非虚函数运行速度慢10倍,原因如下:

(1)需要定位接收信号的对象

(2)安全地遍历所有的关联(如一个信号关联多个槽的情况)

(3)编组(marshal)/解组(unmarshal)传递的参数

(4)多线程的时候,信号可能需要排队等待

然而,与创建堆对象的new操作即删除堆对象的delete操作相比,信号和槽的运行代价只是它们很少的一部分,信号和槽机制导致的这点性能损耗,对实时应用程序是可以忽略的;同信号和槽提供的灵活性和简便性相比,这点性能的损失也是值得的


Qt5元对象系统

Qt元对象系统提供了对象间的通信机制(信号和槽)、运行时类型信息和动态属性系统的支持,是标准C++的一个扩展,它使Qt能够更好地实现GUI图形用户界面编程。Qt的元对象系统不支持C++模板,尽管模板扩展了标准C++的功能,但是元对象系统提供了模板无法提供的一些特性。Qt元对象系统基于以下三个事实。

(1)基类QObject:任何需要使用元对象系统功能的类必须继承自QObject

(2)Q_OBJECT宏:Q_OBJECT宏必须出现在类的私有声明区,用于启动元对象的特性

(3)元对象编译器(Meta-Object Complier,moc):为QObject子类实现元对象特性必须提供必要的代码实现


L3 布局管理器

在设计较复杂的GUI用户界面时,仅通过指定窗口部件的父子关系以期达到加载和排列窗口部件的方法是行不通,最好的办法是使用Qt提供的布局管理器。

QGridLayout *mainLayout = new QGridLayout(this);      //(a)

mainLayout->addWidget(label1,0,0);                    //(b)

mainLayout->addWidget(lineEdit,0,1);

mainLayout->addWidget(label2,0,1);

mainLayout->addWidget(button,1,1);

setLayout(mainLayout);                                //(c)

其中,(a)QGridLayout *mainLayout=new QGridLayout(this):创建一个网格布局管理器对象mainLayout,并用this指出父窗口

(b)mainLayout->addWidget(...):分别将控件对象label1,lineEdit、label2和button放置在该管理器中,还可以在创建布局管理器对象时不必指明父窗口

(c)QWidget::setLayout(...):将布局管理器添加到对应的窗口部件对象中,因为这里的主窗口就是父窗口,所以直接调用setLayout(mainLayout)即可

                                    be1f99fd311286655aa45899591efce6003.gif

             - - - - - - - - - 害你加班的bug,就是我写的 - - - - - - - - - 

查看点赞情况
全部点赞
总计: --

共有2条评论

  • HuRui HuRui

    B_109.gif 欢迎喜欢编程的朋友们来交流,分享....

    沙发 2017/11/08 15:47 回复
发布新贴
招版主啦

版主

  • 西米酱 西米酱
  • xly xly
  • 章鱼哥笔记 章鱼哥笔记

注册有礼

完善以下信息,为你推荐课程

  • 学生
  • 白领
  • 高管
  • 自由职业
  • 其他
  • 工作需要
  • 自我提升
  • 兴趣爱好
  • 创业/转型
  • 其他
  • 小白
  • 了解
  • 熟悉
  • 精通
  • 其他
  • 高中/中专
  • 专科
  • 本科
  • 硕士
  • 其他
  • 影视枪战大片特效解析
  • PS视觉惊悚课堂
  • 45天7千平方大厦变形记
  • 原画学习痛点技法全解析
  • 影视动画奇幻课堂
  • AI高端商业设计全攻略
  • UG职场生存必备指南
  • 日赚千元之新媒体行业揭秘
出现异常