2010-02-11 10 views
16

मैंने QEvent को उप-वर्गीकरण करके अपने क्यूटी एप्लिकेशन में एक कस्टम ईवेंट बनाया है।क्यूटी: एक कस्टम इवेंट प्रकार को परिभाषित करना

class MyEvent : public QEvent 
{ 
    public: 
    MyEvent() : QEvent((QEvent::Type)2000)) {} 
    ~MyEvent(){} 
} 

आदेश इस ईवेंट की जांच करने के लिए, मैं एक घटना() विधि में निम्न कोड का उपयोग करें:

if (event->type() == (QEvent::Type)2000) 
{ 
    ... 
} 

मैं अपने आवेदन में कहीं कस्टम घटना के प्रकार परिभाषित करने में सक्षम होना चाहते हैं ताकि मुझे अपने ईवेंट विधियों में वास्तविक पूर्णांक डालने की आवश्यकता न हो। तो मेरी घटना() पद्धतियों में मैं कैसे और कहाँ कोड में मैं यह कर सकता है

if (event->type() == MyEventType) 
{ 
    ... 
} 

किसी भी विचार की तरह कुछ करने में सक्षम होना चाहते हैं?

+4

जादू निरंतर '2000' के बजाय, आप' QEvent :: उपयोगकर्ता' का उपयोग कर सकते हैं। –

+2

@ टॉनवेंडेनहेवेल: +1। इसके अलावा। "उपयोग कर सकते हैं" के बजाय, मैं कहूंगा ** ** का उपयोग करना चाहिए **। ;) – Macke

उत्तर

15

घटना प्रकार अपने विशिष्ट वर्ग की पहचान करता है, मैं इसे वहाँ डाल चाहते हैं:

class MyEvent : public QEvent { 
public: 
    static const QEvent::Type myType = static_cast<QEvent::Type>(2000); 
    // ... 
}; 

// usage: 
if(evt->type() == MyEvent::myType) { 
    // ... 
} 
+0

इससे बहुत मदद मिली, धन्यवाद! हालांकि मैं पूरी तरह से समझ नहीं पा रहा हूं कि आपने संशोधन क्यों किया है। – Chris

+1

यदि कक्षा परिभाषा में प्रारंभ किया गया है, तो इसका उपयोग अभिन्न निरंतर अभिव्यक्तियों में किया जा सकता है जैसे 'केस'' में 'केस' कथन' या सरणी सीमाओं के साथ। –

13

सुविधा के लिए आप रजिस्टर और एक कस्टम घटना आरक्षण QEvent :: registerEventType() स्थिर समारोह का उपयोग कर सकते अपने आवेदन के लिए टाइप करें। ऐसा करने से आप अपने आवेदन में कहीं और इस्तेमाल होने वाले कस्टम इवेंट प्रकार को गलती से दोबारा उपयोग करने से बच सकते हैं।

उदाहरण:

class QCustomEvent : public QEvent 
{ 
public: 
    QCustomEvent() : QEvent(QCustomEvent::type()) 
    {} 

    virtual ~QCustomEvent() 
    {} 

    static QEvent::Type type() 
    { 
     if (customEventType == QEvent::None) 
     { 
      int generatedType = QEvent::registerEventType() 
      customEventType = static_cast<QEvent::Type>(generatedType); 
     } 
     return customEventType; 
    } 

private: 
    static QEvent::Type customEventType; 
}; 

QEvent::Type QCustomEvent::customEventType = QEvent::None; 
+6

यह एक अच्छा प्रस्ताव है, लेकिन आप QEvent :: कोई भी भाग छोड़ सकते हैं: const QEvent :: Type CustomEvent :: EventType = static_cast (QEvent :: registerEventType()); – gaspard

+1

और अपने उदाहरण का नामकरण QCustomEvent बहुत चालाक नहीं है: यह एक क्यूटी 3 वर्ग का नाम है। – gaspard

+0

इसके अलावा, आपको एक सदस्य चर की आवश्यकता नहीं है। बस एक स्थिर स्थानीय का उपयोग करें। –

4

