On Wednesday 29 June 2005 4:07 pm, Giovanni Bajo wrote: > Phil Thompson <[EMAIL PROTECTED]> wrote: > >>> Yes - but they aren't in existence at the same time. > >>> [...] > >>> Using a temporary name to keep a reference to sv.viewport() solves the > >>> problem. > >> > >> Then you have the inverse problem: > >> > >> ---------------------------------------------- > >> from qt import * > >> > >> app = QApplication([]) > >> sv = QScrollView(None) > >> w = QWidget(sv.viewport()) > >> > >> p = w.parent() > >> print sv.viewport().width() > >> ---------------------------------------------- > >> Traceback (most recent call last): > >> File "D:\Work\caligola3d\src\pyqtbug3.py", line 9, in ? > >> print sv.viewport().width() > >> AttributeError: width > >> > >> which is wrong because viewport() is supposed to return a QWidget > > pointer. > > > It sees that it has already been wrapped (as a QObject) and just returns > > an > > > extra reference. It doesn't try to retype the existing wrapper, or create > > a > > > new wrapper to the same C++ instance with the more specific type. > > I understand the technical problem, but I believe it is a right expectation > that any call to QScrollView.viewport() return a QWidget, as documented. > The fact that thousands lines away I happen to have a QObject reference to > the same object should not thoeretically make QScrollView.viewport() break > its contract.
Understood - but I'm concerned about possible unforeseen implications. Of the two obvious options... 1) Re-type the existing object when the more specific type is known. This is probably safe to do as far as the internals are concerned - but the idea of a Python object changing type under your feet sounds horrible. 2) Generate a new wrapper to the same C++ object with the more specific type. This has obvious problems with ownership (who calls the C++ dtor?), and things like "is" would fail. This is a real can of worms. > Notice that there is *never* a need for downcast in PyQt, and this would be > a sole example. Some PyKDE uses have this requirement - hence sip.cast(). > For instance: > ---------------------------------- > > >>> from qt import * > >>> app = QApplication([]) > >>> class Foo(QWidget): > > ... k = 1 > ... > > >>> f = Foo(None) > >>> w = QWidget(f) > >>> w.parent().k > > 1 > > >>> print w.parent() > > <__main__.Foo object at 0x00813660> > ---------------------------------- > In this case, PyQt was *even* able to recreate a wrapper of type Foo from > the parent call. I assume because the actual underlying type is something > that PyQt knows about (Foo) instead of an internal Qt type (as for the case > of the scrollview's viewport). No, it's because f keeps the wrapper alive so it is found by w.parent(). > It is surprising that the call to parent() in the original example is not > able to return a QWidget. The common PyQt behaviour is always to return a > reference to most down-casted type. So I would expect the parent() to > return *at least* a QWidget whenever the object is a QWidget. The most down-cast type, yes - but *only* if it is a know type. Otherwise it resorts to the base type. > Either that, or always retry to downcast any reference you get from the > internal SIP map of existing python refernces. QScrollView.viewport() > really *is* supposed to return *at least* a QWidget. Yes - rather than see if the type *is* a known type, see if the type is *derived* from a known type. Or maybe do the second only if the first fails (for speed and to ensure it doesn't break existing behaviour). Phil _______________________________________________ PyKDE mailing list [email protected] http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
