Qt 自定义信号与槽

注 对象与槽理解

    //第一个参数lineEdit是激发事件对象,信号中的方法必须在对象中存在,并在对象类头文件signals下定义,
    //第二个参数信号,
    //第三个参数this是槽方法所属类的对象,且必须在对象类的头文件的slots下定义
    //第四个参数槽方法类,槽 方法
    connect(lineEdit,SIGNAL(textChanged(QString)),this,SLOT(showArea()));

使用自定义的信号和槽,需要注意以下几点: 
1、类的声明和实现分别放在.h和.cpp文件中; 
2、类声明中包含Q_OBJECT宏; 
3、信号只要声明不要设计其的实现函数; 
4、发射信号用emit关键字; 
5、自定义槽的实现与普通成员函数的实现一样。 

6、信号和槽方法必须在类的头文件中定义

本文所示代码在windows xp + MingW3.4.2+ eclipse3.4+CDT5.0版本中调试通过
    QT系统为我们提供功能非常全面信号处理机制,它的内制信号和槽已经非常全面,因此大多数情况下,我们不需要自己设计信号和槽,但是有些时候,我们可能需要设计一些独特的信号和槽,来满足程序的需求。QT的核心机制信号和槽是独立于C++的,一般C++设计处理如按钮点击等方法,多采用回调函数,而回调函数设计上的复杂,虽然执行效率相对于QT信号与槽要高,但是其导制容易出错。况且在日常应用程序设计中来说,这种高效率相差不成比例,因此QT采用自己独门设计,来高效的编程。本文也同样倡导大家使用信号与槽。
    如何才能设计自己的信号和槽呢,阅读完本节您将会轻松实现自己的需求。
    在创建信号和槽之前首先大家需要建立三个文件:类申明文件(yourclass.h),类实现文件(youclass.cpp),程序主体文件(main.cpp)。
    请看下面的例子,假设我们需要一个来处理文本框的内容的程序,程序主界面有两个按钮,当们点击按钮[Modify]时,文本框内容被改为“jingjing”。
1、自定义槽:
    按钮点击信号clilcked()通过继承已经存在,因此我们暂时不需要定义这个信号。那么我们要改变文本框内容,就需要自己定义一个槽,来响应点击信号。
    示例代码(类申明文件 yourclass.h):

复制代码

  1. #ifndef YOURCLASS_H_
  2.     #define YOURCLASS_H_
  3.     #include <QWidget>                        //QT窗口应用程序需要包含的文件
  4.     #include <QPushButton>                    //制作按钮时,需要包含
  5.     #include <QLineEdit>                      //制作文本框时,需要包含
  6.     class MyMainWindows:public QWidget        //申明一个MyMainWindows类,这个类用于实现窗体
  7.     {                                                         
  8.      Q_OBJECT                            //Q_OBJECT是在定制信号和槽和必须包含的一条宏语句
  9.     public:                                                   
  10.         MyMainWindows();                    //类构造函数(用于实现程序的主体部份)
  11.     public slots:                              //所有的槽函数都必须申明public slots语句内
  12.           void SlotTest();                    //这个槽函数用于显应点击按钮时改变文本框内容
  13.     private:
  14.         QPushButton * pb;                    //申请一个按钮QPushButton
  15.         QLineEdit * ledit;                      //申请一个文本框ledit
  16.     };
  17.     #endif /* YOURClASS_H_ */   

    在上面的示例代码中,我们申明了一窗口应用程序类文件,它的功能是申明程序所需要全部元素信息。在这个类中,我们申明了自己的槽SlotTest()函数,来响应按钮点击的信号。如下所示:

复制代码

  1. public slots:                              //所有的槽函数都必须申明public slots语句内
  2.           void SlotTest();                    //这个槽函数用于显应点击按钮时改变文本框内容

    正如代码中注释说明,在自定义槽和信号是有两点是至关重要的:
    第一点:所有的槽函数都需要包含在public slots语句下面。它的申明和类的公有函数方法pulic是类似的。如果你有多个槽函数,只要需要一一列出即可。
    第二点;在类的文件开始部份应含Q_OBJECT宏语句,请记住它不需要标点符号,所以不要加[;]符号。所有的QT自定义槽和信号都需要有它的存在。
    下面是制作第二个文件:类实现文件yourclass.cpp。在这个文件用于yourclass.h中申明的元素实现部份。
    示例代码(类实现文件yourclass.cpp)

