[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