[Kde-bindings] Qt bindings to D programming language.

Arno Rehn arno at arnorehn.de
Tue Oct 28 15:40:12 UTC 2008


Hi,

there's now an example on techbase: 
http://techbase.kde.org/Development/Languages/Smoke
You'll need SmokeQt from the kdebindings module. If you didn't install it in 
the same prefix as KDE4 or don't have KDE4 at all, you'll also need to adjust 
the CMakeLists.txt file to point to the correct paths.

On Monday 27 October 2008 17:55:57 Arno Rehn wrote:
> On Monday 27 October 2008 00:34:57 Eldar Insafutdinov wrote:
> > Yeah, I also thought about inheritance. But I can't understand one. For
> > example I subclass a QWidget in my C++ part of wrapper:
> >
> > class QWidget_Proxy: public QWidget
> > {
> >    Q_OBJECT
> >    public:
> >       QWidget_Proxy(QWidget* parent = 0);
> >
> >       void ancestor_mousePressEvent(QMouseEvent* qme);
> >       virtual void mousePressEvent(QMouseEvent* qme);
> > }
> >
> > void QWidget_Proxy::QWidget_Proxy(QWidget* parent)
> > {
> >
> > }
> >
> > //default implementation
> > void QWidget_Proxy::ancestor_mousePressEvent(QMouseEvent* qme)
> > {
> >    QWidget::mousePressEvent(qme);
> > }
> >
> > void QWidget_Proxy::mousePressEvent(QMouseEvent* qme)
> > {
> >    Dispatch_QWidget_MousePressEvent(this, qme);
> > }
> >
> >
> >
> > extern "C" void QWidget_mousePressEvent(Qwidget* qwidget, QMouseEvent
> > qme) {
> >      qwidget.ancestor_mousePressEvent(QMouseEvent* qme)
> > }
> >
> >
> > And my D wrapper
> > class QWidget : QObject
> > {
> >
> >
> >
> > private void* qwidgetPtr;
> >
> >      //constructor of D class
> >      this()
> >      {
> >           qwidgetPtr = QWidget_new();
> >      }
> >
> >      static extern (C) void Dispatch_QWidget_MousePressEvent(void*
> > classPtr, QMouseEvent *qme);
> >      {
> >           classPtr.mousePressEvent(qme);
> >      }
> >
> >      void mousePressEvent(QMouseEvent qme)
> >      {
> >           QWidget_mousePressEvent(this.qwidgetPtr,qme)
> >      }
> > }
> >
> > Okey and I have the QPushButton which inherirts from QWidget (not
> > directly but it doesn't matter). C++ wrapper:
> >
> > extern "C" void* QPushButton_new()
> > {
> >     return new QPushButton_proxy();
> > }
> >
> > D wrapper:
> > class QPushButton : QWidget
> > {
> >
> >
> >
> > private void* qpushbuttonPtr;
> >
> >      //constructor of D class
> >      this()
> >      {
> >           qpushbuttonPtr = QPushButton_new();
> >      }
> > }
> >
> > This is not 100% accurate - but the rough idea is that QPushButton_proxy
> > is inherited from QPushButton and QPushButton in its turn is inherited
> > from QWidget, not from QWidget_proxy. so when we create an instance of
> > QPushButton - all this virtual functions will not be implemented, because
> > they are implemented only in QWidget_proxy - and nothing is derived from
> > this class.
>
> Yes, correct. That's the reason we override all the virtual methods, even
> the inherited ones, in every wrapped class again. This might not be the
> ideal solution, but it's the easiest to use.
> Here is an excerpt from the smoke class that wraps QPushButton:
>
> class x_QPushButton : public QPushButton {
>     SmokeBinding* _binding;
> public:
>     void x_0(Smoke::Stack x) {
> 	// set the smoke binding
> 	_binding = (SmokeBinding*)x[1].s_class;
>     }
>     void x_1(Smoke::Stack x) const {
> 	// metaObject()
> 	const QMetaObject* xret = this->QPushButton::metaObject();
> 	x[0].s_class = (void*)xret;
>     }
>     void x_2(Smoke::Stack x) {
> 	// qt_metacall(QMetaObject::Call, int, void**)
> 	int xret = this->QPushButton::qt_metacall((QMetaObject::Call)x[1].s_enum,
> (int)x[2].s_int,(void**)x[3].s_voidp);
> 	x[0].s_int = xret;
>     }
>
>     [... some more x_* wrapper calls...]
>
>     virtual int metric(QPaintDevice::PaintDeviceMetric x1) const {
> 	Smoke::StackItem x[2];
> 	x[1].s_enum = x1;
> 	if(this->_binding->callMethod(18763, (void*)this, x)) return
> (int)x[0].s_int; return this->QWidget::metric(x1);
>     }
>     virtual QSize minimumSizeHint() const {
> 	Smoke::StackItem x[1];
> 	if(this->_binding->callMethod(12261, (void*)this, x)) {
> 	    QSize *xptr = (QSize *)x[0].s_class;
> 	    QSize xret(*xptr);
> 	    delete xptr;
> 	    return xret;
> 	}
> 	return this->QPushButton::minimumSizeHint();
>     }
>     virtual void mouseDoubleClickEvent(QMouseEvent* x1) {
> 	Smoke::StackItem x[2];
> 	x[1].s_class = (void*)x1;
> 	if(this->_binding->callMethod(18741, (void*)this, x)) return;
> 	this->QWidget::mouseDoubleClickEvent(x1);
>     }
>     virtual void mouseMoveEvent(QMouseEvent* x1) {
> 	Smoke::StackItem x[2];
> 	x[1].s_class = (void*)x1;
> 	if(this->_binding->callMethod(48, (void*)this, x)) return;
> 	this->QAbstractButton::mouseMoveEvent(x1);
>     }
>
>     [...a lot more overridden virtual functions...]
>
> }
>
> So you see that we override even the inherited methods again. There's a
> generator that does all the work, so this is really the easiest way.

-- 
Arno Rehn
arno at arnorehn.de



More information about the Kde-bindings mailing list