Qt元对象系统:使用带有名称的字符串发出信号

Scu*_*der 1 c++ qt qt-signals qmetaobject

Qt信号/插槽系统摇摇欲坠,但看起来它缺少一些真正有用的功能(或者至少我找不到如何使用它)。我有一个带有很多信号的类,而这个类的类switch需要根据变量的值发出适当的信号。现在,我使用C预处理器解决此问题:

#define CASE(_NAME) \    
case MyEnum_ ## _NAME: \
{ \
    emit MySignal_ ## _NAME(); \
    do_other_stuff(); \
    break; \
}

switch(val)
{
CASE(Val_1)
CASE(Val_2)
CASE(Val_3)
}
Run Code Online (Sandbox Code Playgroud)

这看起来不正确。我敢肯定有一种更优雅的方法。QMetaObject有一种indexOfSignal方法,可以使用带有名称的字符串为我提供信号的Qt内部ID。如果我可以使用该ID发出信号,我的代码将变得更加清晰。

我已经窥视了由生成的信号方法实现moc,看起来唯一一个与另一个信号不同的是一位数字:

void *_a[] = { 0, const_cast<void*>(reinterpret_cast<const void*>(&_t1)) };
QMetaObject::activate(this, &staticMetaObject, <signal_id>, _a);
Run Code Online (Sandbox Code Playgroud)

其中<signal_id>,每个信号的唯一整数。

所以,问题是,我该怎么办emit(int signalIdx)?还是至少有机会致电QMetaObject::activate,因为它看上去埋在专用标头中?

fbu*_*cek 5

使用 QMetaObject :: invokeMethod

我在程序中使用这个:

mCaller是具有定义的插槽的对象,并且mSlotName是插槽的名称

QMetaObject::invokeMethod(mCaller, mSlotName.toLatin1().constData(), Qt::DirectConnection)
Run Code Online (Sandbox Code Playgroud)