Is it possible to detect a mouse press or mouse click on a QLineEdit that has been set to either .NoFocus or .setReadOnly, and then call a function to do something? If so, how?
Is it possible to detect a mouse press or mouse click on a QLineEdit that has been set to either .NoFocus or .setReadOnly, and then call a function to do something? If so, how?
Hi, you could try an event filter:
https://doc.qt.io/qt-5/qobject.html#installEventFilter
but I'm not sure if an object with NoFocus will receive any events.
What do you want to do?
Ginsengelf
Sorry for the delay -- went out of town.
I set several QLineEdits to .setReadOnly when I do not want the user to input any data. However, I wanted to remind the user why they cannot enter any data. I used a tooltip to accomplish what I want, but the best thing is to show a QMessageBox (or something like that) when the user "clicks" the LiineEdit to enter data (a tooltip does not show when clicking the line edit). I read about the event filters, but am such a newbie that I could not set it up to test. Could you help? Here is what I tried, but of course, it does not work:
in my init:
Qt Code:
self.ui.BTE.installEventFilter(self.ui.BTE)To copy to clipboard, switch view to plain text mode
in a function:
thanks for lookingQt Code:
def eventFilter(self, source, event): if self.BTE.isReadOnly: message = 'Test' self.blueboxmessage(message) else: returnTo copy to clipboard, switch view to plain text mode
If you are trying to fire a mouse event to test your code, this is not the way to do it. You need to post an actual event to the Qt event loop so it can be processed and eventually sent to your event filter. See QCoreApplication::postEvent() or QCoreApplication::sendEvent() for the details. I do not know for sure whether sendEvent() will activate your event filter or not, so you would have to test that. If it doesn't work, then you'll have to use postEvent() instead.self.ui.BTE.mousePressEvent(QMouseEvent=)
In C++, an eventFIlter() method must return a Boolean true or false to determine whether the event handling stops (true - the event filter "eats" the event) or continues (false - to be also handled by the object it is intended for). If you are not interested in the event at all, then you have to call the superclass eventFilter() method and return its true / false return value. If you don't follow these rules, then your line edit might fail to work at all.
See the documentation for QObject::eventFilter() which shows how to correctly implement eventFilter() in a MainWindow class.
If I were doing this, I would not use a dialog-based class to show the message. I would create a QToolTip instance as a member of your class, call QToolTip::showText() in the mouse pressed event, and call QToolTip::hideText() in both the mouse release and leave events for your line edit. You could also start a QTimer when you show the tooltip, and hide the tooltip when the timeout event fires.
Doing it with a QDialog means the user has to click somewhere else to dismiss the dialog, and it removes the focus from the line edit in the process. I guarantee this will lead to more UI problems.
<=== The Great Pumpkin says ===>
Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.
Trying to implement what you suggested in last paragraph:
in init:
Qt Code:
self.ui.BTFE.installEventFilter(self)To copy to clipboard, switch view to plain text modeQt Code:
def eventFilter(self, source, event): self.ui.BTFE.setToolTip('Cannot enter data here') return super(UIMainWindow, self).eventFilter(source, event) def remove_tooltip(self): self.ui.BTFE.setToolTip('')To copy to clipboard, switch view to plain text mode
I cannot figure out the pyqt code for "showing" and 'hiding" the tooltip -- I only know how to code .setTooltip, but that does not show the tip when the line edit is clicked -- only when hover. Plus, not sure if QTimer will do what I want. Ultimately, I'll have nine line edits that I need to test, all with the same tool tip. thanks
I am not a Qt Python expert, but I think you need something like this:
Qt Code:
def eventFilter(self, source, event): QtWidgets.QTooltiip.showText( source.pos(), 'Cannot enter data here') return super(UIMainWindow, self).eventFilter(source, event) def remove_tooltip(self): QtWidgets.QTooltiip.hideText()To copy to clipboard, switch view to plain text mode
In the eventFilter() "source" is the QWidget instance that is the focus of the event, so it -is- "self.ui.BTFE" in this case, since that's where you have installed the filter. So in the event filter code, you can simply replace "self.ui.BTFE" with "source" and it will work for all of your line edits.
I do not know for sure if QTooltip::showText() is a blocking method (ie, it suspends the rest of the code until it is hidden again), so I switched the order of starting the timer and showing the tip just to make sure the timer is running first.
You also need to check to see if you can TAB into a read-only QLineEdit, and if so, you will probably wnat to display the tooltip for an enter event as well.
<=== The Great Pumpkin says ===>
Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.
My PyCharm IDE is telling me it does not recognize QtWidgets, even though I have this import:
Qt Code:
from PyQt5.QtWidgets import QMainWindow, QMenu, QLineEdit, QComboBox, QFileDialog, QMessageBox, QPushButton, QToolTip, QWidgetTo copy to clipboard, switch view to plain text mode
I then added: (below import above):
Qt Code:
from PyQt5 import QtWidgetsTo copy to clipboard, switch view to plain text mode
That import got rid of the 'not recognized' issue, and no errors when run. I changed the event to MouseButtonRelease so the message would show for the 5 seconds. However, 1) the tooltip shows well away from the line edit. Is the source.pos() supposed to make the tooltip show next to the line edit that was clicked?
thanks for your response
Last edited by dennisvz; 28th August 2020 at 01:06.
Hi, pos() returns the position in widget coordinates. I think globalPos() is what you need.
Ginsengelf
Qt Code:
To copy to clipboard, switch view to plain text mode
gives an AttributeError: 'QLineEdit' object has no attribute 'globalPos'
So you fire up your browser, type "Qt globalpos" into the Google search box, and what do you think you get as the first hit? Certainly faster than asking questions here and waiting for someone to answer.gives an AttributeError: 'QLineEdit' object has no attribute 'globalPos'
And since you already imported QTooltip from QtWidgets, you can probably remove the QtWidgets part of QtWidgets.QTooltip.showText and just use QTooltip.showText. I said I wasn't a Python expert. Also get rid of the separate import of all of QtWidgets. It just bogs things down at runtime.
<=== The Great Pumpkin says ===>
Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.
dennisvz (28th August 2020)
Bookmarks