How to wrap protected virtual methods
Hi, again... I finally managed to wrap public virtual functions correctly. Everything is fine and I eliminated all of the "segfaults" caused by bad chosen return value policies. But I have another challenge: wrapping protected virtual methods. I know that virtual methods cannot be called outside the class. They might be visible only by its class scope and its derived classes. But imagine now (thinking hybrid) that you may want to derive this C++ class (with a protected method) in Python. Then, it should be something like this: ======= C++ ========= class QWidget: { ... protected: void mouseEvent(QEvent* event) { ... } }; ====== Python ====== class MyWidget(QWidget): def __init__(self, ...): QWidget(self, ...) def mouseEvent(self, event): # ... do something QWidget.mouseEvent(self, event) # call the default after or: def mouseEvent(self, event): QWidget.mouseEvent(self, event) # call the default before # ... do something or worse: def mouseEvent(self, event): # ... do something # do not call the default I tried the same approach we discussed today on this list. But it didnt worked, because the compiler complainted when I tried to pass a pointer of a protected method. So, is there any way to do this, as naturally as possible? I though 2 solutions for this problem: 1 - One is wrapping the "default_mouseEvent" on the wrapped class with a different name. I think it should work, but the user must know that he should call a different name for the same function. It may confuse the user. 2 - The other way is a "hack". I can create a static semaphor inside the method, so I realise if it is the first (or not) time it is being called. If it is called the first time, I try to call the Python overriden version. If it is called twice or more, I call the default implementation. This way, the user can use the same function for different behaviors. The second approach seems to be dangerous. I am afraid of loosing the semaphor control (eg: if an exception is thrown). Well, is there a more simple and secure way of doing this? Thanks, [Eric Jardim] P.S. Sorry for bothering you all with so many questions in just a single day
Hi, everyone... I think I solved this "problem". Actually, I think that there is no problem. I worked so much last night that I couldn't see the simple solution. class QWidget_Wrapper: QWidget, wrapper<QWidget> { void mousePressEvent(QMouseEvent* p0) { if (override mousePressEvent = this->get_override("mousePressEvent")) { mousePressEvent( ptr( p0 ) ); } else { QWidget::mousePressEvent(p0); } } void default_mousePressEvent(QMouseEvent* p0) { QWidget::mousePressEvent(p0); } ... }; // and do .def("mousePressEvent", &QWidget::mousePressEvent, &QWidget_Wrapper::default_mousePressEvent) // instead of .def("mousePressEvent", &QWidget_Wrapper::default_mousePressEvent) So, solved another issue. But I think this should be noticed on some place of the docs or the tutorial itself. [Eric Jardim]
Eric Jardim <ericjardim@gmail.com> writes:
// and do .def("mousePressEvent", &QWidget::mousePressEvent, &QWidget_Wrapper::default_mousePressEvent)
// instead of .def("mousePressEvent", &QWidget_Wrapper::default_mousePressEvent)
So, solved another issue. But I think this should be noticed on some place of the docs or the tutorial itself.
I honestly don't think this is a problem that anyone else has. It probably doesn't make sense to document mistakes like passing the wrong arguments to a function until it becomes a common occurrence. After all, there are so many functions other than "def" that you could make that mistake with! -- Dave Abrahams Boost Consulting www.boost-consulting.com
participants (2)
-
David Abrahams -
Eric Jardim