How to map Qt Signal to Event in Managed C++ (C++/

2020-02-09 06:09发布

问题:

I'm writing a wrapper in .NET (C++/CLI) to be able to use some native C++ Qt code in .NET. How can I map a Qt signal into a managed .NET event, so that when my Qt code fires off a signal, I can bring this forward to the .NET code.

My Managed class defines the event, but if I try to use the normal QObject::connect method to hook up to the signal, it requires a QObject * receiver... I guess I have to do some magic marshalling of some sorts?

回答1:

Define normal unmanaged Qt event handler. From this handler, raise managed event.

Edit: if you have previous experience in Qt, you know how to handle Qt signals in unmanaged class. Don't try to make this class managed. Instead of this, write C++/CLI wrapper which contains this QObject-derived class.

Edit 2. Create C++/CLI Console application, call it test1, and add the following code to it:

test1.cpp:

#include "stdafx.h"
#include "ManagedClass.h"

using namespace System;

int main(array ^args)
{
    ManagedClass^ c = gcnew ManagedClass();
    c->Test();

    return 0;
}

ManagedClass.h:

#pragma once

class UnmanagedClass;

// Wrapper
ref class ManagedClass
{
public:
    ManagedClass(void);
    ~ManagedClass();
    !ManagedClass();
    void Test();
    void Callback();

private:
    UnmanagedClass* m_pUnmanagedClass;
};

ManagedClass.cpp:

#include "StdAfx.h"
#include "ManagedClass.h"
#include "UnmanagedClass.h"

ManagedClass::ManagedClass(void)
{
    m_pUnmanagedClass = new UnmanagedClass(this);
}

ManagedClass::~ManagedClass()
{
    this->!ManagedClass();
    GC::SuppressFinalize(this);
}

ManagedClass::!ManagedClass()
{
    if ( m_pUnmanagedClass )
    {
        delete m_pUnmanagedClass;
        m_pUnmanagedClass = NULL;
    }
}


void ManagedClass::Test()
{
    m_pUnmanagedClass->Test();
}

void ManagedClass::Callback()
{
    Console::WriteLine(L"This text is printed from managed wrapper function, called from unmanaged class.");
    Console::WriteLine(L"Here you can raise managed event for .NET client.");
    Console::WriteLine(L"Let's say that UnmanagedClass is QObject-derived, and this funcstion");
    Console::WriteLine(L"is called from UnmanagedClass Qt event handler - this is what you need.");
}

UnmanagedClass.h:

#pragma once

#include 
using namespace System;


ref class ManagedClass;

// Wrapped native class
class UnmanagedClass
{
public:
    UnmanagedClass(ManagedClass^ pWrapper);
    ~UnmanagedClass(void);
    void Test();

private:
    gcroot m_pWrapper;
};

UnmanagedClass.cpp:

#include "StdAfx.h"
#include "UnmanagedClass.h"
#include "ManagedClass.h"

UnmanagedClass::UnmanagedClass(ManagedClass^ pWrapper)
{
    m_pWrapper = pWrapper;
}

UnmanagedClass::~UnmanagedClass(void)
{
}

void UnmanagedClass::Test()
{
    m_pWrapper->Callback();
}

This gives you idea how unmanaged class and managed wrapper can play together. If you know Qt programming and know how to raise .NET event from ref C++/CLI class, this is enough to accomplish your task.