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给我留言.