首页 文章

从回调中发出信号

提问于
浏览
2

我正在使用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()周围是否有什么东西,但是因为我不知道我是否需要使用它 .

2 回答

  • 0

    它就像从回调中调用 emit obj->quarterFrame(data); 一样简单 . 如果连接类型是默认值,那么这将是完全线程安全的 .

    虽然您应该从 data 创建一个 QByteArray 来传递,因为 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

    在最后一次 connect() 调用中,您将 thisMidiTest::onQuarterFrame 作为接收器对象和方法传递 . 我打赌 this 不是 MidiTest 的实例,是吗?

    这里的问题是你从 MidiTest 传递SLOT方法,而接收者对象是 this ,这不是 MidiTest 的实例 . 将接收器从 this 更改为 MidiTest 的某个实例 .

    我很惊讶这段代码在运行时不会崩溃你的应用程序 .

相关问题