2013-10-02 4 views
1

Мне нужно создать 2 пользовательских события. Я следовал этой ссылке & сделал мой код: -
Is there a cleaner way to register Qt custom events?Создайте & опубликуйте настроенный Qevent

Является ли это правильный путь, чтобы создать & пост & передать некоторые данные (QString) к заказному событию?

================================================================================================================================== =============

Редактирование кода в соответствии с Kuba Ober sugession: ---

mainwindow.h: -

UpdateEvent *myUpdateEvent ; 
ClearEvent *myClearEvent ; 

Mainwindow.c: - -

MainWindow::MainWindow(QWidget *parent) : 
    QMainWindow(parent), 
    ui(new Ui::MainWindow) 
{ 
    ui->setupUi(this); 

    i =0; 
    myUpdateEvent = new UpdateEvent("hello"); 
    myClearEvent = new ClearEvent("bye"); 

    QCoreApplication::postEvent(this, myUpdateEvent); 
    QCoreApplication::postEvent(this, myClearEvent); 


} 

bool MainWindow::eventFilter(QObject *obj, QEvent *event) 
{ 

    qDebug() << "oo"; 
    if (UpdateEvent::is(event)) { 
     UpdateEvent *tempUpdateEvent = static_cast<UpdateEvent *>(event); 
     qDebug() << tempUpdateEvent->value(); 

    } 
    else if (ClearEvent::is(event)) { 
     ClearEvent *tempClearEvent = static_cast<ClearEvent *>(event); 
     qDebug() << tempClearEvent->value(); 

    } 

    return true; 

} 

event.h файл: -

template <typename T> class StringEvent : public QEvent 
{ 
    QString m_str; 
public: 
    explicit StringEvent(const QString val) : QEvent(staticType()), m_str(val) 
    { 
    } 

    QString setvalue(QString val) 
    { 
     m_str = val; 
    } 

    QString value() const 
    { 
     return m_str; 
    } 

    static QEvent::Type staticType() 
    { 
     static int type = QEvent::registerEventType(); 
     return static_cast<QEvent::Type>(type); 

    } 

    static bool is(const QEvent * ev) 
    { 
     return ev->type() == staticType(); 
    } 
}; 

class UpdateEvent : public StringEvent<UpdateEvent> 
{ 
public: 
    explicit UpdateEvent(QString val): StringEvent(val) 
    { 

    } 

}; 

class ClearEvent : public StringEvent<ClearEvent> 
{ 
public: 
    explicit ClearEvent(QString val): StringEvent(val) 
    { 

    } 
}; 

Почему eventFilter не срабатывает? И я не могу видеть сообщение отладки на postevent?

ответ

0

Я могу только прокомментировать запах кода реализации вашего события, так как на данный момент неясно, зачем вам отправлять события в элемент управления редактирования в окне. Последний плохой дизайн.

Ваш класс событий излишне усложнен. Вы должны настраивать все значения внутри события во время построения, и после этого они должны быть доступны через аксессоры только для чтения. Дополнительный тип события также кажется ненужным трюком.

Вот как я сделал бы это, используя метафорический шаблон (имя, которое я только что придумал, возможно, есть лучшее/существующее имя для него?). Это решает необходимость в явном производном конструктора классов, который в противном случае был бы необходим.

Я разделил метафабрикат на небольшие составляющие классы для удобства понимания.

// A type-identifier-generating wrapper for events 
template <typename D> class EventWrapper : public QEvent { 
public: 
    EventWrapper() : QEvent(staticType()) {} 
    static QEvent::Type staticType() { 
     static QEvent::Type type = static_cast<QEvent::Type>(registerEventType()); 
     return type; 
    } 
    static bool is(const QEvent * ev) { return ev->type() == staticType(); } 
    static D* cast(QEvent * ev) { return is(ev) ? static_cast<D*>(ev) : 0; } 
}; 

