我正在使用RtMidi库来处理我的 Qt 应用程序中的midi消息,我遇到了插槽触发器的问题:
我的 PhMidiInput 对象在特定midi消息时从 RtMidi 回调中发出信号,但并不总是触发插槽。
以下是 PhMidiInput 类的一部分:
class PhMidiInput : QObject
{
Q_OBJECT
public:
void PhMidiInput() {}
signals:
void quarterFrame(unsigned char data);
private:
static void callback(double, std::vector< unsigned char > *message, void *userData ) {
PhMidiInput *midiInput = (PhMidiInput*)userData;
if(midiInput)
midiInput->onMessage(message);
}
void onMessage(std::vector<unsigned char> *message) {
...
emit quarterFrame(data);
...
}
}
连接到lambda仿函数:
PhMidiInput midiIn;
int quarterFrameCount;
connect(&midiIn, &PhMidiInput::quarterFrame, [&](unsigned char data) {
quarterFrameCount++;
});
连接到我的应用程序窗口适用于:
// MyWindow inherits from QMainWindow
connect(_midiIn, &PhMidiInput::quarterFrame, this, &MyWindow::onQuarterFrame);
尝试连接到继承自 QObject 的自定义类( MidiTest )时,它不会触发:
connect(_midiIn, &PhMidiInput::quarterFrame, this, &MidiTest::onQuarterFrame);
我想知道QObject::moveToThread()周围是否有什么东西,但由于我自己不创建线程(信号是从回调发送的),我不知道是否需要使用它。< / p>
答案 0 :(得分:1)
就像从回调中调用emit obj->quarterFrame(data);
一样简单。如果连接类型是默认的,那么这将是完全线程安全的。
虽然您应该从QByteArray
创建data
以传递data
,但在广告时段被调用时可能无效。
void callback(..., void* user){
//user is the standard void* in most callbacks passed as reinterpret_cast<void*>(this)
unsigned char* data = ...;
QByteArray bytes(data);
emit reinterpret_cast<PhMidiInput>(user)->quarterFrame(bytes);//calling the signal which will behave as you'd expect
}
答案 1 :(得分:0)
在上次connect()
来电中,您传递了this
和MidiTest::onQuarterFrame
作为接收器对象和方法。我敢打赌this
不是MidiTest
的实例,是吗?
这里的问题是您从MidiTest
传递SLOT方法,而接收方对象是this
,而不是MidiTest
的实例。将接收方从this
更改为MidiTest
的某个实例。
我很惊讶这段代码在运行时不会使你的应用程序崩溃。