Russian Qt Forum
Ноябрь 22, 2024, 22:42 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Как отправить наследника QEvent в несколько объектов в разных потоках?  (Прочитано 1899 раз)
Fregloin
Супер
******
Offline Offline

Сообщений: 1025


Просмотр профиля
« : Август 01, 2013, 10:21 »

Привет. Есть приложение, в котором множество объектов в разных потоках. Нужно что бы эти объекты могли общаться между собою.
Объекты связываются между собой по тегу, допустим простро строки. Нужно написать свой диспетчер событий, который будет заниматься перенаправлением QEvent из отправителя получателям ( от 1-го до N) в разных потоках. Связи кто кому отправляет задаются заранее, хотя должна быть возможность динамического связывания.
Раньше я слал конкретным потокам события через QCoreApplication::postEvent, но там была связь 1 к 1. В документации написано, что событие нужно создавать в куче, слать через postEvent, после чего очередь его сама удалит. Вопрос, а когда она удалит это событие? Когда его обработает первый приемник?

Вот мои наброски диспетчера

Рассматриваем CInterfaceTag как QString(хотя на самом деле это набор из нескольких строк).

Код:
#include <QObject>
#include <QHash>
#include "csharedobjectinterface.h"
#include "cxmldocumentiteminterface.h"
#include "ctaggedinterface.h"

class   CAbstractEvent;
class   CAbstractArmLogic;

class CEventProxy : public QObject, public CSharedObjectInterface, public CXMLDocumentItemInterface
{
Q_OBJECT

    QHash<CInterfaceTag, QObject*>              fsubscribedObjects; //подписчики на события
    QHash<CInterfaceTag, QList<CInterfaceTag> > freceivers;         //приемники

public:

    explicit    CEventProxy(QObject *parent = 0);

    void        subscribeObjectForEventReceiving(const CInterfaceTag & address, QObject * InterfaceObject);  //подписывает объект на приём событий
    void        unsubscribeObjectFromEventReceiving(const CInterfaceTag & address);   //отписывает объект по адерсу
    void        unsubscribeObjectFromEventReceiving(QObject *InterfaceObject);    //отписывает объект по интерфейсу

    void        loadFromDocument(QDomDocument &doc, QDomElement &node);
    void        saveToDocument(QDomDocument &doc, QDomElement &node);
    void        afterDocumentLoad();
    void        clearDocument();

    void        applyReceiversList(const QHash<CInterfaceTag, QList<CInterfaceTag> > & receivers);
    void        getReceiversList(QHash<CInterfaceTag, QList<CInterfaceTag> > & receivers);

    inline      QList<QObject*> subscribedObjects() { return    fsubscribedObjects.values();    }

public  slots:

    void        sendEvent(const CAbstractEvent & event);  //отправка события

};

Код:
#include <QCoreApplication>
#include "ceventproxy.h"
#include "cabstractevent.h"

CEventProxy::CEventProxy(QObject *parent) :
    QObject(parent),CSharedObjectInterface(),CXMLDocumentItemInterface()
{

}

void CEventProxy::sendEvent(const CAbstractEvent &event)
{
    QList<CInterfaceTag>    destinationTags = freceivers.value(event.eventTag());
    if(!destinationTags.isEmpty())
    {
        QObject                 *   interfaceObject;
        CAbstractEvent  *   eventPtr = new CAbstractEvent(QEvent::Type(ABSTRACT_EVENT_TYPE));
        *eventPtr = event;
        foreach (const CInterfaceTag & destinationTag, destinationTags)
        {
            if((interfaceObject=fsubscribedObjects.value(destinationTag,NULL)))
            {
                QCoreApplication::postEvent(interfaceObject,eventPtr);
            }
        }
    }
}

void CEventProxy::subscribeObjectForEventReceiving(const CInterfaceTag &address, QObject *InterfaceObject)
{
    if(!address.isValid() || !InterfaceObject)   return;
    fsubscribedObjects[address] = InterfaceObject;
}

void CEventProxy::unsubscribeObjectFromEventReceiving(const CInterfaceTag &address)
{
    fsubscribedObjects.remove(address);
}

void CEventProxy::unsubscribeObjectFromEventReceiving(QObject *InterfaceObject)
{
    for(QHash<CInterfaceTag, QObject*>::iterator it = fsubscribedObjects.begin(); it!= fsubscribedObjects.end(); it++)
    {
        if(it.value() == InterfaceObject)
        {
            unsubscribeObjectFromEventReceiving(it.key());
            break;
        }
    }
}

//остальное не интересно
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.045 секунд. Запросов: 22.