[PyQt] QWidget call other __init__ methods, but why?
Phil Thompson
phil at riverbankcomputing.com
Tue Jun 28 18:11:36 BST 2016
On 28 Jun 2016, at 5:32 pm, Barry Scott <barry at barrys-emacs.org> wrote:
>
>
>> On 28 Jun 2016, at 17:01, Phil Thompson <phil at riverbankcomputing.com> wrote:
>>
>> On 28 Jun 2016, at 4:52 pm, Barry Scott <barry at barrys-emacs.org> wrote:
>>>
>>> Here we have a class that I use in my app. I just fixed a bug
>>> where wbTrackedModeless.__init__ was called twice as proved
>>> by using traceback.print_stack().
>>>
>>> class WbTrackedModelessQWidget(QtWidgets.QWidget, WbTrackedModeless):
>>> def __init__( self ):
>>> QtWidgets.QWidget.__init__( self, None ) # line 50
>>> def closeEvent( self, event ):
>>> WbTrackedModeless.closeEvent( self, event )
>>>
>>> super().closeEvent( event )
>>>
>>> From the definition it looks like wbTrackedModeless.__init__ is
>>> not called.
>>>
>>> However here is the stack:
>>>
>>> File "wb_scm_main.py", line 21, in <module>
>>> sys.exit( wb_main.main( wb_scm_app.WbScmApp, sys.argv ) )
>>> File "/Users/barry/wc/git/scm-workbench/Source/Common/wb_main.py", line 52, in main
>>> rc = app.exec_()
>>> File "/Users/barry/wc/git/scm-workbench/Source/Git/wb_git_ui_actions.py", line 172, in treeTableActionGitLogHistory
>>> self.main_window.callTreeOrTableFunction( self.treeActionGitLogHistory, self.tableActionGitLogHistory )
>>> File "/Users/barry/wc/git/scm-workbench/Source/Scm/wb_scm_main_window.py", line 617, in callTreeOrTableFunction
>>> return fn_tree()
>>> File "/Users/barry/wc/git/scm-workbench/Source/Git/wb_git_ui_actions.py", line 347, in treeActionGitLogHistory
>>> self.main_window.getQIcon( 'wb.png' ) )
>>> File "/Users/barry/wc/git/scm-workbench/Source/Git/wb_git_log_history.py", line 162, in __init__
>>> super().__init__()
>>> File "/Users/barry/wc/git/scm-workbench/Source/Common/wb_tracked_qwidget.py", line 50, in __init__
>>> QtWidgets.QWidget.__init__( self, None )
>>> File "/Users/barry/wc/git/scm-workbench/Source/Common/wb_tracked_qwidget.py", line 29, in __init__
>>> self.__trackWidget()
>>> File "/Users/barry/wc/git/scm-workbench/Source/Common/wb_tracked_qwidget.py", line 34, in __trackWidget
>>> traceback.print_stack()
>>>
>>> This shows that QtWidgets.QWidget.__init__( self, None ) called WbTrackedModeless.__init__()
>>> (__trackWidget is first line of __init__ at line 29).
>>>
>>> I guess Phil this is a question for you.
>>>
>>> Why does PyQt call __init__ if there is multiple inheritance? Is this a bug in PyQt?
>>
>> See...
>>
>> http://pyqt.sourceforge.net/Docs/PyQt5/multiinheritance.html
>
> Phil,
>
> I must be missing something important.
>
> https://rhettinger.wordpress.com/2011/05/26/super-considered-super/ shows the base classes being called
> via explicit super() calls. I cannot find a way to have super() call more then one function.
>
> If I recreate your Person example in pure python I do not see Age.__init__ called.
> It seems that you are doing something unique in PyQt to get Age called.
>
> Here is the code I used to test the idea in Hettinger’s blog based on your example
> (but avoiding the PyQy5 implementation):
>
> class QObject(object):
> def __init__( self ):
> print( 'instance of QObject.__init__' )
>
> class Age(object):
> def __init__( self, age=0, **kwds ):
> print( 'instance of Age.__init__' )
>
> self.age = age
>
> class Person(QObject, Age):
> def __init__( self, name='', **kwds ):
> print( 'instance of Person.__init__' )
> super().__init__()
>
> self.name = name
>
> x = Person( name='Barry', age=21 )
> print( x.name )
> print( x.age )
>
> Output:
>
> $ python3.5 qqq.py
> instance of Person.__init__
> instance of QObject.__init__
> <__main__.Person object at 0x1019e6668>
>
> Barry
You've missed out calls to super().__init__(**kwds)
Phil
More information about the PyQt
mailing list