简化实现qt中的信号阻塞blockSignals

http://www.oschina.net/code/snippet_54100_1304
QT中经常会用到blockSignals, 且是成对出现,实现时常在函数的开始阻塞信号,在函数的结尾 释放信号。
若里面有大量需要阻塞的变量对象,这样写是件很麻烦的事,代码也比较多。
如果能实现象下面的方式实现,这样能简化很多,且不关心释放 问题.
下面的例子是关于slider与spinbox联动问题,若改slider影响spinbox,反之如此。
标签: 信号阻塞 blockSignals Qt

代码片段(2)[全屏查看所有代码]

1. [代码]cpp代码    跳至 [1] [2] [全屏预览]

view source print ?
01 void ImEffectWidget::slotSlider(int pos)
02 {
03  static int oldPos = 0;
04  if (oldPos != pos)
05  {
06   QRect r;
07   QObject *o = sender();
08 //
09   ImSignalBlock block;
10   block << m_ui.spinBoxTransparent << m_ui.spinBoxVerticalPos
11      << m_ui.spinBoxHerizontalPos << m_ui.spinBoxSTTransparent
12      << m_ui.spinBoxSTVPos;
13   int tabType = m_treeItem->mdata("effect_catalog").toInt();
14   if (tabType == TAB_CATALOG_WATERMARK ){
15    r = m_treeItem->getEffectItem("effect_item_rect").toRect();
16   }
17   
18   /* 3. for watermark  ***************************/
19   else if (o->objectName() == "sliderTransparent"){
20    m_ui.spinBoxTransparent->setValue(pos);  //与spinbox关联
21    m_treeItem->setEffectItem("effect_item_transparent", pos);
22   }else if (o->objectName() == "sliderVerticalPos"){
23    r.moveLeft(pos);
24    m_ui.spinBoxVerticalPos->setValue(pos);
25   }else if (o->objectName() == "sliderHorizontalPos"){
26    r.moveTop(pos);
27    m_ui.spinBoxHerizontalPos->setValue(pos);
28   }
29   /* 5. for subtitle  ***************************/
30   else if (o->objectName() == "sliderSTTransparent"){
31    m_ui.spinBoxSTTransparent->setValue(pos);
32    m_treeItem->setMediaData("effect_subtitle_transparent", pos);
33   }else if (o->objectName() == "sliderSTVPos"){
34    m_ui.spinBoxSTVPos->setValue(pos);
35    m_treeItem->setMediaData("effect_subtitle_pos", pos);
36   }
37   
38   if (tabType == TAB_CATALOG_WATERMARK ){
39    m_treeItem->setEffectItem("effect_item_rect", r);
40   }
41   sendEffectEvent();   //向sdl发信号
42   oldPos = pos;
43  }
44 }

2. [代码]ImSignalBlock.h    跳至 [1] [2] [全屏预览]

view source print ?
01 #ifndef IMSIGNALBLOCK_H_
02 #define IMSIGNALBLOCK_H_
03 #include <QObject>
04 class ImSignalBlock
05 {
06 public:
07  ImSignalBlock();
08  ~ImSignalBlock();
09   ImSignalBlock &operator<< (QObject *o);
10 private:
11  QList<QObject*> m_objs;
12 };
13 #endif
14 ImSignalBlock.cpp:
15 #include <QDebug>
16 #include "ImSignalBlock.h"
17 ImSignalBlock::ImSignalBlock()
18 {
19 }
20 ImSignalBlock::~ImSignalBlock()
21 {
22  foreach (QObject* o, m_objs)
23  {
24   if (o) o->blockSignals(false);
25  }
26 }
27 ImSignalBlock &ImSignalBlock::operator<< (QObject *o)
28 {
29  if (o)
30  {
31   m_objs.append(o);
32   qDebug() << o->objectName();
33   o->blockSignals(true);
34  }
35  return *this;
36 }


http://blog.csdn.net/koilin/article/details/7599223

我有两个QComboBox combo1, combo2:

[cpp] view plain copy print ?
  1. QComboBox *combo1 = new QComboBox;  
  2. QComboBox *combo2 = new QComboBox;  
  3. combo1->addItem("1-1");  
  4. combo1->addItem("1-2");  
  5. combo2->addItem("2-1");  
  6. combo2->addItem("2-2");  
  7. connect(combo1, SIGNAL(currentIndexChanged(int)), combo2, SLOT(process(int)));  
  8. connect(combo2, SIGNAL(currentIndexChanged(int)), combo1, SLOT(process(int)));  

然后是信号处理函数:

[cpp] view plain copy print ?
  1. void process(int index)  
  2. {  
  3.     QComboBox *combo1 = new QComboBox;  
  4.     QComboBox *combo2 = new QComboBox;  
  5.     if (sender() == combo1)  
  6.     {  
  7.         combo2->setCurrentIndex(index);  
  8.     }  
  9.     else if (sender() == combo2)  
  10.     {  
  11.         combo1->setCurrentIndex(index);  
  12.     }  
  13. }  

这样两个combobox之间就产生了死循环。因为不管是手动改变combobox的当前index还是使用函数来设置当前的index都会发出index改变的消息,此时就需要使用关闭信号:

[cpp] view plain copy print ?
  1. void process(int index)  
  2. {  
  3.     QComboBox *combo1 = new QComboBox;  
  4.     QComboBox *combo2 = new QComboBox;  
  5.     if (sender() == combo1)  
  6.     {  
  7.         combo2->blockSignals(true);  
  8.         combo2->setCurrentIndex(index);  
  9.         combo2->blockSignals(false);  
  10.     }  
  11.     else if (sender() == combo2)  
  12.     {  
  13.         combo1->blockSignals(true);  
  14.         combo1->setCurrentIndex(index);  
  15.         combo1->blockSignals(false);  
  16.     }  


你可能感兴趣的:(简化实现qt中的信号阻塞blockSignals)