复制代码

  1. #include "yourclass.h"                                  //包含yourclass.h类申明文件
  2. MyMainWindows::MyMainWindows()                    //实现构造函数
  3. {
  4.   setGeometry(90,90,300,200);                          //绘制主窗体,大小为300X200
  5.   pb = new QPushButton("Modify",this);                  //实现pb按钮,被设计其名字为Modify
  6.   pb->setGeometry(10,10,100,20);                        //绘制pb按钮的位置(10,10)和大小(100,20)
  7.   ledit = new QLineEdit("what's your name",this);          //实现ledit文件框,其内容为what's your name
  8.   ledit->setGeometry(10,30,200,150);                    //绘制ledit文件框位置(10,30)和大小(200,150)
  9.   connect(pb,SIGNAL(clicked()),this,SLOT(SlotTest()));    //连接pb按钮的点击clicked()信号和自定义槽SlotTest()
  10. }
  11. void MyMainWindows::SlotTest()                        //自定义槽函数的实现方法,重置文本框的内容
  12. {
  13.   ledit->setText("jingjing");                            //“jingjing”为点击按钮Modify后的内容
  14. }

在yourclass.cpp中,我们实现了程序的全部功能,程序的执行还需要有一个入口。它的主体部分mian.cpp。

复制代码

  1. #include <QApplication>              //所有QT应用程序都要包含QApplication头文件
  2. #include "yourclass.h"                //包含类定义文件yourclass.h
  3. int main(int argc,char * argv[])
  4. {
  5.   QApplication app(argc,argv);        //申明一个QT应用程序对像app
  6.   MyMainWindows w;                      //申明我们实现MyMainWindows窗体对像 w.
  7.   w.show();                                //显示这个w 窗体
  8.   return app.exec();
  9. }

程序编译完成后执行当点击Modify按钮,文本内容what's your name 被修改为jingjing
2、自定义信号
    在上例中,我们了解了怎样来实现自己的槽函数,在下文中我们将介绍怎么实现自己的信号。QT信号的申明与实现,相对QT槽函数来说,要更加容易一些。它相当于一系列函数原型。不需要有具体实现处理内容。在上文中,我们是通过点击clicked()这个信号,来连接槽函数SlotTest(),并达到修改文本框的内容。本例中,我们将在窗体添加一个文字标签label,然后在槽函数SlotTest()中测试label内容是否发生变化,如果发生了变化,就引发信号SigTest()。该信号连接到槽函数SlotTest2(),将文本框内容修改为"SigSig"。
    下面为实现文件:
    请打开上节中的yourclass.h文件,在代码加入一个槽函数SlotTest2(),和一个信号SigTest()。红色代码为新增加内容,如下所示:

复制代码

  1. #ifndef YOURCLASS_H_
  2.     #define YOURCLASS_H_
  3.     #include <QWidget>                        //QT窗口应用程序需要包含的文件
  4.     #include <QPushButton>                    //制作按钮时,需要包含
  5.     #include <QLineEdit>                      //制作文本框时,需要包含
  6.     #include <QLabel>                        //制作文本标签时,需要包含
  7.     class MyMainWindows:public QWidget        //申明一个MyMainWindows类,这个类用于实现窗体
  8.     {                                                         
  9.      Q_OBJECT                            //Q_OBJECT是在定制信号和槽和必须包含的一条宏语句
  10.     public:                                                   
  11.         MyMainWindows();                    //类构造函数(用于实现程序的主体部份)
  12.     public slots:                              //所有的槽函数都必须申明public slots语句内
  13.           void SlotTest();                    //这个槽函数用于显应点击按钮时改变文本框内容
  14.           void SlotTest2();                    //新增加槽函数,用于将文本框内容改为SigSig
  15.   private:
  16.         QPushButton * pb;                    //申请一个按钮QPushButton
  17.         QLineEdit * ledit;                      //申请一个文本框ledit
  18.         QLabel * label;                        //申请一个文本标签label
  19.      Signals:                                //所有信号都需要申明在signals语句内
  20.        void SigTest()                        //新增加信号SigTest()。
  21.     }; 
  22.     #endif /* YOURClASS_H_ */   

    在这个例子中,我们加入了自定义的信号SigTest()。在QT中信号的申请方法是,在类中加入signals(信号)语句。然后在语句后面定义自己的信号函数就可以了。有趣的是信号的定义并不需要具体实现,它就像一系列函数原型一样。你只需要申请就可以了。本例中,我们申请了一个不带有任何参数的信号SigTest()。在下文中我们将用这个信号来实现文本框内容变化。
    在窗体上要绘制文本标签,就必须加入<QLabel>头文件。其次我们在代码中新增加了一个槽SlotTest2()函数和一个信号SigTest()函数,并通过connect()函数连接。
    代码如下所示(yourclass.cpp):

