Solved QLineEdit::setReadOnly(), no signal
-
I have been a bit disappointed to find that
QLineEdit::setReadOnly()
does not emit a signal.Why do I want one? All over existing code there are sundry creations of
QLineEdit
s, and then they may callsetReadOnly(False)
andsetReadOnly(True)
dynamically at later times than construction all over the code. I decided to aid my poor confused users with a global-stylesheet-file rule:QLineEdit:read-only { background-color: #E5E7E9 }
But as we know, stylesheet rules are not re-evaluated after construction/first being shown till you explicitly force it to update by changing whatever stylesheet it has of its own (nothing to do with the global one), so for that I have defined a helper function:
def widgetPropertyChanged(widget: QWidget): # Whenever a widget property is changed # (widget.setProperty() or something like QLineEdit.setReadOnly()) called to *alter* a property after initialisation) # we have to "alter" widget's stylesheet to cause Qt to refresh for the property change ss = widget.styleSheet() widget.setStyleSheet("/* */" + (ss if ss is not None else "")) widget.setStyleSheet(ss)
Now, at least I could have hooked up existing
QLineEdit
s with a "change read only" signal to call that. But with no signal, I either have to track down every occurrence ofsetReadOnly()
and follow it with a call to that helper, or I have to subclass all myQLineEdit
s so that I can overridesetReadOnly()
to do it and change all my instances to the derived class.Is that right? I suppose this would apply equally to any other widget-inbuilt-property which may have a function to alter it and as a result of which i might want to force stylesheet re-evaluation?
-
@SGaist
Thank you, but sorry, let me be clear then:- From C++
QLineEdit::setReadOnly()
is not an overridable, virtual function. - From PyQt, there is a "wrapper" around the whole of
QLineEdit
, and that has chosen to supply a function, which happens to also be namedsetReadOnly
[but could have been called anything, e.g.pyqtSetReadOnly
], which (in Python) is a virtual, overridable function. - PyQt's
QLineEdit.setReadOnly()
presumably calls the base C++QLineEdit::setReadOnly()
to effect its work.
The big difference then is:
- In the case of a genuine
virtual
Qt C++ function, which I have chosen to override in PyQt, if Qt code internally calls the virtual function from itself it will hit my Python override. - But in the case of this non-
virtual
QLineEdit::setReadOnly()
, any internal Qt C++ calls to it will not be affected by the "override" I have defined from Python.
Does the above sound right?
EDIT I confirmed with the PyQt creator that this is indeed the way it works.
- From C++
-
And while I am here, here is a second post for a couple of additional brief clarification requests. Though please answer the main question first!
- In my stylesheet I could have written either one of:
QLineEdit:read-only { ... }
or
QLineEdit[readonly="true"] { ... }
for my rule. It didn't seem to matter which, they both respond to the result (after update forcing!) of
setReadOnly()
. Are they indeed the same, or is there a subtle difference?- Above I said a possible solution would be
subclass all my
QLineEdit
s so that I can overridesetReadOnly()
Now, I write in Python/PyQt, not C++, for my sins. From the (C++) documentation I can reach from page http://doc.qt.io/qt-5/qlineedit.html, Public Functions, click on link
void setReadOnly(bool)
, I get taken to http://doc.qt.io/qt-5/qlineedit.html#readOnly-prop, which describes a "Property". I did not see the definition ofsetReadOnly()
sayingvirtual
somewhere. So can I override it in a derived class? Is there something special about these "properties". Anything special Python/PyQt here?Thanks.
-
Hi,
You can use an event filter and listen for the
ReadOnlyChange
event on your QLineEdit objects.Hope it helps.
-
@SGaist
Thanks, I'm changing over to useQWidget::changeEvent
.Any comment on either of the questions in my second post above:
-
Is QSS
QLineEdit:read-only
simply the same as/a shortcut forQLineEdit[readonly="true"]
? -
Am I supposed to know from Qt C++ documentation that, e.g.
QLineEdit::setReadOnly()
is overridable, because I don't seevirtual
? My PyCharm shows it as "overridable" for me from PyQt, but I don't see where that correspond to the C++ documentation?
-
-
@JonB said in QLineEdit::setReadOnly(), no signal:
@SGaist
Thanks, I'm changing over to useQWidget::changeEvent
.Any comment on either of the questions in my second post above:
-
Is QSS
QLineEdit:read-only
simply the same as/a shortcut forQLineEdit[readonly="true"]
? -
Am I supposed to know from Qt C++ documentation that, e.g.
QLineEdit::setReadOnly()
is overridable, because I don't seevirtual
? My PyCharm shows it as "overridable" for me from PyQt, but I don't see where that correspond to the C++ documentation?
-
- It's possible both of these selection works as similar but they are differente methods of selection -> Read More: https://webplatform.github.io/docs/guides/advanced_selectors_guide/
-
- Yes, you can reimplement this function, but it is good to know why some functions are implemented as Virtual -> Read More: https://stackoverflow.com/questions/2391679/why-do-we-need-virtual-functions-in-c
-
-
@KillerSmath
Thank you, but I'm afraid neither of your comments address my questions:-
The selector reference you provided is for CSS, which I know about. My questions is about Qt's QSS, which has "invented" the
:read-only
pseudo-state. -
I know all about
virtual
functions. My question is: is/how come http://doc.qt.io/qt-5/qlineedit.html#readOnly-prop does not showvirtual
anywhere, yet it is overridable at least from PyQt?
-
-
Because it's not a virtual function and yes, the documentation is correct (you can check the source code)
Python is an entirely different beast. You can modify any element of an object the way you want.
-
@SGaist
Thank you, but sorry, let me be clear then:- From C++
QLineEdit::setReadOnly()
is not an overridable, virtual function. - From PyQt, there is a "wrapper" around the whole of
QLineEdit
, and that has chosen to supply a function, which happens to also be namedsetReadOnly
[but could have been called anything, e.g.pyqtSetReadOnly
], which (in Python) is a virtual, overridable function. - PyQt's
QLineEdit.setReadOnly()
presumably calls the base C++QLineEdit::setReadOnly()
to effect its work.
The big difference then is:
- In the case of a genuine
virtual
Qt C++ function, which I have chosen to override in PyQt, if Qt code internally calls the virtual function from itself it will hit my Python override. - But in the case of this non-
virtual
QLineEdit::setReadOnly()
, any internal Qt C++ calls to it will not be affected by the "override" I have defined from Python.
Does the above sound right?
EDIT I confirmed with the PyQt creator that this is indeed the way it works.
- From C++
-
Would it be possible for you to provide a small example that would confirm that ?