[PyKDE] Implementation of KConfigSkeleton::addItemUInt
Jim Bublitz
jbublitz at nwinternet.com
Wed Sep 1 22:14:07 BST 2004
On Wednesday 01 September 2004 00:26, Michael Franz Aigner wrote:
> Subject: Implementation of KConfigSkeleton::addItemUInt
>
> Hello,
>
> While using KConfigSkeleton in an application of mine, I noticed that
> KConfigSkeleton::addItemInt/UInt are not working. The value of the
> returned configuration item would change randomly while the
> application runs.
>
> Tracking down the problem i found out that the C++ code generated by
> sip passes a reference to temporary integer variable to the C++
> function, whereas a reference to a non-temporary variable would be
> needed. This is because KConfigSkeleton remembers the reference and
> uses it later in the application. This reference ends up pointing to
> the location on the stack where this temporary variable once was but
> not anymore is. As this location on the stack is reused, the variable
> the reference is pointing to seemingly changes its value randomly as
> the application runs.
>
> In search for a way to make KConfigSkeleton::addItemUInt work, i came
> up with the following. The patch is against PyKDE 3.11.3:
> http://amfranz.com/pykde/PyKDE-3.11.3-intref.diff
>
> Usage would be something like:
>
> ===
> from kdecore import KConfigSkeleton, UIntRef
>
> class Preferences(KConfigSkeleton):
> def __init__(self, *args):
> KConfigSkeleton.__init__(self, *args)
>
> self.some_int_setting = kdecore.UIntRef()
> self.some_int_setting_property =
> self.addItemUInt('some_int_setting', self.some_int_setting, 1000)
>
> print "value is: %d" % self.some_int_setting.getValue()
> ===
>
> Could you comment on that?
> Maybe there a simpler way to make KConfigSkeleton::addItemInt work,
> w/o introducing a new class, like 'UIntRef' in the above example?
This is what KDE does:
KConfigSkeleton::ItemBool *KConfigSkeleton::addItemBool (onst QString &name,
bool &reference, bool defaultValue, const QString &key )
{
KConfigSkeleton::ItemBool *item;
item =
new KConfigSkeleton::ItemBool( mCurrentGroup, key.isNull() ? name : key,
reference,defaultValue );
addItem( item, name );
return item;
}
In Python you should be able to do:
self.reference = True
self.item = KConfigSkeleton.ItemBool (mCurrentGroup, name, reference,
defaultValue)
self.addItem (self.item, name)
I'm not sure I handled the key/name distinction correctly, but it should be
doable. I'm also not sure if that fixes the "scalar-by-reference" problem
either, but I think it does.
In that case, you should be able to overload addItemBool in Python to take
self.item instead of the bool reference. Seems to me that should work,
although I obviously don't have the details worked out. I'd prefer that to
adding the additional classes. What I'd like to avoid is "special" PyKDE
methods/classes if at all possible. In this case, the required classes
*almost* exist already.
I could also modify the addItem* calls to create the referenced scalar on the
heap instead of as a temporary. I'm not sure how it would get deleted though
- probably in the dtors for the Item* objects. There are some other things I
could try along those lines, including not calling the C++ addItem* methods
at all, but doing the equivalent on the sip C++ code side if that proved
useful.
Would you be able to try out the Python suggestion above?
It's going to take me some time to work through this, as I don't have any
working code that uses KConfigSkeleton, and whatever solution I try, I'd like
to be able to test here. I also need to test out the Item<scalar> classes and
verify that the Python code (including "casting") works correctly - those
might also need some work. It's likely to take some time.
The underlying problem is that all of this is built off of
KConfigSkeletonGenericItem, which is a template class and I've taken the
"easy" way around that.
Very nice job on the C++ code fix though - it looks like it should work
correctly and it doesn't seem like it would have the memory leak problem
mentioned above.
Jim
More information about the PyQt
mailing list