复制代码

  1. #include "yourclass.h"
  2. MyMainWindows::MyMainWindows()
  3. {
  4.   setGeometry(90,90,300,200);
  5.   pb = new QPushButton("Modify",this);
  6.   pb->setGeometry(10,10,100,20);
  7.   ledit = new QLineEdit("what's your name",this);
  8.   ledit->setGeometry(10,30,200,150);
  9.   label = new QLabel("My MeMe",this);                //实现一个文本标签label,并将其内容初使为:My MeMe
  10.   label->setGeometry(115,10,100,20);
  11.   connect(pb,SIGNAL(clicked()),this,SLOT(SlotTest())); 
  12.   connect(this,SIGNAL(SigTest()),this,SLOT(SlotTest2())); //连接自定义信号SigTest  ()和SlotTest2()槽函数
  13. }
  14. void MyMainWindows::SlotTest()                      //信号1
  15. {
  16.   ledit->setText("jingjing");
  17.   label->setText("TTT");                          //将文本标签label内容设置为TTT文本
  18.   if(label->text() != "My MeMe")
  19.     {
  20.       emit SigTest();
  21.     }
  22. }
  23. void MyMainWindows::SlotTest2()              //信号2
  24. {
  25.   ledit->setText("SigSig");  //设置文本框内容为SigSig
  26. }

    从上面代码中可以看出,首先我们在MyMainWindows()主窗体类构造函数中加入了
      

复制代码

  1. label = new QLabel("My MeMe",this);             
  2.        label->setGeometry(115,10,100,20);

    Label文本标签的初使内容为My MeMe。其位置为窗体的(115,10),大小为(100,20),我们在上一事例中讲过的槽函数SlotTest()中新加入了对文本标签的检测,来达到对我们自定义信号SigTest()触发。如下所示:

复制代码

  1. void MyMainWindows::SlotTest()                      //信号1
  2. {
  3.   ledit->setText("jingjing");
  4.   label->setText("TTT");                          //将文本标签label内容设置为TTT文本
  5.   if(label->text() != "My MeMe")
  6.     {
  7.       emit SigTest();
  8.     }
  9. }
  10. void MyMainWindows::SlotTest2()              //信号2
  11. {
  12.   ledit->setText("SigSig");  //设置文本框内容为SigSig
  13. }

    如代码所示当SlotTest()槽函数被调用时,首先将ledit文本框内容设为jingjing,并把label文本标签内容设为TTT,然后此时我们检测label的内容是不是还为它的初使内容My MeMe,如果不是,则引发我们自定义的SigTest()信号。请注意代码中emit(发射)关键字,做为QT信号与槽机制来说,emit的作用就是将信号发出来的意思。也就是说,当我们类申明文件中定义了一个信号时,如果要使用这个信号,只需在信号语句前面加上emit关键字就可以了。
    而在SlotTest2()槽函数中,我们把文本框ledit的内容设为:SigSig。也就是当SlotTest2()槽函数被调用时就又会把ledit中内容修改为SigSig。在本事例中,我们用SigTest()信号来连接SlotTest2()这个槽,也就是说当SigTest()信号被触发时,就会将文本框的内容修改为:SigSig。代码如下:

复制代码

  1. connect(this,SIGNAL(SigTest()),this,SLOT(SlotTest2()));

    现在让我们把上例中的Main.cpp文件放到一起,进行编译
    当第一次点击[Modify]按钮时,程序首先产生一个信号clicked(),而这个信号将导致SlotTest()槽被执行,文本框的内容首先被修改为jingjing,然后label文本标签的内容被修改为TTT,随后在SlotTest()语句发现label的内容不是My MeMe,因此向外发射信号SigTest()。而SigTest()信号与SlotTest2()槽连接,因此导致SlotTest2()槽函数被调用,它又将文本框内容修改为了SigSig。因此当我们点击Modify时,文本框内容最终会变为SigSig文本。

时间: 2024-08-03 16:57:39

Qt 自定义信号与槽的相关文章

qt 信号与槽的发送和接收

问题描述 qt 信号与槽的发送和接收 . . . . 最后结果打印不出来... 解决方案 信号和槽函数做了绑定了吗? 解决方案二: 楼主你connect的是&t发送的fasong(QString)信号 而你代码里面是this->fasong(zhi); ps:这个t是啥.... 解决方案三: 关于Qt信号/槽的参数类型Qt之信号与槽关于Qt中信号槽机制

PyQt 5信号与槽的几种高级玩法

