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

QT中经常会用到blockSignals, 且是成对出现,实现时常在函数的开始阻塞信号,在函数的结尾释放信号。
若里面有大量需要阻塞的变量对象,这样写是件很麻烦的事,代码也比较多。
如果能实现象下面的方式实现,这样能简化很多,且不关心释放问题.

下面的例子是关于slider与spinbox联动问题,若改slider影响spinbox,反之如此。
实现效果可参考www.thinkvd.com中的视频编辑效果

样例代码:

void ImEffectWidget::slotSlider(int pos)
{
 static int oldPos = 0;
 if (oldPos != pos)
 {
  QRect r;
  QObject *o = sender();
//
  ImSignalBlock block;
  block << m_ui.spinBoxTransparent << m_ui.spinBoxVerticalPos
     << m_ui.spinBoxHerizontalPos << m_ui.spinBoxSTTransparent
     << m_ui.spinBoxSTVPos;

  int tabType = m_treeItem->mdata("effect_catalog").toInt();
  if (tabType == TAB_CATALOG_WATERMARK ){
   r = m_treeItem->getEffectItem("effect_item_rect").toRect();
  }
 
  /* 3. for watermark  ***************************/
  else if (o->objectName() == "sliderTransparent"){
   m_ui.spinBoxTransparent->setValue(pos);  //与spinbox关联
   m_treeItem->setEffectItem("effect_item_transparent", pos);
  }else if (o->objectName() == "sliderVerticalPos"){
   r.moveLeft(pos);
   m_ui.spinBoxVerticalPos->setValue(pos);
  }else if (o->objectName() == "sliderHorizontalPos"){
   r.moveTop(pos);
   m_ui.spinBoxHerizontalPos->setValue(pos);
  }
  /* 5. for subtitle  ***************************/
  else if (o->objectName() == "sliderSTTransparent"){
   m_ui.spinBoxSTTransparent->setValue(pos); 
   m_treeItem->setMediaData("effect_subtitle_transparent", pos);
  }else if (o->objectName() == "sliderSTVPos"){
   m_ui.spinBoxSTVPos->setValue(pos); 
   m_treeItem->setMediaData("effect_subtitle_pos", pos);
  }
  
  if (tabType == TAB_CATALOG_WATERMARK ){
   m_treeItem->setEffectItem("effect_item_rect", r);
  }
  sendEffectEvent();   //向sdl发信号
  oldPos = pos;
 }
}


现在看看ImSignalBlock类是如何实现的:
ImSignalBlock.h:
#ifndef IMSIGNALBLOCK_H_
#define IMSIGNALBLOCK_H_

#include <QObject>
class ImSignalBlock
{
public: 
 ImSignalBlock();
 ~ImSignalBlock();

  ImSignalBlock &operator<< (QObject *o);

private:
 QList<QObject*> m_objs;
};

#endif

ImSignalBlock.cpp:
#include <QDebug>
#include "ImSignalBlock.h"

ImSignalBlock::ImSignalBlock()
{
}

ImSignalBlock::~ImSignalBlock()

 foreach (QObject* o, m_objs)
 {
  if (o) o->blockSignals(false);
 }
}

ImSignalBlock &ImSignalBlock::operator<< (QObject *o)
{
 if (o)
 {
  m_objs.append(o);
  qDebug() << o->objectName();
  o->blockSignals(true);
 } 
 return *this;
}

利于ImSignalBlock可简化代码,以便今后维护. 有问题可到www.thinkvd.com给我留言.

你可能感兴趣的:(qt)