• 7902阅读
  • 3回复

简化实现qt中的信号阻塞blockSignals [复制链接]

上一主题 下一主题
离线notton
 

只看楼主 倒序阅读 楼主  发表于: 2010-10-31
— 本帖被 XChinux 执行加亮操作(2010-10-31) —
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给我留言.

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/notton/archive/2010/10/30/5975872.aspx
c++ dev
离线dbzhang800

只看该作者 1楼 发表于: 2010-10-31
恩,不错
离线paranoid
只看该作者 2楼 发表于: 2010-10-31
一个建议:如果要提供给别人使用的话,应该考虑不同的使用情况,增强代码的健壮性,比如m_objs内QObject的生命周期
离线notton

只看该作者 3楼 发表于: 2010-11-01
m_objs内QObject的生命周期是与此类没有直接联系,此类仅对signal block起作用,
若在此类作用期间,m_objs内QObject的对象被free了,个人觉得是调用者来处理这种情况比较合适
c++ dev
快速回复
限100 字节
 
上一个 下一个