信号(Signal)和槽(Slot)是Qt中的核心机制,也是在PyQt编程中对象之间进行通信的机制.本文介绍了几种PyQt 5信号与槽的几级玩法. 在Qt中,每一个QObject对象和PyQt中所有继承自QWidget的控件(这些都是QObject的子对象)都支持信号与槽机制.当信号发射时,连接的槽函数将会自动执行.在PyQt 5中信号与槽通过object.signal.connect()方法连接. PyQt的窗口控件类中有很多内置信号,开发者也可以添加自定义信号.信号与槽具有如下特点. 一个信

qtcreator-qt中用信号和槽导致程序挂掉

问题描述 qt中用信号和槽导致程序挂掉 工具是qt creator,qt库版本为5.4,环境是windows 7,在我的程序中有一个信号的参数是(QSringdoubledoubledoubledouble)然后和在同一个类中的私有成员类的信号connect,最后这个私有成员类将此信号和这个私有成员类的私有成员类的槽函数connect,结果运行起来会让程序无缘无故挂掉.调试也发现不了原因,我在猜想是不是因为QString的原因,求有经验的大神赐教 解决方案 给程序的每一步都加个log看看是哪儿的

[Qt教程] 第44篇 进阶(四)信号和槽

[Qt教程] 第44篇 进阶(四)信号和槽 楼主  发表于 2013-9-12 16:48:59 | 查看: 298| 回复: 0 信号和槽 版权声明 该文章原创于Qter开源社区 导语 在前面的内容中已经多次用到过信号和槽了,这一节我们将详细讲解信号和槽的机制和使用方式.大家可以在帮助中查看Signals& Slots关键字. 环境:Windows Xp + Qt 4.8.5+QtCreator2.8.0 目录 一.信号和槽机制 二.信号和槽的自动关联 三.信号和槽的高级应用 正文 一.信号和

【C/C++学院】(13)QT开发技术/QT 基础/QT 信号和槽

Qt是一个跨平台的c++图形用户界面应用程序框架. Qt安装说明: windows下环境变量path需要加入以下路径,以便QT写的程序可以离开QT开发环境独立运行 C:\Qt\Qt5.2.0\5.2.0\mingw48_32\bin\;C:\Qt\Qt5.2.0\Tools\mingw48_32\bin; linux下需要设置.bash_profile文件 PATH中加入/opt/Qt5.2.0/5.2.0/gcc/bin 用root用户登录系统,进入/usr/lib目录后执行 ln libGL

qt c++-QT使用中关于布局与信号与槽的基础问题,求高手来看看

问题描述 QT使用中关于布局与信号与槽的基础问题,求高手来看看 1.假如在一个QDialog中左边是一个QTreeWidget右边添加一个Qwidget空间,QWidget里面放4个QLabel,用GridLayout布局平分,现在实现双击某一个label,其余3个label隐藏,而只有一个label出现并且填充满整个Qwidget,怎么实现这个过程? 2.在一个QT的button槽函数里,实现对视频文件回放:打开文件解码(解码产生一个getImage(QImage*)信号),然后由这个信号关联

6.QT信号和槽

 新建项目SignalAndSlot项目 编写代码如下: mysignal.h #ifndef MYSIGNAL_H #define MYSIGNAL_H   #include <QObject>   class MySignal : public QObject {     Q_OBJECT public:     explicit MySignal(QObject *parent = 0);   signals:     void sig();   public slots:   };

qt ui设计界面 创建信号与槽 原理,

在ui设计界面,设计信号和槽时,会把信息存在ui文件中,在编译时会在成成的头文件**.h 中把连接代码加上. ui界面添加信号和槽有两种方法 第一种: 在界面选择操作对象->右键->转到槽->选择信号->qtCreator 自动生成 槽方法->编写槽方法.此方法在ui文件中并不会保存响应信号与槽信息,因为它生成的槽格式固定,如on_countBtn_clicked.在编译时加入QMetaObject::connectSlotsByName(MainWindow);方法就可以自

在Qt Creator 和在 vs2012 里添加信号和槽

Qt  的窗口部件通过发射信号(signal)来表明一个用户的动作已经发生了或者是一个状态已经改变了. 如点击一个QPushButton时,按钮会发送一个clicked()信号,信号可以与函数(在qt里称做槽slot)相连接 可以把信号理解为c#里的事件 在vs2012里和在Qt Creator里添加信号和槽不一样,这里把两种环境下怎么添加详细说明一下   1.在vs2012里添加信号和槽 新建一个qt的项目QtDemo   在qtdeom.h里添加槽 private slots: void B