[PyQt] QSettings.registerFormat unavailable in PyQt4?

Giovanni Bajo rasky at develer.com
Sat Jun 6 11:17:21 BST 2009

On Sat, 06 Jun 2009 11:02:18 +0100, Phil Thompson
<phil at riverbankcomputing.com> wrote:
> On Sat, 06 Jun 2009 02:56:55 +0200, Giovanni Bajo <rasky at develer.com>
> wrote:
>> On Sat, 6 Jun 2009 01:19:39 +0200, David Boddie <david at boddie.org.uk>
>> wrote:
>>> On Fri Jun 5 19:25:01 BST 2009, Giovanni Bajo wrote:
>>>> On 6/4/2009 10:18 PM, Phil Thompson wrote:
>>>> > It can't be wrapped because of the nature of the function pointer
>>>> > arguments - bad API design.
>>>> Is it the same with Jambi?
>>> I think so - look here:
>> Given that there is no way to unregister a format, I think that there is
> a
>> way to wrap it for PyQt: just prepare a fixed number of clones of global
>> read/write functions, that retrieve Python's callable objects from a
>> fixed-size global array. Each time registerFormat() is used, save the
> read
>> and write function callables into the global arrays (incref'ing them
>> forever, and using an ever growing counter that says how many custom
>> formats have been registered); then, call the C++ version and pass it
>> pointers to the correct couple of clones of the global read/write
>> functions.
> How do you identify the correct couple of clones?

With a growing index. Let's see if this makes sense

#define MAX_CUSTOM_FORMATS 3  // "ought to be enough for everyone"(TM)

int index = 0;
PyObject *ReadCallable[MAX_CUSTOM_FORMATS];
PyObject *WriteCallable[MAX_CUSTOM_FORMATS];

void ReadFunc0(args...) { invoke ReadCallable[0] with args }
void ReadFunc1(args...) { invoke ReadCallable[1] with args }
void ReadFunc2(args...) { invoke ReadCallable[2] with args }

void WriteFunc0(args...) { invoke WriteCallable[0] with args }
void WriteFunc1(args...) { invoke WriteCallable[1] with args }
void WriteFunc2(args...) { invoke WriteCallable[2] with args }

ReadFunc *ReadFuncTable[MAX_CUSTOM_FORMATS] = {
     ReadFunc0, ReadFunc1, ReadFunc2

WriteFunc *WriteFuncTable[MAX_CUSTOM_FORMATS] = {
     WriteFunc0, WriteFunc1, WriteFunc2

   if (index == MAX_CUSTOM_FORMATS) {
      PyErr_Format(RuntimeError, "Sorry, PyQt supports only %d custom
QSettings formats", MAX_CUSTOM_FORMATS);

   PyObject *read = sipA1;
   ReadCallable[index] = read;

   PyObject *write = sipA2;
   WriteCallable[index] = write;

   QSettings::registerFormat(sipA0, ReadFuncTable[index],


> There's no problem with wrapping function pointers in themselves. What's
> missing is that those functions should also take the QSettings::Format as
> an additional parameter. A good API will allow you to use a single
> in all situations which requires that the callback is passed something
> allows it to identify the particular context.

Yes: but we can get away with this in this case because we can support a
bounded number of custom formats without probably noone ever hitting the
Giovanni Bajo
Develer S.r.l.

More information about the PyQt mailing list