[PyQt] QSettings.registerFormat unavailable in PyQt4?
Phil Thompson
phil at riverbankcomputing.com
Sat Jun 6 13:35:14 BST 2009
On Sat, 06 Jun 2009 12:17:21 +0200, Giovanni Bajo <rasky at develer.com>
wrote:
> 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:
>>>>
>>>>
>>>
>>
>
http://doc.trolltech.com/qtjambi-4.5.0_01/com/trolltech/qt/core/QSettings.html
>>>
>>> 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
> the
>>> 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
> };
>
> registerFormat(...)
> %MethodCode
> if (index == MAX_CUSTOM_FORMATS) {
> PyErr_Format(RuntimeError, "Sorry, PyQt supports only %d custom
> QSettings formats", MAX_CUSTOM_FORMATS);
> return;
> }
>
> PyObject *read = sipA1;
> Py_INCREF(read);
> ReadCallable[index] = read;
>
> PyObject *write = sipA2;
> Py_INCREF(write);
> WriteCallable[index] = write;
>
> QSettings::registerFormat(sipA0, ReadFuncTable[index],
> WriteFuncTable[index]);
>
> index++;
> %End
>
>
>> 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
> callback
>> in all situations which requires that the callback is passed something
> that
>> 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
> limit.
I agree that that would work. If I can get over my strong sense of distaste
I might implement it.
Phil
More information about the PyQt
mailing list