Sharing widgets between PyQT and Boost.Python

I was wondering if it is possible to share widgets between PyQt and Boost.Python.

I will embed the Python interpreter in my application that uses Qt. I would like users of my application to be able to embed their own user interface widgets in user interface widgets programmed in C ++ and displayed through Boost.Python.

Is it possible and how to do it?

+3
source share
1 answer

I tried to write proxies for this, but I failed. Here's a start that tries to solve this, but dir () will not work. Call functions work directly.

The idea was to create an additional python object wrapped in SIP and redirect any calls / attributes to this object if the source boost.python object does not have the corresponding attribute.

I am not a Python guru to do this job properly. :(

(I turn this into a wiki, so ppl can edit and update here, as this code is only a semi-periodic template.)

C ++:

#include "stdafx.h"    
#include <QtCore/QTimer>

class MyWidget : public QTimer
{
public:
    MyWidget() {}
    void foo() { std::cout << "yar\n"; }
    unsigned long myself() { return reinterpret_cast<unsigned long>(this); }
};

#ifdef _DEBUG
BOOST_PYTHON_MODULE(PyQtBoostPythonD)
#else
BOOST_PYTHON_MODULE(PyQtBoostPython)
#endif
{
    using namespace boost::python;

    class_<MyWidget, bases<>, MyWidget*, boost::noncopyable>("MyWidget").
        def("foo", &MyWidget::foo).
        def("myself", &MyWidget::myself);
} 

Python:

from PyQt4.Qt import *
import sys

import sip
from PyQtBoostPythonD import * # the module compiled from cpp file above

a = QApplication(sys.argv)
w = QWidget()
f = MyWidget()

def _q_getattr(self, attr):
  if type(self) == type(type(MyWidget)):
    raise AttributeError
  else:
    print "get %s" % attr
    value = getattr(sip.wrapinstance(self.myself(), QObject), attr)
    print "get2 %s returned %s" % (attr, value)
    return value

MyWidget.__getattr__ = _q_getattr

def _q_dir(self):
  r = self.__dict__
  r.update(self.__class__.__dict__)
  wrap = sip.wrapinstance(self.myself(), QObject)
  r.update(wrap.__dict__)
  r.update(wrap.__class__.__dict__)
  return r

MyWidget.__dir__ = _q_dir

f.start()
f.foo()
print dir(f)
+2
source

Source: https://habr.com/ru/post/1717894/


All Articles