[PyKDE] Re: Bug with QScrollView viewport binding

Giovanni Bajo rasky at develer.com
Wed Jun 29 16:07:28 BST 2005


Phil Thompson <phil at riverbankcomputing.co.uk> 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.

Notice that there is *never* a need for downcast in PyQt, and this would be
a sole example. 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).

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.

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.
-- 
Giovanni Bajo




More information about the PyQt mailing list