⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qt信号机制(全文) - 关注性能 - 飞翔,嵌入式linux.htm

📁 关于QT的国际化,帮助不同国家人员之间的交流
💻 HTM
📖 第 1 页 / 共 4 页
字号:
                              : "qt_invoke", membcode );<BR>/* 创建一个新的信号/反应槽连接 
                              */<BR>clist-&gt;append( c ); /* 信号源端加入这一对连接 
                              */<BR>if ( !r-&gt;senderObjects ) {<BR>/* 
                              类似于信号源端,反应槽端的连接列表也是动态创建的 */<BR>r-&gt;senderObjects 
                              = new 
                              QObjectList;<BR>}<BR>r-&gt;senderObjects-&gt;append( 
                              s ); /* 反应槽端加入这一对连接 
                              */<BR>}<BR>到此,信号与反应槽的连接已建立完毕,那么信号产生时又是如何触发反应槽的呢?从QObject的定义中可以看出其有多个activate_signal的成员函数,这些函数都是protected的,也即只有其自身或子类才可以使用。看一下它的实现:<BR>void 
                              QObject::activate_signal( QConnectionList *clist, 
                              QUObject *o )<BR>{<BR>if ( !clist ) /* 有效性检查 
                              */<BR>return;<BR>QObject *object;<BR>QConnection 
                              *c;<BR>if ( clist-&gt;count() == 1 ) {<BR>/* 
                              对某一个对象的一个具体信号来说,一般只有一种反应槽与之相连,这样事先判断一下可以加快处理速度 
                              */<BR>c = clist-&gt;first();<BR>object = 
                              c-&gt;object();<BR>sigSender = this;<BR>if ( 
                              c-&gt;memberType() == QSIGNAL_CODE 
                              )<BR>object-&gt;qt_emit( c-&gt;member(), o ); /* 
                              信号级连 */<BR>else<BR>object-&gt;qt_invoke( 
                              c-&gt;member(), o );/* 调用反应槽函数 */<BR>} else 
                              {<BR>QConnectionListIt it(*clist);<BR>while ( 
                              (c=it.current()) ) { /* 有多个连接时,逐一扫描 
                              */<BR>++it;<BR>object = 
                              c-&gt;object();<BR>sigSender = this;<BR>if ( 
                              c-&gt;memberType() == QSIGNAL_CODE 
                              )<BR>object-&gt;qt_emit( c-&gt;member(), o ); /* 
                              信号级连 */<BR>else<BR>object-&gt;qt_invoke( 
                              c-&gt;member(), o ); /* 调用反应槽函数 
                              */<BR>}<BR>}<BR>}<BR>至此我们已经可以基本了解Qt中信号/反应槽的流程。我们再看一下Qt为此而新增的语法:三个关键字:slots、signals和emit,三个宏:SLOT()、SIGNAL()和Q_OBJECT。在头文件qobjectdefs.h中,我们可以看到这些新增语法的定义如下:<BR>#define 
                              slots // slots: in class<BR>#define signals 
                              protected // signals: in class<BR>#define emit // 
                              emit signal<BR>#define SLOT(a) "1"#a<BR>#define 
                              SIGNAL(a) 
                              "2"#a<BR>由此可知其实三个关键字没有做什么事情,而SLOT()和SIGNAL()宏也只是在字符串前面简单地加上单个字符,以便<BR>程序仅从名称就可以分辨谁是信号、谁是反应槽。中间编译程序moc.exe则可以根据这些关键字和宏对相应的函数进行“翻译”,以便在C++编译器中编译。剩下一个宏Q_OBJECT比较复杂,它的定义如下:<BR>#define 
                              Q_OBJECT \<BR>publi \<BR>virtual QMetaObject 
                              *metaObject() const { \<BR>return 
                              staticMetaObject(); \<BR>}<BR>\<BR>virtual const 
                              char *className() const; \<BR>virtual void* 
                              qt_cast( const char* ); \<BR>virtual bool 
                              qt_invoke( int, QUObject* ); \<BR>virtual bool 
                              qt_emit( int, QUObject* ); 
                              \<BR>QT_PROP_FUNCTIONS<BR>\<BR>static QMetaObject* 
                              staticMetaObject(); \<BR>QObject* qObject() { 
                              return (QObject*)this; } 
                              \<BR>QT_TR_FUNCTIONS<BR>\<BR>private: \<BR>static 
                              QMetaObject 
                              *metaObj;<BR>从定义中可以看出该宏的作用有两个:一是对与自己相关的QMetaObject中间类操作进行声明,另一个是对信号的释放操作和反应槽的激活操作进行声明。当moc.exe对头文件进行预编译之后,将会产生一个可供C++编译器编译的源文件。以上述的Demo类为例,假设它的代码文件分别为d 
                              e m o . h和d e m o . c p p 
                              ,预编译后将产生<BR>moc_demo.cpp,其主要内容如下:<BR>QMetaObject 
                              *Demo::metaObj = 0;<BR>void 
                              Demo::initMetaObject()<BR>{<BR>if ( metaObj 
                              )<BR>return;<BR>if ( strcmp(QObject::className(), 
                              "QObject") != 0 
                              )<BR>badSuperclassWarning("Demo","QObject");<BR>(void) 
                              staticMetaObject();<BR>}<BR>QMetaObject* 
                              Demo::staticMetaObject()<BR>{<BR>if ( metaObj 
                              )<BR>return metaObj;<BR>(void) 
                              QObject::staticMetaObject();<BR>typedef 
                              void(Demo::*m1_t0)(int);<BR>m1_t0 v1_0 = 
                              Q_AMPERSAND Demo::setValue; /* 定位反应槽的入口 
                              */<BR>QMetaData *slot_tbl = 
                              QMetaObject::new_metadata(1);<BR>/* 新建一个反应槽数据 
                              */<BR>QMetaData::Access *slot_tbl_access = 
                              QMetaObject::new_metaaccess(1);<BR>slot_tbl[0].name 
                              = "setValue(int)"; /* 反应槽名称 */<BR>slot_tbl[0].ptr 
                              = *((QMember*)&amp;v1_0);<BR>/* 
                              通过反应槽名称可以找到反应槽的入口指针 */<BR>slot_tbl_access[0] = 
                              QMetaData::Public; /* 权限类型 */<BR>typedef 
                              void(Demo::*m2_t0)(int);<BR>m2_t0 v2_0 = 
                              Q_AMPERSAND Demo::valueChanged; /* 定位信号的入口 
                              */<BR>QMetaData *signal_tbl = 
                              QMetaObject::new_metadata(1); /* 新建信号数据 
                              */<BR>signal_tbl[0].name = "valueChanged(int)"; /* 
                              信号名称 */<BR>signal_tbl[0].ptr = 
                              *((QMember*)&amp;v2_0);<BR>/* 通过信号名称可以找到信号的入口指针 
                              */<BR>metaObj = QMetaObject::new_metaobject(<BR>/* 
                              创建一个与demo类相关的QMetaObject对象 */<BR>"Demo", 
                              "QObject",<BR>slot_tbl, 1,<BR>signal_tbl, 1,<BR>0, 
                              0 );<BR>metaObj-&gt;set_slot_access( 
                              slot_tbl_access ); /* 设置权限 */<BR>return 
                              metaObj;<BR>}<BR>// 有信号时即激活对应的反应槽或另一个信号<BR>void 
                              Demo::valueChanged( int t0 
                              )<BR>{<BR>activate_signal( "valueChanged(int)", t0 
                              );<BR>}<BR>该文件中既没有Qt特有的关键字,也没有特殊的宏定义,完全符合普通的C++语法,因此可以顺利编译和链接。<BR><BR></DIV></DIV></TD></TR></TBODY></TABLE>
                        <P style="MARGIN: 5px; LINE-HEIGHT: 150%"></P></TD></TR>
                    <TR>
                      <TD height=25>&nbsp;<FONT 
                        color=#000099><B>原文地址</B></FONT> <A 
                        href="http://www.qobject.com/simple/index.php?t1827.html" 
                        target=_blank>http://www.qobject.com/simple/index.php?t1827.html</A> 
                      </TD></TR>
                    <TR>
                      <TD align=middle height=25><FONT color=#295200>发表于: 
                        2007-08-14,修改于: 2007-08-14 16:19,已浏览178次,有评论0条</FONT> <A 
                        id=star title=推荐这篇文章 
                        onclick="NewWindows(this.href);return false;" 
                        href="http://blog.chinaunix.net/u2/star.php?blogid=30686&amp;artid=359959">推荐</A> 
                        <A id=complaint title=投诉这篇文章 
                        onclick="NewWindows(this.href);return false;" 
                        href="http://blog.chinaunix.net/u2/complaint.php?blogid=30686&amp;artid=359959">投诉</A> 
                      </TD></TR></TBODY></TABLE></TD></TR>
              <TR>
                <TD width=7 height=7><IMG alt="" 
                  src="QT信号机制(全文) - 关注性能 - 飞翔,嵌入式linux.files/w_left_buttom.gif" 
                  border=0></TD>
                <TD bgColor=#f3f3f3></TD>
                <TD width=7 height=7><IMG alt="" 
                  src="QT信号机制(全文) - 关注性能 - 飞翔,嵌入式linux.files/w_right_buttom.gif" 
                  border=0></TD></TR></TBODY></TABLE>
        <TR>
          <TD width=11 height=11><IMG alt="" 
            src="QT信号机制(全文) - 关注性能 - 飞翔,嵌入式linux.files/g_left_bottom.gif" 
            border=0></TD>
          <TD bgColor=#dddddd></TD>
          <TD width=11 height=11><IMG alt="" 
            src="QT信号机制(全文) - 关注性能 - 飞翔,嵌入式linux.files/g_right_bottom.gif" 
            border=0></TD></TR></TBODY></TABLE><BR><BR>
      <TABLE style="BORDER-COLLAPSE: collapse" cellSpacing=0 cellPadding=0 
      width="100%" border=0>
        <TBODY>
        <TR>
          <TD width=11 height=11><IMG alt="" 
            src="QT信号机制(全文) - 关注性能 - 飞翔,嵌入式linux.files/g_left_top.gif" 
          border=0></TD>
          <TD width="99%" bgColor=#dddddd height=11></TD>
          <TD width=11 height=11><IMG alt="" 
            src="QT信号机制(全文) - 关注性能 - 飞翔,嵌入式linux.files/g_right_top.gif" 
          border=0></TD></TR>
        <TR>
          <TD vAlign=top align=middle width="100%" bgColor=#dddddd 
            colSpan=3><B>网友评论</B> <BR>
            <TABLE style="BORDER-COLLAPSE: collapse" cellSpacing=0 cellPadding=0 
            width="96%" border=0>
              <TBODY>
              <TR>
                <TD width=7 height=7><IMG alt="" 
                  src="QT信号机制(全文) - 关注性能 - 飞翔,嵌入式linux.files/w_left_top.gif" 
                  border=0></TD>
                <TD width="100%" bgColor=#f3f3f3></TD>
                <TD width=7 height=7><IMG alt="" 
                  src="QT信号机制(全文) - 关注性能 - 飞翔,嵌入式linux.files/w_right_top.gif" 
                  border=0></TD></TR>
              <TR>
                <TD align=middle bgColor=#f3f3f3 colSpan=3>
                  <TABLE style="BORDER-COLLAPSE: collapse" cellSpacing=0 
                  cellPadding=0 width=700 align=center border=0>
                    <TBODY>
                    <TR>
                      <TD style="COLOR: #0000cc" height=25> 发表评论 </TD></TR>
                    <TR>
                      <TD height=25><IFRAME name=comment 
                        src="QT信号机制(全文) - 关注性能 - 飞翔,嵌入式linux.files/comment.htm" 
                        frameBorder=0 width=640 
                    height=160></IFRAME></TD></TR></TBODY></TABLE></TD></TR>
              <TR>
                <TD width=7 height=7><IMG alt="" 
                  src="QT信号机制(全文) - 关注性能 - 飞翔,嵌入式linux.files/w_left_buttom.gif" 
                  border=0></TD>
                <TD bgColor=#f3f3f3></TD>
                <TD width=7 height=7><IMG alt="" 
                  src="QT信号机制(全文) - 关注性能 - 飞翔,嵌入式linux.files/w_right_buttom.gif" 
                  border=0></TD></TR></TBODY></TABLE>
        <TR>
          <TD width=11 height=11><IMG alt="" 
            src="QT信号机制(全文) - 关注性能 - 飞翔,嵌入式linux.files/g_left_bottom.gif" 
            border=0></TD>
          <TD bgColor=#dddddd></TD>
          <TD width=11 height=11><IMG alt="" 
            src="QT信号机制(全文) - 关注性能 - 飞翔,嵌入式linux.files/g_right_bottom.gif" 
            border=0></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE>
<CENTER></CENTER></BODY></HTML>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -