Совместное использование виджетов между PyQT и Boost.Python - PullRequest
3 голосов
/ 17 сентября 2009

Мне было интересно, можно ли делиться виджетами между PyQt и Boost.Python.

Я буду встраивать интерпретатор Python в мое приложение, использующее Qt. Я хотел бы, чтобы пользователи моего приложения могли встраивать свои собственные виджеты UI в виджеты UI, запрограммированные в C ++ и предоставляемые через Boost.Python.

Возможно ли это и как можно поступить так?

1 Ответ

2 голосов
/ 07 октября 2009

Я пытался написать прокси для этого, но мне не удалось полностью. Вот начало, которое пытается решить эту проблему, но dir () не будет работать. Вызов функций напрямую работает несколько.

Идея состояла в том, чтобы создать дополнительный объект python, завернутый в SIP, и перенаправить любые вызовы / атрибуты этому объекту, если исходный объект boost.python не имеет какого-либо соответствующего атрибута.

Мне не хватает гуру Python, чтобы заставить это работать должным образом. (

(я превращаю это в вики, чтобы ppl мог редактировать и обновлять здесь, так как этот код - просто недоделанный шаблон).

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)
...