[PyQt] PyQt4 question (follow on)

Detlev Offenbach detlev at die-offenbachs.de
Mon May 28 10:51:56 BST 2007


On Montag, 28. Mai 2007, Phil Thompson wrote:
> On Monday 28 May 2007 9:53 am, Detlev Offenbach wrote:
> > On Montag, 28. Mai 2007, Detlev Offenbach wrote:
> > > On Sonntag, 27. Mai 2007, Phil Thompson wrote:
> > > > On Sunday 27 May 2007 1:10 pm, Detlev Offenbach wrote:
> > > > > On Sonntag, 27. Mai 2007, Phil Thompson wrote:
> > > > > > On Sunday 27 May 2007 12:37 pm, Detlev Offenbach wrote:
> > > > > > > On Sonntag, 27. Mai 2007, Phil Thompson wrote:
> > > > > > > > On Sunday 27 May 2007 11:50 am, Detlev Offenbach wrote:
> > > > > > > > > On Sonntag, 27. Mai 2007, Phil Thompson wrote:
> > > > > > > > > > On Saturday 26 May 2007 9:07 pm, Detlev Offenbach wrote:
> > > > > > > > > > > On Samstag, 26. Mai 2007, Phil Thompson wrote:
> > > > > > > > > > > > On Saturday 26 May 2007 7:58 pm, Detlev Offenbach 
wrote:
> > > > > > > > > > > > > On Samstag, 26. Mai 2007, Phil Thompson wrote:
> > > > > > > > > > > > > > On Saturday 26 May 2007 4:52 pm, Detlev Offenbach
> >
> > wrote:
> > > > > > > > > > > > > > > Hi,
> > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > is there a PyQt equivalent to
> > > > > > > > > > > > > > > "qobject_cast<T*>(object)"?
> > > > > > > > > > > > > >
> > > > > > > > > > > > > > sip.cast()?
> > > > > > > > > > > > > >
> > > > > > > > > > > > > > But it shouldn't be necessary if the sub-class
> > > > > > > > > > > > > > conversion code has been properly implemented.
> > > > > > > > > > > > >
> > > > > > > > > > > > > How do I do that. I haven't wrapped complicated
> > > > > > > > > > > > > stuff like this so far. The situation is as
> > > > > > > > > > > > > follows. I have the following code:
> > > > > > > > > > > > >
> > > > > > > > > > > > >
> > > > > > > > > > > > > self.plugins.extend(self.designer.pluginManager().i
> > > > > > > > > > > > >ns ta nc es () ) for plugin in self.plugins:
> > > > > > > > > > > > >             if isinstance(plugin,
> > > > > > > > > > > > > QDesignerFormEditorPluginInterface): if not
> > > > > > > > > > > > > plugin.isInitialized():
> > > > > > > > > > > > > plugin.initialze(self.designer)
> > > > > > > > > > > > >
> > > > > > > > > > > > >
> > > > > > > > > > > > > "self.designer.pluginManager().instances()" returns
> > > > > > > > > > > > > a list of QObject. The first if statement shall
> > > > > > > > > > > > > check, wether the returned QObject is of type
> > > > > > > > > > > > > QDesignerFormEditorPluginInterface. In C++ you
> > > > > > > > > > > > > would do it with code like
> > > > > > > > > > > > >
> > > > > > > > > > > > > if (
> > > > > > > > > > > > > (qobject_cast<QDesignerFormEditorPluginInterface*>(
> > > > > > > > > > > > >pl ug in )) )
> > > > > > > > > > > > >
> > > > > > > > > > > > > How can the problem be solved with PyQt4 and
> > > > > > > > > > > > > Python?
> > > > > > > > > > > > >
> > > > > > > > > > > > > Note: self.designer.pluginManager() returns an
> > > > > > > > > > > > > object of type QDesignerPluginManager.
> > > > > > > > > > > >
> > > > > > > > > > > > The wrapper for QDesignerFormEditorPluginInterface
> > > > > > > > > > > > must define some %ConvertToSubClassCode which will
> > > > > > > > > > > > use RTTI provided by the instance to identify the
> > > > > > > > > > > > right Python type object. See how PyQt does it for
> > > > > > > > > > > > QObject and QEvent. If the instance doesn't provide
> > > > > > > > > > > > any RTTI then you're stuck.
> > > > > > > > > > >
> > > > > > > > > > > Mustn't the %ConvertToSubClassCode go into the more
> > > > > > > > > > > general class (e.g. QObject)?
> > > > > > > > > >
> > > > > > > > > > No - just in a QObject sub-class in the module.
> > > > > > > > > >
> > > > > > > > > > > Is there a way to extend the QObject wrapper?
> > > > > > > > > >
> > > > > > > > > > That's what sip does under the covers.
> > > > > > > > >
> > > > > > > > > I am stuck at the moment due to my lack of sip know how.
> > > > > > > > > Below is the wrapper code in question. How does the
> > > > > > > > > %ConvertToSubClassCode have to be?
> > > > > > > > >
> > > > > > > > > -----------------------------------------------------------
> > > > > > > > >-- -- -- -- -- -- -- -- - class
> > > > > > > > > QDesignerFormEditorPluginInterface {
> > > > > > > > >
> > > > > > > > > %TypeHeaderCode
> > > > > > > > > #include <abstractformeditorplugin.h>
> > > > > > > > > %End
> > > > > > > > >
> > > > > > > > > public:
> > > > > > > > >     virtual ~QDesignerFormEditorPluginInterface();
> > > > > > > > >
> > > > > > > > >     virtual bool isInitialized() const = 0;
> > > > > > > > >     virtual void initialize(QDesignerFormEditorInterface
> > > > > > > > > *core) = 0; virtual QAction *action() const = 0;
> > > > > > > > >
> > > > > > > > >     virtual QDesignerFormEditorInterface *core() const = 0;
> > > > > > > > > };
> > > > > > > > > -----------------------------------------------------------
> > > > > > > > >-- -- -- -- -- -- -- --
> > > > > > > >
> > > > > > > > What RTTI is available for the code to determine what the
> > > > > > > > class really is? I can't see anything that is obviously
> > > > > > > > suitable - in which case you are stuck.
> > > > > > >
> > > > > > > In a C++ program one would do it with this statement
> > > > > > >
> > > > > > > qobject_cast<QDesignerFormEditorPluginInterface*>(object)
> > > > > > >
> > > > > > > where object is a pointer to a QObject. If the conversion code
> > > > > > > would be in QObject.sip, one could probably use the inherits()
> > > > > > > method of QObject.
> > > > > >
> > > > > > So that's what you put in your conversion code in your
> > > > > > QDesignerFormEditorPluginInterface class.
> > > > >
> > > > > I tried that before I posted to this list, but it didn't work.
> > > > > Phil, can you give a little help?
> > > >
> > > > Post what you tried.
> > >
> > > I tried it with the following code:
> > >
> > > %ModuleHeaderCode
> > > #include <qobject.h>
> > > %End
> > >
> > > class QDesignerFormEditorPluginInterface
> > > {
> > >
> > > %TypeHeaderCode
> > > #include <abstractformeditorplugin.h>
> > > %End
> > >
> > > %ConvertToSubClassCode
> > >     if ( (qobject_cast<QDesignerFormEditorPluginInterface*>(sipCpp)) )
> > >         sipClass = sipClass_QDesignerFormEditorPluginInterface;
> > >     else
> > >         sipClass = NULL;
> > > %End
> > >
> > > public:
> > >     virtual ~QDesignerFormEditorPluginInterface();
> > >
> > >     virtual bool isInitialized() const = 0;
> > >     virtual void initialize(QDesignerFormEditorInterface *core) = 0;
> > >     virtual QAction *action() const = 0;
> > >
> > >     virtual QDesignerFormEditorInterface *core() const = 0;
> > > };
> > >
> > > However, that code doesn't even compile because at this place,
> > > QDesignerFormEditorPluginInterface isn't derived from QObject. It
> > > seems, that this is a mixin class, that QDesignerPluginManager takes
> > > care of and returns a QObject.
> >
> > I traced this a bit further through the Qt code and found, that the
> > plugin is loaded via QPluginLoader::instance(). Here is an excerpt from
> > the Qt docu on how to use such a plugin.
> >
> > "The component object is a QObject. Use qobject_cast() to access
> > interfaces you are interested in."
> >
> > It seems, we are missing something here on the Python side.
>
> I'm not sure how to come to that conclusion.
>
> I would look at creating a C++ class that is the minimal implementation of
> an object that conforms to the interface (ie. it is subclassed from QObject
> and QDesignerFormEditorPluginInterface). Then provide it with appropriate
> sub-class conversion code. You could look at the QtDesigner QPy classes in
> PyQt4 - these don't include sub-class convertor code because they are
> intended for writing Python plugins rather than loading C++ plugins.
>

Ok, I have to give up at this point. Unless some experienced programmer offers 
some help, I will stop the eric4 designer integration.

Detlev
-- 
Detlev Offenbach
detlev at die-offenbachs.de


More information about the PyQt mailing list