
ã¿ãªããããã«ã¡ã¯ã ãã®ããšã«ã€ããŠã話ããããšæããŸã...çŽ2é±éåãç§ã¯æåã«C ++ã§GUIãæäœããå¿ èŠããããå°ãGoogleãè©ŠããåŸãQtã䜿çšããããšã«ããŸããã 誰ãã圌ãã²ã©ãè³è³ããå®éãäžèŠãããšåœŒã¯éåžžã«ãµããããããã«èŠããŸããã
äžèŠãããšãããQtãè¯ãããšã§ãããããã®ã¡ãœãããªããžã§ã¯ãã³ã³ãã€ã©ã®å®è£ ã«ã¯ããã€ãã®å¶éããããããå°ããªæŸèæãèšèšããå¿ èŠããããŸããã ãã®ãšãã»ã€ã§ã¯ïŒããšãã»ã€ããšããèšèã¯ãããªã¥ãŒã ã®ããèšäºãåŒã£åŒµããªãã®ã§ãããé©ããŠãããšæããŸãïŒãçããåé¡ãã©ã®ããã«è§£æ±ºãããã«ã€ããŠã話ããããšæããŸãã
è¿œå ïŒèŠªåãªäººã ã®ã³ã¡ã³ãã«åºã¥ããŠãMOCãªãã§ãäžè¬çã«æŸèæãªãã§è¡ãæ¹æ³ã瀺ãç·šéãè¡ãããŸããã
ããããã¹ãŠå§ãŸã£ãæ¹æ³
ããã¯ãã¹ãŠãã©ã€ãã©ãªå ã®MVCã¢ãŒããã¯ãã£ã®å®è£ ã®äžéšãšããŠãã³ãã¬ãŒãã³ã³ãããŒã©ãŒã¯ã©ã¹ãäœæããå¿ èŠããããšããäºå®ããå§ãŸããŸããã ã³ã³ãããŒã©ãŒã¯ãç°çš®ã®æŽæ°ããŒã¿ãšå¯Ÿè©±ãã QSpinBoxãGUIãšããŠé¢é£ä»ããªããã°ãªããŸããã§ãã ã ãã¹ãŠã®æ®»ãç Žæ£ãããšã次ã®ãããªãã®ãåºãŠããŸããã
ãã³ãã¬ãŒãã³ã³ãããŒã©ãŒ
template< typename T_IntegralType > class IntegralController { private: T_IntegralType *_modelField; QSpinBox *_view; ... public: QSpinBox *getView() { if (!_view) { _view = new QSpinBox(); /* */ } return _view; } . . . private: // , void setValue(T_IntegralType inValue) { * modelField = inValue; } };
ã³ãŒããã¹ã±ããããåŸãQtã§ã®ã€ãã³ãåŠçã«ã€ããŠèªã¿ãäžè¬çãªã€ãã³ããç¹ã«GUIèŠçŽ ããã®ã€ãã³ããæäœããã«ã¯ã ä¿¡å·ãšã¹ãããã®ã·ã¹ãã ã䜿çšããå¿ èŠãããããšã«æ°ä»ããŸããïŒãã®ã·ã¹ãã ã¯ãã®èšäºã§ããå解ãããŠããŸã -ããã¯å ¬åŒããã¯ã®ç¿»èš³ã®ããã§ãïŒ ã
ã¢ãã«ãã¥ãŒã¢ãããŒãã«é¢ãã泚æ
ãŸããQtã®ã¢ãã«ãã¥ãŒã¢ãããŒãã®ãã¬ãŒã ã¯ãŒã¯ã«ã¯ããªã²ãŒãã·ã¹ãã ãªã©ããããã·ã°ãã«ã¹ãããã·ã¹ãã ã䜿çšããã«ãã€ã³ã¿ãŒãã§ã€ã¹ã®å®è£
ãéããŠãã¥ãŒãšã¢ãã«éã®ããŒã¿è»¢éãåŠçã§ããŸãã ç¹å®ã®çç±ã«ãããã©ã€ãã©ãªã§Qtã¢ãã«ãã¥ãŒãé©åã«äœ¿çšã§ããŸããã§ããã
ä»»æã®ã¯ã©ã¹ãã·ã°ãã«ã¹ãããã·ã¹ãã ã«ã¹ããããæäŸã§ããããã«ããã«ã¯ããã®ã¯ã©ã¹ãQObjectã¯ã©ã¹ãç¶æ¿ãã Q_OBJECTãã¯ããå«ããå¿ èŠããããŸããã ãªãã§ïŒ ããããç§ã¯ãããç解ããããã«ã¹ããŒã ãã¹ãåããªãã£ãã ããã¯å¿ èŠã§ã-ããã¯ãããå¿ èŠã§ãããšããããšã§ãã ããã«èŠåŽããã«ã圌ã¯å¿ èŠãªãã®ããã³ãã¬ãŒãã¯ã©ã¹ã«è¿œå ããGUIã€ãã³ãåŠçã®å®è£ ã«ã€ããŠèª¬æããŸããã
ã€ãã³ãé§ååãã³ãã¬ãŒãã³ã³ãããŒã©ãŒ
template< typename T_IntegralType > class IntegralController : public QObject { Q_OBJECT private: T_IntegralType *_modelField; QSpinBox *_view; ... public: QSpinBox *getView() { if (!_view) { _view = new QSpinBox(); QObject::connect(_view, SIGNAL(valueChanged(int)), this, SLOT(valueChanged(int)); } } . . . private slots: void valueChanged(int inValue) { *_modelField = inValue; } };
ãã¹ãŠãéãŸã£ãã ãŸããç§ã¯ãªããŠçŽ æŽããã仲éã ãšæã£ããã ïŒ -ãããŠããã°ããã®éããã®ãã³ãã¬ãŒãã³ã³ãããŒã©ãå¿ããŠãã©ã€ãã©ãªãèŠç¶ããŸããã ãã¡ããã圌ã¯ãããåŸæã§ã¯ãªãã£ãã®ã§ãç¡é§ã«æ¥ãã§ãäžè¬çã«æ©ãåã³ãŸããã ãã³ãã¬ãŒãã³ã³ãããŒã©ãŒã®ç¹æ®åã䜿çšããã³ãŒããã³ã³ãã€ã«ããããšãããšããã«ããªã³ã«ãŒãšã©ãŒã¡ãã»ãŒãžã次ã®ããã«éã£ãŠããŸããã
ãªã³ã¯ãšã©ãŒ
æªè§£æ±ºã®å€éšã·ã³ãã«ãpublicïŒvirtual struct QMetaObject const * __cdecl TClass <int> :: metaObjectïŒvoidïŒconstãïŒïŒmetaObject @ïŒ$ TClass @ H @@ UEBAPEBUQMetaObject @@ XZïŒ æªè§£æ±ºã®å€éšã·ã³ãã«ãpublicïŒvirtual void * __cdecl TClass <int> :: qt_metacastïŒchar const *ïŒãïŒïŒqt_metacast @ïŒ$ TClass @ H @@ UEAAPEAXPEBD @ ZïŒ æªè§£æ±ºã®å€éšã·ã³ãã«ãpublicïŒvirtual int __cdecl TClass <int> :: qt_metacallïŒenum QMetaObject :: Callãintãvoid * *ïŒãïŒïŒqt_metacall @ïŒ$ TClass @ H @@ UEAAHW4Call @ QMetaObject @@ HPEAPEAX @ ZïŒ
ã¡ã¿ãªããžã§ã¯ãã·ã¹ãã ã§äœãééã£ãããšãããŠããã®ã¯æããã§ããã MOCã«ã€ããŠèªã¿çŽããªããã°ãªããŸããã§ããã ãœãŒã¹ã³ãŒããééãããšãã«ãMOCã¯è¿œå ã®cppãã¡ã€ã«ãçæããäœæãããã·ã¹ãã ã®ã¡ã¿ãªããžã§ã¯ãã«å¿ èŠãªã¡ãœããã®å®è£ ãäœæãããããšãå€æããŸããã ãã®ã·ã¹ãã ã¯ãã³ãã¬ãŒããéåžžã«æ²ããããã£ãŠåäœãããã®éåžžã«ã¡ã¿ãªããžã§ã¯ãã®ã³ãŒãã貧匱ã«çæããŸã-MOCã¯ã³ãŒããçæãããšãã«ãã³ãã¬ãŒãã¯ã©ã¹ãåã«ç¡èŠããããéåžžã®ã¯ã©ã¹ãšããŠèªèãããã³ãã¬ãŒãåŒæ°ãç Žæ£ããŸãã
ãã³ãã¬ãŒããšQtã®è©³çŽ°
ã·ã°ãã«ã¹ãããã·ã¹ãã ã§ãã³ãã¬ãŒãã䜿çšããªãçç±ã«ã€ããŠã¯ãããã¯ã«å¥ã®èšäºããããŸãã æ®å¿µãªãããç§ã®å Žåãããã¯æé©æ§ã«é¢ãããã®ã§ã¯ãªããã³ãŒãã®éãé©åã«åæžãã倧éã®ã³ããŒã¢ã³ãããŒã¹ããåé¿ããããšã«é¢ãããã®ã§ããããããã£ãŠããã®èšäºã®ãã€ã³ãã¯é©åã§ã¯ãããŸããã§ããã
MOCã«ããã«æ £ãããšãMOCãå¶åŸ¡ããã¯ã©ã¹ã®äœ¿çšã«ã¯ããã«ããã€ãã®å¶éããããŸããã æãäžæå¿«ãªã®ã¯ããã¹ããããã¯ã©ã¹ã§QObjectã®å®å šã«ç®¡çãããMOCã®åå«ãèšè¿°ã§ããªãããšã§ãã ãããŠãç§ã¯ãã¹ããããã¯ã©ã¹ãäœãããã®äžã«äœãã§ããå°ããªå€å žã®éã®å€§ããªã¯ã©ã¹ã®è²¬ä»»ã®é åãå£ããŸãã ã¯ããç§ã¯ç¥ã£ãŠããŸããåŽåããã°ã©ããŒã¯åå空éã䜿çšããŸãããåæã«ãç§ã®æèŠã§ã¯ãããã°ã©ã ã®ã³ã³ããã¹ãã¯ä¹±éã§ããããã¹ããããã¯ã©ã¹ã®ã»ãã³ãã£ã¯ã¹ã¯åå空éã®ã»ãã³ãã£ã¯ã¹ãšã¯ç°ãªããŸãïŒæåã®ã±ãŒã¹ã§ã¯ãã¯ã©ã¹éã®é¢ä¿ã®éå±€ãæ§ç¯ããŸããäœãïŒã
äžè¬çã«ãMOCã·ã¹ãã ããã¯éçQObject :: connectïŒ...ïŒã¡ãœãããä»ããŠã€ãã³ãããµãã¹ã¯ã©ã€ãããæ©èœã®ã¿ãå¿ èŠã§ãããããå°ããªæŸèæãäœæããããšã«ããŸãã...éåžžã«å°ããªãå°ããªæŸèæã
泚ïŒå€æããããã«ãKostylikã¯ãæ²ãã£ãMOCãæ¯é ãã5çªç®ãããæ°ããQtã®ããŒãžã§ã³çšã§ããããšãå€æããŸããã Qt 5ããŒãžã§ã³ã«ã¯ããã®MOCãªãã§ä¿¡å·ã¹ããããèš±å¯ããã¯ãŒã«ãªAPIããããŸãã ãã®æ å ±ãèšäºã®æåŸã«è¿œå ããŸãã ã ç¹°ãè¿ãã«ãªããŸãããé埳ã¯ç§ã«ãšã£ãŠã¯ãèšäºã®æ authorãªèè ã§ããããŸã£ããããŸããã£ãŠããŸãããGoogleã7åãèšäºãäžåºŠæžããŠãã ãã ã
æŸèæã«ã€ããŠ
ã¢ã€ãã¢ã¯ã·ã³ãã«ã§ãããQObjectãç¶æ¿ããä¿¡å·ã¹ãããã·ã¹ãã å ã§ã®æ£ããåäœã®ããã«ã¯ã©ã¹ãç»é²ãããšããæå³ã§ãMOCã«å®å šã«é©ããããã¯ã©ã¹ãäœæããããšã§ãã ãã®ããã¯ã©ã¹ã¯ãQtã«äŸåããªãã³ãŒã«ããã¯ããã®è£å©ã¯ã©ã¹ã®ã¹ãããåŒã³åºãã«é¢é£ä»ããããã®ã¡ãœãããæäŸããŸãã
è€éã«èãããŸãããäŸãããæ確ã«ãªããšæããŸãã QSpinBoxããã®ã€ãã³ããåŠçããã³ãŒãã§ã¯ã次ã®ããã«ãªããŸããã
QSpinBoxããã®ã€ãã³ãã®Kostylik
FastDelegateå šè¬ã«ã€ããŠ
GitHubã®FastDelegate
class ValueChangedWorkaround : public QObject { Q_OBJECT public: // -, . // FastDelegate ( , ) typedef fastdelegate::FastDelegate1 < int > Callback; private: Callback _callback; public: ValueChangedWorkaround() : _callback() { } void bind(QSpinBox *inSpinBox, const Callback &inCallback) { _callback = inCallback; QObject::connect(inSpinBox, SIGNAL(valueChanged(int)), this, SLOT(valueChanged(int)); } private slots: void valueChanged(int inValue) { _callback(inValue); } };
FastDelegateå šè¬ã«ã€ããŠ
GitHubã®FastDelegate
ç§ã¯ãã®ã³ãŒããã³ã³ãããŒã©ãŒã§äœ¿çšããŸãã-ãããŠããã¯æ©èœããŸããïŒ
æŸèæã³ã³ãããŒã©ãŒ
template< typename T_IntegralType > class IntegralController { private: typedef IntegralController< IntegralType > OwnType; T_IntegralType *_modelField; QSpinBox *_view; ValueChangedWorkaround _valueChangedWorkaround; ... public: QSpinBox *getView() { if (!_view) { _view = new QSpinBox(); _valueChangedWorkaround.bind(_view, ValueChangedWorkaround::Callback( &OwnType::valueChanged)); } } . . . private: void valueChanged(int inValue) { *_modelField = inValue; } };
ããã¯èœã¡çãããã«æããŸã...ããããç§ã¯æ®éçãªãœãªã¥ãŒã·ã§ã³ã®ç çåŠçãªãã¡ã³ãªã®ã§ãç£æ¥èŠæš¡ã§Qtãªããžã§ã¯ãããã®ããŸããŸãªã€ãã³ããåŠçããæŸèæãäœæã§ãããã¯ããäœæããããšã«ããŸããã

æŸèæãžã§ãã¬ãŒã¿ãŒ
å€ããã¯ãã«åºã¥ããŠæ°ãããã¯ããäœæããåã«ããã€ãã®èå¥åããã¯ãåŒæ°ã«çœ®ãæãããã¯ãèªäœããããã«äžè¬åããããšãã§ããããã«æãããŸãã
æŸèæãçæãããã¯ãã ããŒãžã§ã³1.0
ããã§ã¯ã¹ã©ãã·ã¥ãçç¥ããŸãïŒã\ããªã©ïŒ-æ¿æããŸãïŒ
define QT_EVENT_WORKAROUND_1_ARG(M_WorkaroundName, M_EventName, M_Arg0Type) class M_WorkaroundName : public QObject { Q_OBJECT public: typedef fastdelegate::FastDelegate1 < M_Arg0Type > Callback; private: Callback _callback; public: M_WorkaroundName() : _callback() { } void bind(QObject *inQSignalSource, const Callback &inCallback) { _callback = inCallback; QObject::connect(inQSignalSource, SIGNAL(M_EventName(M_Arg0Type)), this, SLOT(M_EventName(M_Arg0Type)); } private slots: void M_EventName(M_Arg0Type inValue) { _callback(inValue); } };
ãã®ãã¯ããæžããã®ã§ãç§ã¯èªä¿¡ãæã£ãŠãä»ã¯ç¢ºãã«ããã§ããŠããŠãäžè¬çã«æŸèæã®é äž»ïŒäžèšã®ç·ã®ãããªïŒã§ãããšæããŸããã éåžžã«åãã§ãç§ã¯ã³ãŒããå®è¡ããŸãã...ã¯ãããã¡ãããäœãæ©èœããŸããã§ããã ã³ã³ãã€ã«ãšã©ãŒã¯ãªãããã¹ãŠãåéãããŸããããã³ãŒã«ããã¯ã¯åŒã³åºããããã¡ãã»ãŒãžããã°ã«éä¿¡ãããŸãããããšãã°ã TestWorkaroundã¯ã©ã¹ã«å¿ èŠãªã¹ãããããããŸããã
ããã«æãäžããªããã°ãªããŸããã§ããã Qtã®MOCã¯ãã¯ããå±éããæ¹æ³ãç¥ããªãããšãå€æããŸããã ããªããã»ããµãå®è¡ãããåã«ã³ãŒããééããŸãïŒã€ãŸããMinGWã§-Eãã©ã°ã䜿çšããŠãã«ãããå Žåã«è¡šç€ºãããã³ãŒãã§ã¯ãªããåŠçãããŠããªãã³ãŒãã«ãã£ãŠå®è¡ãããŸãïŒã
äžæ¹ãMOCã¯ããã¹ãããããšããåèªã®åŸã«ã¯ã©ã¹ã®å®£èšãããã¯ã«ããã¡ãœããã·ã°ããã£ãç¥ã£ãŠããå¿ èŠããããŸã-æååãšããŠèªã¿åãã QObject :: connectãåŒã³åºããšãã«ãããã®æåååã䜿çšããŸãïŒSLOTããã³SIGNALãã¯ãããããã®åå+䜿çšå ŽæïŒã ãããã£ãŠãæŸèæãçæãããã¯ããŠãŒã¶ãŒã¯ãã¹ãããã®ç¬èªã®å®è£ ãèšè¿°ããå¿ èŠãããããšãæããã«ãªããŸããã
ç§ã¯ãã®ã³ãŒãã®éãšè€éããæå°éã«æããããšããŸããããæçµçãªè§£æ±ºçã¯æ¬¡ã®ããã«ãªããŸãïŒãã§ã«æçµçãªã³ãŒãã§ãããäžæ¬ãªã¹ã©ãã·ã¥ãå«ãŸããŠããŸãïŒã
#define SIGNAL_WORKAROUND_1_ARG(M_WorkaroundName, M_CallName, M_Arg0Type)\ class M_WorkaroundName : public QObject {\ public:\ typedef fastdelegate::FastDelegate1< M_Arg0Type > Delegate;\ \ private:\ Delegate _delegate;\ \ public:\ void bind(QObject *inQSignalSource, const Delegate &inDelegate) {\ _delegate = inDelegate;\ QObject::connect(inQSignalSource, SIGNAL(M_CallName(M_Arg0Type)),\ this, SLOT(M_CallName(M_Arg0Type)));\ }\ \ void CALL(M_Arg0Type inArgument) { _delegate(inArgument); }\
-ã芧ã®ãšããããã¯ãã¯ã¯ã©ã¹ãå®å
šã«ã¯èšè¿°ããŠããŸããããŠãŒã¶ãŒã¯ãCALLïŒ...ïŒã¡ãœãããåŒã³åºãããã®ã¹ãããã®èšè¿°ãå®äºããå¿
èŠããããŸãã 以äžã®æŸèæãžã§ãã¬ãŒã¿ãŒã®äœ¿çšã«é¢ããå®å
šãªèª¬æ...
å®å šãªèª¬æïŒ
1.ãã¯ãã䜿çšããŠã©ããã«æŸèæã¯ã©ã¹ãçæããŸãã ãã®äŸã§ã¯ã YourWorkaroundNameãšåŒã°ããæŸèæãçæããŸããããã¯ãã¿ã€ãEventArg1Typeã® 1ã€ã®åŒæ°ãåãqtEventNameã€ãã³ããã©ããããŸãã ã¯ã©ã¹ãçæããã³ãŒãïŒ
SIGNAL_WORKAROUND_1_ARG(YourWorkaroundName, qtEventName, EventArg1Type) Q_OBJECT private slots: void qtEventName(EventArg1Type a0) { CALL(a0); } };
2.ã©ãããããã¿ã€ãã®ã€ãã³ããéä¿¡ã§ããQtãªããžã§ã¯ãããã®ã€ãã³ããåŠçããå¿ èŠãããã³ãŒãã®ä»»æã®å Žæã§æ°ããã¿ã€ãã䜿çšããŸãïŒãã®äŸã§ã¯ãã¿ã€ãEventArg1Typeã® 1ã€ã®åŒæ°ãéä¿¡ããqtEventNameã€ãã³ãïŒã æŸèæã䜿çšããã³ãŒãäŸïŒ
class UserClass { private: QSomeObject *_qTestObject; YourWorkaroundName _workaround; public: UsingClass() : _qTestObject(new QSomeObject()) { _workaround.bind(_qTestObject, YourWorkaroundName::Callback(&UsingClass:: onEvent)); } void onEvent(EventArg1Type inArg) { /* Some actions on callback */ } }
ãã¹ãŠæºåå®äºã§ãã ããã§ãQt MOCã«ããå¶éãªãã«ãä»»æã®ã¯ã©ã¹ã®Qtãªããžã§ã¯ãããã®ã¡ãã»ãŒãžãåŠçã§ããŸãã
çµè«ãšããŠãããã€ãã®ã³ã¡ã³ãïŒ
1.ææ¡ããããã¯ãã¯ãåäžã®å ¥ååŒæ°ãåãã€ãã³ãã«é©ããŠããŸãã ç°ãªãæ°ã®åŒæ°ãåŠçããã«ã¯ããã®ãã¯ãïŒå€ãã¹ã¿ã€ã«ã®ã¹ã¿ã€ã«ïŒãã³ããŒããŠè²Œãä»ããããC ++ 11ã®å¯å€é·ãã¯ãã䜿çšããŸã ã
2.ææ¡ããããœãªã¥ãŒã·ã§ã³ã¯ã FastDelegateã©ã€ãã©ãªã䜿çšããŠã³ãŒã«ããã¯ãåŠçããŸãã ãã¡ã³ã¯ã¿ãŒã䜿çšããå Žåã¯ããã¯ãå ã®FastDelefateãã䜿çšã®ã¿ã€ãã«ç°¡åã«çœ®ãæããããšãã§ããŸãã
3.ãã®ãœãªã¥ãŒã·ã§ã³ã§ã¯ããšã©ãŒåŠçãã¢ãµãŒã·ã§ã³ãªã©ã¯ãããŸãããç§ã®å Žåããã®ãããªåŠçã¯å¿ èŠãããŸããã å³ã«è¿œå ã§ããŸãã
4.ææ¡ããããœãªã¥ãŒã·ã§ã³ãå°çã®ãããªãã®ã§ããããšã«åæããæºåãã§ããŠãããQt MOCã®å¶éã«å¯ŸåŠããä»ã®æ¹æ³ã«ã€ããŠã®ææ¡ãåãã§èããŸãã ç§ã¯ããªãã®ææ¡ãèšäºã«è¿œå ãã決å®ã®åäœè ã瀺ããç§èªèº«ããæè¬ã®æãè¡šããŸãã äºåã«æè¬ããŸãïŒ
ãããã«
ææ¡ãããæŸèæãžã§ãã¬ãŒã¿ãŒãã誰ããåæ§ã®ã·ãŒããæžãæéãç¯çŽããã®ã«åœ¹ç«ã€ããšãé¡ã£ãŠããŸãã æåŸã«ãæŸèæãžã§ãã¬ãŒã¿ãŒã«ã¯å°éã®ã³ãŒããå«ãŸããŠãããããGitHubã«æçš¿ããããšã¯æå³ããããŸããã
ããããç±ç·ãã倧è¡ã®èŠè«ã§ãç§ã¯è©Šä¹ããŠå°ããªã«ããäœãããšãã§ããŸãã 5人以äžãåžæããå Žåã¯ãã³ã¡ã³ãã§ã³ã¡ã³ãããŠãã ãããæçš¿ããŸãã
èªãã§ãããŠããããšãã
PSïŒèšäºã§ãšã©ãŒãèŠã€ããå Žå-æžããŠãç·šéããŸãã
ïŒ2016幎3æ11æ¥ã«æçš¿ïŒ
AlexPublicãšVioletGiraffeã«æè¬ããŸã ãæ°ããAPIä¿¡å·ã¹ãããã«éŒ»ãçªã£èŸŒã¿ãŸããã
æŸèæãžã§ãã¬ãŒã¿ãŒã«ã€ããŠè©±ããšã次ã®ããã«ãªããŸãã
æŸèæãžã§ãã¬ãŒã¿ãŒ
䜿ãããããªããŸããã ããã§ããã³ãã¬ãŒãã³ã³ããã¹ããå«ããã©ãã§ãã©ãããŒã¿ã€ããäœæã§ããŸãã ãã®ãããªãã®ïŒ
#define SIGNAL_WORKAROUND_1ARG(M_WorkaroundName, M_CallName, M_Arg0Type)\ class M_WorkaroundName : public QObject {\ public:\ typedef fastdelegate::FastDelegate1< M_Arg0Type > Delegate;\ \ private:\ Delegate _delegate;\ \ public:\ template< typename T_ListenerType >\ void bind(T_ListenerType *inQSignalSource, const Delegate &inDelegate) {\ _delegate = inDelegate;\ connect(inQSignalSource,\ static_cast< void (T_ListenerType::*)(M_Arg0Type) > &T_ListenerType::M_CallName),\ this, &M_WorkaroundName::M_CallName);\ }\ \ void M_CallName(M_Arg0Type a0) { _delegate(a0); }\ };
䜿ãããããªããŸããã ããã§ããã³ãã¬ãŒãã³ã³ããã¹ããå«ããã©ãã§ãã©ãããŒã¿ã€ããäœæã§ããŸãã ãã®ãããªãã®ïŒ
template<typename T_SomeQObject> class UserClass { private: SIGNAL_WORKAROUND_1ARG(YourWorkaroundName, qtEventName, EventArg1Type); T_SomeQObject *_qTestObject; YourWorkaroundName _workaround; public: UsingClass() : _qTestObject(new T_SomeQObject()) { _workaround.bind(_qTestObject, YourWorkaroundName::Callback(&UsingClass::onEvent)); } void onEvent(EventArg1Type inArg) { /* Some actions on callback */ } }
ãã ãããã®æ°ããQt5 APIã·ã°ãã«ã¹ãããã䜿çšãããšãMOCãšãã®å¶éãå®å šã«åãé€ãããšãã§ããŸãã ãããã£ãŠãæŸèæã䜿çšãã代ããã«ãQObjectãããªã¹ããŒã¯ã©ã¹ãç¶æ¿ããã®ãç°¡åã§ãïŒMOCãžã®ãã€ã³ãããªããªãããããªã¹ããŒã®çžç¶äººã¯å®åå¥ãªã©ã«ãªãå¯èœæ§ããããŸãïŒã AlexPublicã§ææ¡ãããŠããããã«ãC ++ 11以åã䜿çšããã©ã ãã䜿çšãã å Žå ã