Python method resolution mystery

前端 未结 3 537
终归单人心
终归单人心 2021-01-13 07:29

I can\'t figure out why this program is failing.

#!/usr/bin/env python
from __future__ import division, print_function
from future_builtins import *
import t         


        
相关标签:
3条回答
  • 2021-01-13 08:15

    I suggest that you not attempt to expose QPoint in boost python. You should be able to register converters to/from python with boost that will use the SIP api functions to convert QPoint from/to python as the sip objects.

    I've done it, but not recently enough to give more details.

    0 讨论(0)
  • 2021-01-13 08:17

    This is an example how to integrate PyQt4 and boost::python

    first of all we must define wrap/unwrap function to deal with bare pointers

    long int unwrap(QObject* ptr) {
        return reinterpret_cast<long int>(ptr);
    }
    
    template <typename T>
    T* wrap(long int ptr) {
        return reinterpret_cast<T*>(ptr);
    }
    

    after that we must register all classes we want integrate to

    class_<QObject, QObject*, boost::noncopyable>("QObject", no_init)
        .def("unwrap", unwrap)
        .def("wrap", make_function( wrap<QObject>, return_value_policy<return_by_value>() ))
        .staticmethod("wrap");
    
    class_<QWidget, bases<QObject>, QWidget*, boost::noncopyable>("QWidget")
        .def("wrap", make_function( wrap<QWidget>, return_value_policy<return_by_value>() ))
        .staticmethod("wrap");
    
    class_<QFrame, bases<QWidget>, QFrame*, boost::noncopyable>("QFrame")
        .def("wrap", make_function( wrap<QFrame>, return_value_policy<return_by_value>() ))
        .staticmethod("wrap");
    
    class_<QLabel, bases<QFrame>, QLabel*, boost::noncopyable>("QLabel")
        .def("wrap", make_function( wrap<QLabel>, return_value_policy<return_by_value>() ))
        .staticmethod("wrap");
    

    and for example we have class that works with.. QLabel:

    class worker: public QObject {
    ...
    void add_label(QLabel*);
    };
    

    we must expose this class to python too:

    class_<worker, bases<QObject>, worker*, boost::noncopyable>("worker")
            .def("add_label", &worker::add_label);
    

    now we a ready to interaction, on C++-size do something like this

    worker* w = new worker;
    main_namespace["worker"] = boost::ref(w);
    

    python:

    from PyQt4.Qt import *
    import sip
    import mylib as MyLib
    
    #...
    
    #If you are using QApplication on C++-size you don't need to create another one
    
    lb = QLabel("label from PyQt4!")
    
    lb_ptr = sip.unwrapinstance(f)
    
    my_lb = MyLib.QLabel.wrap(lb_ptr)
    
    worker.add_label(my_lb)
    

    In other case if you wan't send you own Q-object to PyQt4 :

    QLabel* lb = new QLabel("C++ label");
    main_namespace["lb"] = boost::ref(lb);
    

    python:

    from PyQt4.Qt import *
    import sip
    import mylib as MyLib
    
    #...
    
    my_lb_ptr = lb.unwrap()
    
    qt_lb = sip.wrapinstance(my_lb_ptr, QLabel)
    

    And this is my real little helper:

    from PyQt4.Qt import *
    import sip
    
    def toQt(object, type):
        ptr = object.unwrap()
        return sip.wrapinstance(ptr, type)
    
    def fromQt(object, type):
        ptr = sip.unwrapinstance(object)
        return type.wrap(ptr)
    
    0 讨论(0)
  • 2021-01-13 08:29

    This is somewhat similar to the issue someone else has encountered just yesterday. In short, it seems like special methods (like __getattr__, __str__, __repr__, __call__ and so on) aren't overridable in new-style class instance, i.e. you can only define them in its type.

    And here's an adaptation of my solution for that problem which should hopefully work for yours:

    def _q_getattr(self, attr):
        print("get %s" % attr)
        return getattr(self, 'x')
    
    def override(p, methods):
        oldType = type(p)
        newType = type(oldType.__name__ + "_Override", (oldType,), methods)
        p.__class__ = newType
    
    override(p, { '__getattr__': _q_getattr})
    print(p.__getattr__('x')())  # Works!  Prints "0"
    print(p.x())                 # Should work!
    
    0 讨论(0)
提交回复
热议问题