我正在开发一个包含几个类的图像编辑软件。但我需要我的代码更通用。但是当谈到连接时,我的课程遇到了很大的问题。
QObject::connect(actionSmartContrast, SIGNAL(triggered(bool)), effectsWindow, SLOT(addSmartContrast()));
QObject::connect(actionSaturation, SIGNAL(triggered(bool)), effectsWindow, SLOT(addSaturation()));
我有一个名为“效果”的菜单,当用户点击QAction
actionSmartContrast
时,效果智能对比度会添加到我的效果窗口。问题是,鉴于每个效果都有自己的类,我必须为每个类创建一个函数,如上面的代码所示。这是非常重复的。我想通过这样的事情来避免这个问题:
QObject::connect(actionSmartContrast, SIGNAL(triggered(bool)), effectsWindow, SLOT(addEffect(new SmartContrast())));
QObject::connect(actionSaturation, SIGNAL(triggered(bool)), effectsWindow, SLOT(addEffect(new Saturation())));
对于函数addEffect()
,一切都会好的,因为它需要一个指向Effect对象的指针,而SmartContrast和Saturation都从Effect继承。唯一的问题是不可能像这样传递connect()
中的变量。所以我想到了继承QAction
并创建一个信号,它会每次都返回我喜欢的类,但是又如何告诉我的新Action类它应该返回什么类?如果我有一千个效果,我将不会将QAction
子类化为一千次!我需要创建一个函数,该函数将采用例如指向SmartContrast
对象的指针,并且每次单击Action时它都会猜测它必须返回SmartContrast
指针。由于类Effect
的继承,这仍然是可能的。但我真的无法弄清楚如何做到这一点。任何帮助将非常感激。提前谢谢!
答案 0 :(得分:1)
看起来QSignalMapper正是您正在寻找的。 p>
更新:
另一种方法是使用lambda(如果Qt版本和c ++编译器允许):
QObject::connect(actionSmartContrast, &QAction::triggered, [effectsWindow](){ effectsWindow->addEffect(new SmartContrast()) });
答案 1 :(得分:0)
有几种选择。
如果足以拥有效果的基类指针,因为你使用例如解决方案后面的虚拟方法应该这样做:
您可以创建一个中间人类:
class Intermediate : public QObject
{
Q_OBJECT
public:
Intermediate(QObject* parent = 0) : QObject(parent){}
signals:
void triggerEffect(Effect*);
public slots:
void effectTriggered()
{
QAction* action = qobject_cast<QAction*>(QObject::sender());
if ( action ) {
std::map<QAction*,Effect*>::iterator it = m_mapping.find(action);
if ( it != m_mapping.end() )
{ emit triggerEffect( it->second ); }
}
}
public:
void registerActionEffectPair(QAction* action,Effect* effect)
{ m_mapping[action]=effect; }
private:
std::map<QAction*,Effect*> m_mapping;
};
要将Effect基类用作信号和插槽的类型,必须将其注册为元类型:
qRegisterMetaType<Effect*>();
连接它:
QObject::connect(intermediateInstancePtr, SIGNAL(triggerEffect(Effect*),
effectsWindow, SLOT(addEffect(Effect*)));
每个动作的联系如下:
intermediateInstancePtr->registerActionEffectPair( yourEffectAction, theEffectPtr );
QObject::connect(yourEffectAction, SIGNAL(triggered(bool)),
intermediateInstancePtr, SLOT(effectTriggered()));
另一种可能是使用QObjects属性:
setProperty( "property", "value" )
为每个效果QAction调用此方法并读取插槽“addEffect”中的属性。 可以通过调用
来读取该属性QAction* action = qobject_cast<QAction*>(QObject::sender());
if ( action ){
QVariant val = action->property("property");
if ( val.isValid() )
{
//TODO
}
}
因为Object :: sender返回负责插槽调用的发送方。
之后你可以做一个切换案例或类似的东西来区分不同的效果。
答案 2 :(得分:0)
我终于解决了我的问题!我将QAction子类化并向我的新类添加了一个信号,它根据属性text()从我想要的类创建一个新的效果。如果块足够简单。谢谢大家的答案!