[PyQt] Overriding QWidget methods, and/or improving Pythonicity

VA dev+pyqt at indigo.re
Sat Nov 5 13:14:58 GMT 2016


Le 02.11.2016 19:29, John Ladasky a écrit :
> Hello everyone,
>
> I understand that the PyQt5 package wraps Qt5 in a highly parallel
> fashion.  PyQt5's documentation links, function by function, to the
> Qt documentation.  Thus we frequently find C++ ways of doing things
> in our Python code.
>
> I am currently customizing a QWidget which owns child widgets.  I
> don't want ALL my child widgets to be grayed out when I disable the
> widget.  So I am overriding the setEnabled() function of my custom
> widget.  Each child widget is enabled or disabled separately.
>
> I am always nervous when I override a PyQt class whose code I haven't
> read (I'm not much of a C++ programmer, and I don't have the Qt
> source).  I don't always know when to call the superclass function
> because it performs important housekeeping tasks.  We all know to
> call the superclass __init__() within our own __init__().  How about
> with other methods?  I always try to get away without a superclass
> call.  So far I haven't broken anything.
>
> In any case, setEnabled(True) and setEnabled(False) is starting to
> bug me.  I have noticed that QWidget lacks enable() and disable(). 
> Is there any reason that Qt itself does not include methods with 
> these
> simple names, which would take no arguments, and are more explicit? 
> As a Python programmer, I would prefer to see that.
>
> Of course I could subclass QWidget from Python, to add these features
> to any class I design.  But any QWidget subclasses which are already
> in the Qt hierarchy would be unaffected.  Monkey patching could work,
> but I would prefer a more transparent solution.
>

> Comments are appreciated, thanks.

Fellow PyQters should correct me if I'm wrong, but I think another 
factor is the "virtual" C++ attribute on certain methods. To simplify, 
if it is not present on a method, you can still override the method in 
Python, but only Python code will be able to call it.
For example, setEnabled is not virtual in C++. If C++ code calls 
setEnabled on your widget, your implementation will *not* be called.

However, a QEvent::EnabledChange is sent to a widget. changeEvent an 
event methods are virtual, so you can override them.
Furthermore, Qt provides an "event filtering" mechanism. This allows 
any QObject (and thus QWidget) to incercept all events sent to another 
QObject, and possibly stop them.
This solution will probably work better than monkey-patcing and gives 
finer control on which objects you want to handle.

http://doc.qt.io/qt-5/qobject.html#installEventFilter
http://doc.qt.io/qt-5/qcoreapplication.html#notify


More information about the PyQt mailing list