Chinaunix首页 | 论坛 | 博客
  • 博客访问: 31901
  • 博文数量: 15
  • 博客积分: 386
  • 博客等级: 一等列兵
  • 技术积分: 185
  • 用 户 组: 普通用户
  • 注册时间: 2012-05-25 15:22
文章分类

全部博文(15)

文章存档

2012年(15)

我的朋友
最近访客

分类: C/C++

2012-06-14 15:36:32

Qt的信号与槽可以让程序吧一些互不相干的对象绑定在一块,槽和普通的C++成员函数差不多,可以是虚函数或被重载,也可以共有、保护、或者是私有,且可以被其他C++成员直接调用,唯一不同的是经过signals和slots连接到一起,每当发射signals信号的时候可以自动调用绑定的槽。

Connect()的语法:

connect(sender,SIGNAL(signal),receiver,SLOT(slots));

sender,receiver必须是一个QObject的指针,signal和slot是根据声明的信号或槽的函数来决定参数的。例如:


点击(此处)折叠或打开

  1. signals:
  2.     void setvalue(int value);
  3. private slots:
  4.     void changevalue(int value);
注意参数的一致性。

如果带参数那么connect应该是这个样子的。

connect(sender,SIGNAL(setvalue(int)),receiver,SLOT(changevalue(int)));

下面我们来看一个程序界面。

.
 

程序功能是当拖动QSlider时,界面的四个控件会同时获取并同步QSlider的值。

我们来看一下程序代码:

h文件


点击(此处)折叠或打开

  1. #ifndef DIALOG_H
  2. #define DIALOG_H

  3. #include <QDialog>
  4. #include <QSpinBox>
  5. #include <QSlider>
  6. #include <QProgressBar>
  7. #include <QHBoxLayout>
  8. #include <QVBoxLayout>
  9. namespace Ui {
  10. class Dialog;
  11. }

  12. class Dialog : public QDialog
  13. {
  14.     Q_OBJECT
  15.     
  16. public:
  17.     explicit Dialog(QWidget *parent = 0);
  18.     ~Dialog();
  19. signals:
  20.     void setvalue(int value);
  21. private:
  22.     Ui::Dialog *ui;
  23. private slots:
  24.     void changevalue(int value);
  25. };

  26. #endif // DIALOG_H


点击(此处)折叠或打开

  1. #include "dialog.h"
  2. #include "ui_dialog.h"

  3. Dialog::Dialog(QWidget *parent) :
  4.     QDialog(parent),
  5.     ui(new Ui::Dialog)
  6. {
  7.     ui->setupUi(this);
  8.     connect(ui->hslider,SIGNAL(valueChanged(int)),this,SIGNAL(setvalue(int)));
  9.     connect(ui->sbox,SIGNAL(valueChanged(int)),this,SIGNAL(setvalue(int)));
  10.     //disconnect(ui->sbox,SIGNAL(valueChanged(int)),this,SIGNAL(setvalue(int)));
  11.     connect(this,SIGNAL(setvalue(int)),SLOT(changevalue(int)));
  12. }

  13. Dialog::~Dialog()
  14. {
  15.     delete ui;
  16. }
  17. void Dialog::changevalue(int value)
  18. {
  19.     ui->lcd->display(value);
  20.     ui->probar->setValue(value);
  21.     ui->sbox->setValue(value);
  22.     ui->hslider->setValue(value);
  23. }


connect(ui->hslider,SIGNAL(valueChanged(int)),this,SIGNAL(setvalue(int)));//将QSlider的valueChanged信号绑定槽setvalue;
connect(ui->sbox,SIGNAL(valueChanged(int)),this,SIGNAL(setvalue(int)));//将QSpinBox的valueChanged信号绑定槽setvalue;
 //disconnect(ui->sbox,SIGNAL(valueChanged(int)),this,SIGNAL(setvalue(int)));//代码演示如何动态断开槽链接
connect(this,SIGNAL(setvalue(int)),SLOT(changevalue(int)));//将setvalue信号绑定槽setvalue;

一个信号可以链接到多个槽。

多个信号可以链接到同一个槽

一个信号可以与另外一个信号链接(这里第一行与第二行已经演示了)。

动态连接移除功能很少被用到,因为除特别功能上的需要,当Qt删除对象时会自动移除与这个对象有关的所有链接。

Qt一个最大的特点就是他用特殊的机制来扩展c++。利用这个机制创建的软件组件是独立的,这些组件可以和其他的组件绑定在一起,而不需要知道他要绑定的组件的太多的信息。

这个机制就叫做元对象系统,它提供了两个重要的服务:signal-slot和内省。内省的功能对于实现signal-slots是很重要的,它允许应用程序员程序运行期间来获得关于子对象的“元信息”,包括对象和他的名字所支持的signal和slot列表。这个机制支持properties(Qt设计器广泛的使用)和文本转换(为了国际化)它也为QtScrpt单元打下了基础。从Qt4.2开始,properties可以动态的添加。

标准C++不支持Qt的元对象系统所需要的动态元信息。Qt利用分开的工具,moc,解析Q_OBJECT类的定义来解决这个问题,通过C++函数来使它有效。因为moc所有功能都是通过纯粹的C++来实现的,所以Qt的元对象系统可以再任何的c++编译器下工作。

这个机制有如下工作:
1)Q_OBJECT宏声明了一些内省函数,这些函数必须在QOBJECT的子类(metaObject(),tr(),qt_metacall()等)中实现;
2)Qt的moc实现Q_OBJECT和所有signals声明的函数
3)QOBJECT的成员函数利用内省的功能来做完成他们的工作,像connection(),disconnect();

所有的这些工作都是依靠qmake,moc和QOBJECT来自动处理的,我们不需要去考虑他们的细节。



阅读(1920) | 评论(0) | 转发(2) |
给主人留下些什么吧!~~