[PyKDE] Sugestions for PyQt4
David Boddie
david at boddie.org.uk
Mon Mar 20 18:18:32 GMT 2006
On Mon, 20 Mar 2006 10:26:27, Eric Jardim wrote:
>- "Pythonic" Qt properties: instead of using things like:
>"isEnabled()" and "setEnabled()", properties could be acessed
>like python real properties, I mean, just "enabled". The functions
>could still be mapped anyway.
This could be added or enabled in an additional wrapper. Maybe even
one that is distributed in the PyQt4 package.
>I don't know how SIP works (automatically or handmade), and it
>will give a lot of work to acomplish this "by hand". I've have
>made some progress with a tool called pygccxml, that can parse C++
>code and find Qt properties and other Qt special macros (with some
>tricks).
As I understand it, the SIP binding definitions are auto-generated
by another tool that does this sort of thing. Adding support for
Qt properties in "standard" Qt widgets could be done in Python, and
could either be implemented using Python's descriptors (properties)
http://docs.python.org/ref/descriptors.html
http://docs.python.org/api/descriptor-objects.html
or with __getattr__ and __setattr__.
>- C++ embedding: it may be useful for some users to embed Python
>plugins in an C++ application. This could be a "magic gate" for
>some "static" applications that want to be more flexible. There
>should be some limitations to this technique, but if we can easily
>use Python obejcts in C++ applications. Remember that we have to
>connect C++ signals/slots to Python signal/slots (see dynamic
>metaobjects below).
In many ways, it's straightforward to achieve this by implementing
a suitable plugin class in C++ then wrapping it for Python with
SIP. The code generated by SIP then acts as the "magic gate".
>- QtDesigner integration: I think this is a dream of everyone to
>make your custom widgets available in QtDesigner. With the new Qt4
>API, it is very easy to write plugins for QtDesigner.
Yes, I'm really interested in this.
>The problem of the QtDesigner approach is that you have to create
>a share object (plugin library) for each component you may add to
>the Widget Box (palette).
This can be a good thing in certain situations.
>I thought of a single approach of creating a generic QPythonWidget
>(a proxy) that internally calls your custom real Python extension.
I can't remember if you managed that with your early prototypes
for python-qt. The main problem is that the widgets you return to
Designer have to have the correct meta-information in order for
them to work properly. It's quite easy to give them the correct
class name and super class information; the rest is more difficult.
>Plus, we must adapt the QtUiTools::QUiLoader
>(http://doc.trolltech.com/4.1/quiloader.html) and pyuic4 to load
>the Python widget correctly. A scratch of this can be found
>here:
>http://svn.berlios.de/viewcvs/python-qt4/trunk/PythonQt/
I haven't looked at this.
>By the way, to be fully useful, our Python widgets should expose
>their SIGNALs, SLOTs and properties to QtDesigner (and native C++
>classes if embedded), and this means a new way of facing
>metaobjects (see below).
It basically means having support for custom Qt properties, signals
and slots, so that C++ code can introspect them just like it would
any other QObject subclass.
[...]
>When you create a new class, derived from QObject (or any other
>like QWidget and so on), moc (meta object compiler) creates a
>"static" metaobject, describing the class. I mean static in two
>meanings: it is static (is the same) for every object the class,
>and do not change with time (like const).
>This is Ok for C++ extensions, but Python widgets may change
>durring the execution of the program. We can add new signals,
>slots or properties class-wide or object-wide. This makes the
>complexity grows a little bit.
What's more, you can't just create these objects at the level of
the bindings because subclasses of Python-implemented widgets
also need to store their own meta-data somewhere.
>My progress over this is here:
>http://svn.berlios.de/viewcvs/python-qt4/trunk/PythonQt/QtWrapper.h?view=markup
I need to look at this again.
>With this feature, we can use Python signals inside QtDesigner,
>inside a C++ embedded python application and we can treat all of
>them the same way (goodbye PYSIGNAL). The way things are today,
>there is no way declare a Python signal. You just know it exist
>when you emit it. OTOH, any method in your class can be a slot.
>This is fine, but how do you want to expose your class to someone?
>How do you tell that just some of your methods are really meant to
>be slots?
I think there was a decorator-inspired solution to this problem
that
is equivalent to your suggestion:
>- The new Signal, Slot, Property idom:
>With all this changes, it should be nice to define the a way to
>declare our QObject classes extensions. My sugestion is the
simples
>as possible:
[...]
> # how to define a slot
> def aSlot(sender, text):
> ...
> aSlot = QSLOT(aSlot, 'QObject, str')
>
> # how to define a signal
> def aSignal(message):
> ...
> aSignal = QSIGNAL(aSlot, 'str')
I also chose to implement properties in a similar way to you:
> # how to define a property
> def pSet(value):
> ...
> def pGet():
> ...
> p = QPROPERTY(pGet, PSet, ...) #look: p is a Qt and Python
> property!
The only problem here is that Qt and Python have slightly
different ideas about the other purpose of the property.
Qt supports properties that can be reset; Python's can be
deleted.
>In Python 2.4 we can also have sintax sugar:
>class MyWidget(QWidget):
> @QSLOT('QObject, str')
> def aSlot(sender, text):
> ...
>
> @QSIGNAL('str')
> def aSignal(message):
> ...
Yes, this looks familiar. :-)
>Sweet, hu? So you got the idea. But you may also have noticed
>that I declared the types of the params. Some people may not
>like this. But think that, in some cases, there is no way of
>guessing what kind of slot you are talking about, unless you
>specify the types (remember Qt have some slots with same name,
>but different types). It will help with QtDesigner integration.
Designer integration is the main purpose, as far as I'm concerned.
You absolutely need type information for that.
For properties, things are a little simpler. You could
let developers specify Python types for those because you are
dealing with value types.
[Smart connections]
>- How to deal with Qt Intefaces?
>Not thought about this yet.
I decided to write a C++ plugin class that implemented
QDesignerCustomWidgetInterface using Qt's macros. I think that
this is the place to mix C++ and Python because it's designed to
be instantiated only once, it's simple to construct in a loader
library, and it lets us write the widget in pure Python.
Ideally, I'd write the plugin itself (apart from the loader
library) in Python, but I couldn't think of a way to do it.
>Well, here we have a good start. There are other little things,
>but let's focus on this first :)
I haven't touched my code for about a month. I'll build the
latest SIP and PyQt4 snapshots and see if I can get it working
with them. Then I'll upload the code somewhere.
David
___________________________________________________________
$0 Web Hosting with up to 200MB web space, 1000 MB Transfer
10 Personalized POP and Web E-mail Accounts, and much more.
Signup at www.doteasy.com
More information about the PyQt
mailing list