इस तरह की समस्याओं से निपटने का मुहावरेदार भी तरह से, एक टेम्पलेट आवरण वर्ग बनाने के लिए CRTP लाभ है। प्रत्येक कस्टम इवेंट प्रकार के लिए, इस तरह का टेम्पलेट एक नए प्रकार का प्रतिनिधित्व करता है, इस प्रकार एक अलग staticType() सदस्य प्रत्येक प्रकार के लिए मौजूद है, जो इसके अद्वितीय पंजीकृत प्रकार को लौटाता है।

नीचे मैं की पहचान प्रकार के तीन तरीके दे:

  1. staticType() तक - यह केवल उपयोगी भीतर आवेदन की एक मंगलाचरण है, और प्रकार QEvent साथ प्रयोग किया जा रहा है। मान को किसी एप्लिकेशन के आमंत्रण के बीच रहने की गारंटी नहीं है। वे एक लॉग इन की तरह टिकाऊ स्टोरेज में हैं।

  2. localDurableType() द्वारा - वे invocations और उसी कंपाइलर के साथ recompilations के बीच जारी रहेगा। जटिल घटनाओं को परिभाषित करते समय यह durableType() विधि की मैन्युअल परिभाषा बचाता है।

  3. durableType() द्वारा - वे वास्तव में क्रॉस प्लेटफॉर्म हैं और जब तक आप अपने कोड के भीतर ईवेंट क्लास नाम बदल नहीं लेते तब तक वही रहेगा। यदि आप NEW_QEVENT मैक्रो का उपयोग नहीं कर रहे हैं तो आपको durableType() मैन्युअल रूप से परिभाषित करना होगा।

दोनों localDurableType() और durableType()qHash में परिवर्तन की वजह से क्यूटी 4 और 5 betwen भिन्न होते हैं।

आप दो तरीकों में से किसी में शीर्ष लेख का उपयोग:

#include "EventWrapper.h" 

class MyComplexEvent : public EventWrapper<MyComplexEvent> { 
    // An event with custom data members 
    static int durableType() { return qHash("MyEvent"); } 
    ... 
}; 

NEW_QEVENT(MySimpleEvent) // A simple event carrying no data but its type. 

EventWrapper।एच

#ifndef EVENTWRAPPER_H 
#define EVENTWRAPPER_H 

#include <QEvent> 
#include <QHash> 

template <typename T> class EventWrapper : public QEvent { 
public: 
    EventWrapper() : QEvent(staticType())) {} 
    static QEvent::Type staticType() { 
     static int type = QEvent::registerEventType(); 
     return static_cast<QEvent::Type>(type); 
    } 
    static int localDurableType() { 
     static int type = qHash(typeid(T).name()); 
     return type; 
    } 
}; 

#define NEW_QEVENT(Name) \ 
    class Name : public EventWrapper<Name> \ 
    { static int durableType() { \ 
     static int durable = qHash(#Name); return durable; \ 
    } }; 

#endif // EVENTWRAPPER_H 
+0

मुझे यहां सीआरटीपी का उपयोग पसंद है, लेकिन मुझे आश्चर्य है कि आप कैसे सुनिश्चित होंगे कि 'qHash' का उपयोग करने वाले वेरिएंट मौजूदा ईवेंट प्रकारों से टकराव नहीं करते हैं? – Kamajii

+0

आप सामान्य रूप से सुनिश्चित नहीं हो सकते हैं, लेकिन आप किसी भी विशिष्ट कार्यक्रम के लिए सुनिश्चित हो सकते हैं। आप टकराव के लिए स्थाई जांच कर सकते हैं और "हां, टकराव हैं" या "नहीं, कोई टक्कर नहीं है" उत्तर प्राप्त करें। इसलिए, कभी-कभी तथ्य यह है कि सामान्य रूप से जानने का कोई तरीका नहीं है, यह विशिष्ट परिस्थितियों में इसे जानने से रोकता नहीं है। –

+0

लेकिन क्या यह एक बहुत ही महत्वपूर्ण बात नहीं है जिसका आपके उत्तर में उल्लेख किया जाना चाहिए? अंत में आप अपने कोड में टकराव के खिलाफ कोई प्रावधान शामिल नहीं करते हैं। – Kamajii

संबंधित मुद्दे