QT 的信号与槽机制介绍(4)

2 .信号与槽机制与普通函数的调用一样,如果使用不当的话,在程序执行时也有可能产生死循环。因此,在定义槽函数时一定要注意避免间接形成无限循环,即在槽中再次发射所接收到的同样信号。例如 , 在前面给出的例子中如果在 mySlot() 槽函数中加上语句 emit mySignal() 即可形成死循环。

3 .如果一个信号与多个槽相联系的话,那么,当这个信号被发射时,与之相关的槽被激活的顺序将是随机的。

4. 宏定义不能用在 signal 和 slot 的参数中。

既然 moc 工具不扩展 #define,因此,在 signals 和 slots 中携带参数的宏就不能正确地工作,如果不带参数是可以的。例如,下面的例子中将带有参数的宏 SIGNEDNESS(a) 作为信号的参数是不合语法的:

#ifdef ultrix
    #define SIGNEDNESS(a) unsigned a
    #else
    #define SIGNEDNESS(a) a
    #endif
    class Whatever : public QObject
    {
    [...]
    signals:
        void someSignal( SIGNEDNESS(a) );
    [...]
    };
 


5. 构造函数不能用在 signals 或者 slots 声明区域内。

的确,将一个构造函数放在 signals 或者 slots 区内有点不可理解,无论如何,不能将它们放在 private slots、protected slots 或者 public slots 区内。下面的用法是不合语法要求的:

class SomeClass : public QObject
    {
        Q_OBJECT
    public slots:
        SomeClass( QObject *parent, const char *name )
            : QObject( parent, name ) {}  // 在槽声明区内声明构造函数不合语法
    [...]
    };
 


6. 函数指针不能作为信号或槽的参数。

例如,下面的例子中将 void (*applyFunction)(QList*, void*) 作为参数是不合语法的:

class someClass : public QObject
    {
        Q_OBJECT
    [...]
    public slots:
        void apply(void (*applyFunction)(QList*, void*), char*); // 不合语法
    };
 


你可以采用下面的方法绕过这个限制:

typedef void (*ApplyFunctionType)(QList*, void*);
    class someClass : public QObject
    {
        Q_OBJECT
    [...]
    public slots:
        void apply( ApplyFunctionType, char *);
    };
 


7. 信号与槽不能有缺省参数。

既然 signal->slot 绑定是发生在运行时刻,那么,从概念上讲使用缺省参数是困难的。下面的用法是不合理的:

class SomeClass : public QObject
    {
        Q_OBJECT
    public slots:
        void someSlot(int x=100); // 将 x 的缺省值定义成 100,在槽函数声明中使用是错误的
    };
 


8. 信号与槽也不能携带模板类参数。

如果将信号、槽声明为模板类参数的话,即使 moc 工具不报告错误,也不可能得到预期的结果。 例如,下面的例子中当信号发射时,槽函数不会被正确调用:

[...]
  public slots:
      void MyWidget::setLocation (pair<int,int> location);
  [...]
  public signals:
      void MyObject::moved (pair<int,int> location);
 


但是,你可以使用 typedef 语句来绕过这个限制。如下所示:

typedef pair<int,int> IntPair;
  [...]
  public slots:
      void MyWidget::setLocation (IntPair location);
  [...]
  public signals:
      void MyObject::moved (IntPair location);
 


这样使用的话,你就可以得到正确的结果。

9. 嵌套的类不能位于信号或槽区域内,也不能有信号或者槽。

例如,下面的例子中,在 class B 中声明槽 b() 是不合语法的,在信号区内声明槽 b() 也是不合语法的。

class A
    {
        Q_OBJECT
    public:
        class B
    {
        public slots:  // 在嵌套类中声明槽不合语法
            void b();
        [....]
        };
    signals:
        class B
    {
        // 在信号区内声明嵌套类不合语法
        void b();
        [....]
        }:
    };
 


10. 友元声明不能位于信号或者槽声明区内。

相反,它们应该在普通 C++ 的 private、protected 或者 public 区内进行声明。下面的例子是不合语法规范的:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/7aac900bd6608b6bcc93cff550dc1e56.html