// The generic event metafactory for C++98 (doesn't need C++11) 
template <typename D, template <typename> class Carrier> class EventMF { 
    class EventFwd; 
    class Final; 
    class FinalWrapper : public EventWrapper<EventFwd>, public virtual Final {}; 
public: 
    // EventFwd is a class derived from Event. The EventWrapper's cast() 
    // will cast to a covariant return type - the derived class. That's OK. 
    typedef Carrier<FinalWrapper> Event; 
private: 
    class EventFwd : public Event {}; 
    class Final { 
     friend class FinalWrapper; 
     friend class Carrier<FinalWrapper>; 
    private: 
     Final() {} 
     Final(const Final &) {} 
    }; 
}; 

// A string carrier 
template <typename B> class StringData : public B { 
    QString m_str; 
public: 
    explicit StringData(const QString & str) : m_str(str) {} 
    QString value() const { return m_str; } 
}; 

// A string event metafactory 
template <typename D> class StringEventMF : public EventMF<D, StringData> {}; 

class Update : public EventMF<Update, StringData> {}; // using generic metafactory 
class Clear : public StringEventMF<Clear> {}; // using specific metafactory 
#if 0 
// This should fail at compile time as such derivation would produce classes with 
// duplicate event types. That's what the Final class was for in the matafactory. 
class Error : public Update::Event { Error() : Update::Event("") {} }; 
#endif 

int main(int, char**) 
{ 
    // Test that it works as expected. 
    Update::Event update("update"); 
    Clear::Event clear("clear"); 
    Q_ASSERT(Update::Event::staticType() != Clear::Event::staticType()); 
    Q_ASSERT(Update::Event::staticType() == Update::Event::cast(&update)->staticType()); 
    qDebug() << Update::Event::cast(&update)->value(); 
    Q_ASSERT(Update::Event::cast(&clear) == 0); 
    qDebug() << Clear::Event::cast(&clear)->value(); 
    Q_ASSERT(Clear::Event::cast(&update) == 0); 
} 

В Metafactory::Event классах в пользовательских классов событий, которые происходят от QEvent. Иерархия классов для обновления выглядит :: Event следующим образом (происходит от наименее полученных наиболее производного класса):

  • EventWrapper<EventMF<...>::EventFwd>, EventMF<...>::Final (множественное наследование)
  • EventMF<Update, StringData<Update>>::FinalWrapper
  • StringData<Update> = EventMF<Update, StringData<Update>>::Event

    с EventMF<...> является сокращением на EventMF<Update, StringData<Update>.

Линия Update::Event update("update") создает строковый несущий экземпляр события пользовательского с конструкторами вызывается из последнего к первому в приведенном выше списке.

С EventMF<...> - метафабрикат, который работает только во время компиляции, нет необходимости в том, чтобы его экземпляр существовал во время выполнения. Таким образом, конструктор EventMF<...>::EventMF никогда не вызывается. Вы можете применить этот инвариант, удалив конструктор (объявив его приватным для C++ 98).

Использование в качестве обработчика событий будет выглядеть следующим образом:

+0

спасибо .. узнал кесаревы концепции много ++ этой темы ... Последнее, что metafactory означает класс в классе? – Katoch

+0

@ Katoch: Метафакультет - это класс, который производит для вас другие классы. Здесь «Update» и «Clear» являются метафакторами, которые генерируют правильный вложенный класс «Event» для вас в каждой точке использования. Я [задал другой вопрос] (http://stackoverflow.com/q/19187469/1329652), чтобы получить отзывы сообщества о том, есть ли более простой способ сделать это. –

+0

Я предлагаю, чтобы наша работа также была выполнена без использования класса шаблонов ... потому что мы совсем не используем переменную шаблона T внутри нашего класса событий строки ... как показано в этом примере ... http: // www .cprogramming.com/tutorial/templates.html .... что вы скажете ...? – Katoch

Смежные вопросы