2009-09-17 4 views
3

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

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

Возможно ли это и как это сделать?

ответ

2

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

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

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

(. Я превращаюсь это в вики, так ППЛ может редактировать и обновлять здесь, так как этот код только полусырой шаблонного)

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)