Slot Wrapper Python
- Python Slot Wrapper
- Slot Wrapper Python Download
- Python Api Wrapper
- Python Wrapper Function
- Slot Wrapper Python Example
- Python Wrapper Class
The main interface to PythonQt is the PythonQt singleton. PythonQt needs to be initialized via PythonQt::init() once. Afterwards you communicate with the singleton via PythonQt::self(). PythonQt offers a complete Qt binding, which needs to be enabled via PythonQt_QtAll::init().
The following table shows the mapping between Python and Qt objects:
Installation for Python 2.4 through 2.7; pyjack. Pyjack; Some Doctest Examples. Some examples of connecting to functions. Prevent function from firing; Filtering args; Works across memory space; Works on object methods (but not slot wrappers) Does not work on slot wrappers (like builtin init, etc.) Works on callables that define call. Note that slot wrappers are always unbound (there is a bound variant called method-wrapper). So, they are actually methods which wrap over C-implemented methods of objects. Many of the magic methods and attributes in Python are implemented via slot wrappers over C objects. As most implementations of Python are written in C, this makes sense.
Qt/C++ | Python |
---|---|
bool | bool |
double | float |
float | float |
char/uchar,int/uint,short,ushort,QChar | integer |
long | integer |
ulong,longlong,ulonglong | long |
QString | unicode string |
QByteArray | QByteArray wrapper (1) |
char* | str |
QStringList | tuple of unicode strings |
QVariantList | tuple of objects |
QVariantMap | dict of objects |
QVariant | depends on type (2) |
QSize, QRect and all other standard Qt QVariants | variant wrapper that supports complete API of the respective Qt classes |
OwnRegisteredMetaType | C++ wrapper, optionally with additional information/wrapping provided by registerCPPClass() |
QList<AnyObject*> | converts to a list of CPP wrappers |
QVector<AnyObject*> | converts to a list of CPP wrappers |
EnumType | Enum wrapper derived from python integer |
QObject (and derived classes) | QObject wrapper |
C++ object | CPP wrapper, either wrapped via PythonQtCppWrapperFactory or just decorated with decorators |
PyObject | PyObject (3) |
- The Python 'bytes' type will automatically be converted to QByteArray where required. For converting a QByteArray to 'bytes' use the .data() method.
- QVariants are mapped recursively as given above, e.g. a dictionary can contain lists of dictionaries of doubles.
- PyObject is passed as direct pointer, which allows to pass/return any Python object directly to/from a Qt slot that uses PyObject* as its argument/return value.
All Qt QVariant types are implemented, PythonQt supports the complete Qt API for these objects.
- ('class', type), ('delattr', slot wrapper 'delattr' of 'object' objects), ('dict', mappingproxy('module': 'main', 'hello'.
- Applying Wrapper Methods in Python for Feature Selection. Use a forward selection method with the 'probe' method as a stopping criterion or use the l0-norm embedded method for comparison, following the ranking of step 5, construct a sequence of predictors of same nature using increasing.
All classes derived from QObject are automatically wrapped with a python wrapper class when they become visible to the Python interpreter. This can happen via
- the PythonQt::addObject() method
- when a Qt slot returns a QObject derived object to python
- when a Qt signal contains a QObject and is connected to a python function
It is important that you call PythonQt::registerClass() for any QObject derived class that may become visible to Python, except when you add it via PythonQt::addObject(). This will register the complete parent hierachy of the registered class, so that when you register e.g. a QPushButton, QWidget will be registered as well (and all intermediate parents).
From Python, you can talk to the returned QObjects in a natural way by calling their slots and receiving the return values. You can also read/write all properties of the objects as if they where normal python properties.
In addition to this, the wrapped objects support
- className() - returns a string that reprents the classname of the QObject
- help() - shows all properties, slots, enums, decorator slots and constructors of the object, in a printable form
- delete() - deletes the object (use with care, especially if you passed the ownership to C++)
- connect(signal, function) - connect the signal of the given object to a python function
- connect(signal, qobject, slot) - connect the signal of the given object to a slot of another QObject
- disconnect(signal, function) - disconnect the signal of the given object from a python function
- disconnect(signal, qobject, slot) - disconnect the signal of the given object from a slot of another QObject
- children() - returns the children of the object
- setParent(QObject) - set the parent
- QObject* parent() - get the parent
The below example shows how to connect signals in Python:
You can create dedicated wrapper QObjects for any C++ class. This is done by deriving from PythonQtCppWrapperFactory and adding your factory via addWrapperFactory(). Whenever PythonQt encounters a CPP pointer (e.g. on a slot or signal) and it does not known it as a QObject derived class, it will create a generic CPP wrapper. So even unknown C++ objects can be passed through Python. If the wrapper factory supports the CPP class, a QObject wrapper will be created for each instance that enters Python. An alternative to a complete wrapper via the wrapper factory are decorators, see Decorator slots
For each known C++ class, PythonQt provides a Python class. These classes are visible inside of the 'PythonQt' python module or in subpackages if a package is given when the class is registered.
A Meta class supports:
- access to all declared enum values
- constructors
- static methods
- unbound non-static methods
- help() and className()
From within Python, you can import the module 'PythonQt' to access these classes and the Qt namespace.
PythonQt introduces a new generic approach to extend any wrapped QObject or CPP object with
- constructors
- destructors (for CPP objects)
- additional slots
- static slots (callable on both the Meta object and the instances)
The idea behind decorators is that we wanted to make it as easy as possible to extend wrapped objects. Since we already have an implementation for invoking any Qt Slot from Python, it looked promising to use this approach for the extension of wrapped objects as well. This avoids that the PythonQt user needs to care about how Python arguments are mapped from/to Qt when he wants to create static methods, constructors and additional member functions.
The basic idea about decorators is to create a QObject derived class that implements slots which take one of the above roles (e.g. constructor, destructor etc.) via a naming convention. These slots are then assigned to other classes via the naming convention.
- SomeClassName* new_SomeClassName(...) - defines a constructor for 'SomeClassName' that returns a new object of type SomeClassName (where SomeClassName can be any CPP class, not just QObject classes)
- void delete_SomeClassName(SomeClassName* o) - defines a destructor, which should delete the passed in object o
- anything static_SomeClassName_someMethodName(...) - defines a static method that is callable on instances and the meta class
- anything someMethodName(SomeClassName* o, ...) - defines a slot that will be available on SomeClassName instances (and derived instances). When such a slot is called the first argument is the pointer to the instance and the rest of the arguments can be used to make a call on the instance.
The below example shows all kinds of decorators in action:
Python Slot Wrapper
After you have registered an instance of the above ExampleDecorator, you can do the following from Python (all these calls are mapped to the above decorator slots):
In PythonQt, each wrapped C++ object is either owned by Python or C++. When an object is created via a Python constructor, it is owned by Python by default. When an object is returned from a C++ API (e.g. a slot), it is owned by C++ by default. Since the Qt API contains various APIs that pass the ownership from/to other C++ objects, PythonQt needs to keep track of such API calls. This is archieved by annotating arguments and return values in wrapper slots with magic templates:
These annotation templates work for since C++ pointer types. In addition to that, they work for QList<AnyObject*>, to pass the ownership for each object in the list.
Examples:
There are a large number of structures which are used in the definition ofobject types for Python. This section describes these structures and how theyare used.
All Python objects ultimately share a small number of fields at the beginningof the object’s representation in memory. These are represented by thePyObject
and PyVarObject
types, which are defined, in turn,by the expansions of some macros also used, whether directly or indirectly, inthe definition of all other Python objects.
PyObject
¶All object types are extensions of this type. This is a type whichcontains the information Python needs to treat a pointer to an object as anobject. In a normal “release” build, it contains only the object’sreference count and a pointer to the corresponding type object. Itcorresponds to the fields defined by the expansion of the PyObject_HEAD
macro.
PyVarObject
¶This is an extension of PyObject
that adds the ob_size
field. This is only used for objects that have some notion of length.This type does not often appear in the Python/C API. It corresponds to thefields defined by the expansion of the PyObject_VAR_HEAD
macro.
These macros are used in the definition of PyObject
andPyVarObject
:
PyObject_HEAD
¶This is a macro which expands to the declarations of the fields of thePyObject
type; it is used when declaring new types which representobjects without a varying length. The specific fields it expands to dependon the definition of Py_TRACE_REFS
. By default, that macro isnot defined, and PyObject_HEAD
expands to:
When Py_TRACE_REFS
is defined, it expands to:
PyObject_VAR_HEAD
¶This is a macro which expands to the declarations of the fields of thePyVarObject
type; it is used when declaring new types whichrepresent objects with a length that varies from instance to instance.This macro always expands to:
Note that PyObject_HEAD
is part of the expansion, and that its ownexpansion varies depending on the definition of Py_TRACE_REFS
.
Py_TYPE
(o)¶This macro is used to access the ob_type
member of a Python object.It expands to:
New in version 2.6.
Py_REFCNT
(o)¶This macro is used to access the ob_refcnt
member of a Pythonobject.It expands to:
New in version 2.6.
Py_SIZE
(o)¶This macro is used to access the ob_size
member of a Python object.It expands to:
New in version 2.6.
PyObject_HEAD_INIT
(type)¶This is a macro which expands to initialization values for a newPyObject
type. This macro expands to:
PyVarObject_HEAD_INIT
(type, size)¶This is a macro which expands to initialization values for a newPyVarObject
type, including the ob_size
field.This macro expands to:
PyCFunction
¶Type of the functions used to implement most Python callables in C.Functions of this type take two PyObject*
parameters and returnone such value. If the return value is NULL, an exception shall havebeen set. If not NULL, the return value is interpreted as the returnvalue of the function as exposed in Python. The function must return a newreference.
PyMethodDef
¶Structure used to describe a method of an extension type. This structure hasfour fields:
Field | C Type | Meaning |
---|---|---|
| char * | name of the method |
| PyCFunction | pointer to the Cimplementation |
| int | flag bits indicating how thecall should be constructed |
| char * | points to the contents of thedocstring |
The ml_meth
is a C function pointer. The functions may be of differenttypes, but they always return PyObject*
. If the function is not ofthe PyCFunction
, the compiler will require a cast in the method table.Even though PyCFunction
defines the first parameter asPyObject*
, it is common that the method implementation uses thespecific C type of the self object.
The ml_flags
field is a bitfield which can include the following flags.The individual flags indicate either a calling convention or a bindingconvention. Of the calling convention flags, only METH_VARARGS
andMETH_KEYWORDS
can be combined. Any of the calling convention flagscan be combined with a binding flag.
METH_VARARGS
¶This is the typical calling convention, where the methods have the typePyCFunction
. The function expects two PyObject*
values.The first one is the self object for methods; for module functions, it isthe module object. The second parameter (often called args) is a tupleobject representing all arguments. This parameter is typically processedusing PyArg_ParseTuple()
or PyArg_UnpackTuple()
.
METH_KEYWORDS
¶Methods with these flags must be of type PyCFunctionWithKeywords
.The function expects three parameters: self, args, and a dictionary ofall the keyword arguments. The flag is typically combined withMETH_VARARGS
, and the parameters are typically processed usingPyArg_ParseTupleAndKeywords()
.
METH_NOARGS
¶Methods without parameters don’t need to check whether arguments are given ifthey are listed with the METH_NOARGS
flag. They need to be of typePyCFunction
. The first parameter is typically named self
andwill hold a reference to the module or object instance. In all cases thesecond parameter will be NULL.
METH_O
¶Methods with a single object argument can be listed with the METH_O
flag, instead of invoking PyArg_ParseTuple()
with a 'O'
argument.They have the type PyCFunction
, with the self parameter, and aPyObject*
parameter representing the single argument.
METH_OLDARGS
¶This calling convention is deprecated. The method must be of typePyCFunction
. The second argument is NULL if no arguments aregiven, a single object if exactly one argument is given, and a tuple ofobjects if more than one argument is given. There is no way for a functionusing this convention to distinguish between a call with multiple argumentsand a call with a tuple as the only argument.
These two constants are not used to indicate the calling convention but thebinding when use with methods of classes. These may not be used for functionsdefined for modules. At most one of these flags may be set for any givenmethod.
METH_CLASS
¶The method will be passed the type object as the first parameter ratherthan an instance of the type. This is used to create class methods,similar to what is created when using the classmethod()
built-infunction.
New in version 2.3.
METH_STATIC
¶The method will be passed NULL as the first parameter rather than aninstance of the type. This is used to create static methods, similar towhat is created when using the staticmethod()
built-in function.
One other constant controls whether a method is loaded in place of anotherdefinition with the same method name.
Slot Wrapper Python Download
METH_COEXIST
¶The method will be loaded in place of existing definitions. WithoutMETH_COEXIST, the default is to skip repeated definitions. Since slotwrappers are loaded before the method table, the existence of asq_contains slot, for example, would generate a wrapped method named__contains__()
and preclude the loading of a correspondingPyCFunction with the same name. With the flag defined, the PyCFunctionwill be loaded in place of the wrapper object and will co-exist with theslot. This is helpful because calls to PyCFunctions are optimized morethan wrapper object calls.
New in version 2.4.
PyMemberDef
¶Structure which describes an attribute of a type which corresponds to a Cstruct member. Its fields are:
Field | C Type | Meaning |
---|---|---|
| char * | name of the member |
| int | the type of the member in theC struct |
| Py_ssize_t | the offset in bytes that themember is located on thetype’s object struct |
| int | flag bits indicating if thefield should be read-only orwritable |
| char * | points to the contents of thedocstring |
type
can be one of many T_
macros corresponding to various Ctypes. When the member is accessed in Python, it will be converted to theequivalent Python type.
Macro name | C type |
---|---|
T_SHORT | short |
T_INT | int |
T_LONG | long |
T_FLOAT | float |
T_DOUBLE | double |
T_STRING | char * |
T_OBJECT | PyObject * |
T_OBJECT_EX | PyObject * |
T_CHAR | char |
T_BYTE | char |
T_UBYTE | unsigned char |
T_UINT | unsigned int |
T_USHORT | unsigned short |
T_ULONG | unsigned long |
T_BOOL | char |
T_LONGLONG | long long |
T_ULONGLONG | unsigned long long |
T_PYSSIZET | Py_ssize_t |
Python Api Wrapper
T_OBJECT
and T_OBJECT_EX
differ in thatT_OBJECT
returns None
if the member is NULL andT_OBJECT_EX
raises an AttributeError
. Try to useT_OBJECT_EX
over T_OBJECT
because T_OBJECT_EX
handles use of the del
statement on that attribute more correctlythan T_OBJECT
.
flags
can be 0
for write and read access or READONLY
forread-only access. Using T_STRING
for type
impliesREADONLY
. Only T_OBJECT
and T_OBJECT_EX
members can be deleted. (They are set to NULL).
PyGetSetDef
¶Structure to define property-like access for a type. See also description ofthe PyTypeObject.tp_getset
slot.
Field | C Type | Meaning |
---|---|---|
name | char * | attribute name |
get | getter | C Function to get the attribute |
set | setter | optional C function to set ordelete the attribute, if omittedthe attribute is readonly |
doc | char * | optional docstring |
closure | void * | optional function pointer,providing additional data forgetter and setter |
The get
function takes one PyObject*
parameter (theinstance) and a function pointer (the associated closure
):
It should return a new reference on success or NULL with a set exceptionon failure.
set
functions take two PyObject*
parameters (the instance andthe value to be set) and a function pointer (the associated closure
):
In case the attribute should be deleted the second parameter is NULL.Should return 0
on success or -1
with a set exception on failure.
Python Wrapper Function
Py_FindMethod
(PyMethodDef table[], PyObject *ob, char *name)¶Slot Wrapper Python Example
Return value: New reference.Python Wrapper Class
Return a bound method object for an extension type implemented in C. Thiscan be useful in the implementation of a tp_getattro
ortp_getattr
handler that does not use thePyObject_GenericGetAttr()
function.
The Python Software Foundation is a non-profit corporation. Please donate.
Last updated on Apr 20, 2020. Found a bug?
Created using Sphinx 2.3.1.