Clear QLineEdit on click event

20,090

Solution 1

The solution is to promote QtDesigner use our custom QLineEdit where we implement the signal clicked with the help of mousePressEvent, this class will be called ClickableLineEdit and the file will be called ClickableLineEdit.py.

ClickableLineEdit.py

from PyQt5.QtCore import pyqtSignal
from PyQt5.QtWidgets import QLineEdit


class ClickableLineEdit(QLineEdit):
    clicked = pyqtSignal()
    def mousePressEvent(self, event):
        self.clicked.emit()
        QLineEdit.mousePressEvent(self, event)

To promote it, the following structure will be considered:

.
├── ClickableLineEdit.py
├── main.py  
├── your.ui
└── QLineEdit_test.py

Open the design with Qt Designer and right click on the QLineEdit and select Promote to ...:

enter image description here

A menu will open and place the following

enter image description here

then press and Promote. Then we generate the code again.

Then we connect the signal to clear:

class MainWindow(QMainWindow, QLineEdit_test.Ui_QLineEdit_test):

    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.setupUi(self)

        self.copy_button.clicked.connect(self.copy_and_print)
        self.lineEdit.clicked.connect(self.lineEdit.clear)

    def copy_and_print(self):
        self.label.setText(self.lineEdit.text())

Update:

PySide2:

from PySide2 import QtCore, QtWidgets


class ClickableLineEdit(QtWidgets.QLineEdit):
    clicked = QtCore.Signal()

    def mousePressEvent(self, event):
        super(ClickableLineEdit, self).mousePressEvent(event)
        self.clicked.emit()


class App(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()

        self.lineedit = ClickableLineEdit()
        self.lineedit.clicked.connect(self.lineedit.clear)

        lay = QtWidgets.QVBoxLayout(self)
        lay.addWidget(self.lineedit)


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication.instance()
    if app is None:
        app = QtWidgets.QApplication(sys.argv)
    ex = App()
    ex.show()
    sys.exit(app.exec_())

Solution 2

def __init__(self, *args, **kwargs):
    QWidget.__init__(self, *args, **kwargs)

    layout = QGridLayout()
    self.setLayout(layout)

    self.lineedit = QLineEdit()
    self.lineedit.returnPressed.connect(self.press)
    layout.addWidget(self.lineedit, 0, 0)

def press(self):
    print("Hi World")
    self.lineedit.clear()

Solution 3

I have an optional solution in one line:

self.lineEdit.mouseReleaseEvent = self.copy_and_print

Make sure you are receiving two parameters in your function (self,event) I hope I helped you

Full post: https://wiki.python.org/moin/PyQt/Making%20non-clickable%20widgets%20clickable

Solution 4

Use mousePressEvent of QLineEdit to detect mouse click. To clear the text use clear() method or setText() method of QLineEdit.

#called when ever mouse is pressed
def mousePressed(self, event):
    print('mouse pressed')

self.lineEdit=QLineEdit("Awesome day")#from PyQt5.QtWidget import QLineEdit
self.lineEdit.mousePressEvent = self.mousePressed

Example program :

import sys

from PyQt5.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QApplication, QLineEdit


class ButtonPanel(QWidget):
    def __init__(self, heading):
        self.initUI(heading)

    def initUI(self, heading):
        super().__init__()
        self.layout = QHBoxLayout()
        self.lineEdit = QLineEdit(heading)
        #self.lineEdit.setReadOnly(True)
        self.lineEdit.returnPressed.connect(self.returnPressed)
        self.lineEdit.mousePressEvent = self.mousePressed
        self.delete = QPushButton("D")
        self.layout.addWidget(self.lineEdit)
        self.layout.addWidget(self.delete)
        self.setLayout(self.layout)
        self.show()

    #called when mouse is clicked
    def mousePressed(self, event):
        self.lineEdit.clear() #text is cleared
        //self.lineEdit.setText("") #this way we can also clear the text
        print('mouse pressed')

    //called when return key is pressed
    def returnPressed(self):
        print('return pressed')


if __name__ == "__main__":
    app = QApplication(sys.argv)
    b = ButtonPanel("Awesome")
    sys.exit(app.exec())

Output :

ButtonPanel

Share:
20,090
adam
Author by

adam

Updated on January 17, 2022

Comments

  • adam
    adam over 2 years

    I am using the given code, I want the user to enter text in the QLineEdit widget, press the Copy! button and see the inputted text replace the 'N/A' label. My questions is: following this procedure, how can I clear the text inputted in the QLineEdit widget with a simple mouse click?

    From what I read (this, this and this) it seems like I need to reimplement focusInEvent() in a new class extending QLineEdit. My problem is that the code for my GUI has been imported from Qt Designer using pyuic5 and the examples cited above don't seem to take this in consideration.

    Here is my code:

    from PyQt5.QtWidgets import *
    import sys
    
    import QLineEdit_test
    
    
    class MainWindow(QMainWindow, QLineEdit_test.Ui_QLineEdit_test):
    
        def __init__(self, parent=None):
            super(MainWindow, self).__init__(parent)
            self.setupUi(self)
    
            self.copy_button.clicked.connect(self.copy_and_print)
    
        def copy_and_print(self):
    
            self.label.setText(self.lineEdit.text())
    
    
    def main():
    
        app = QApplication(sys.argv)
        form = MainWindow()
        form.show()
        app.exec_()
    
    if __name__ == "__main__":
        main()
    

    Here is my converted .ui file:

    from PyQt5 import QtCore, QtGui, QtWidgets
    
    class Ui_QLineEdit_test(object):
        def setupUi(self, QLineEdit_test):
            QLineEdit_test.setObjectName("QLineEdit_test")
            QLineEdit_test.resize(300, 200)
            QLineEdit_test.setMaximumSize(QtCore.QSize(300, 200))
            self.centralwidget = QtWidgets.QWidget(QLineEdit_test)
            self.centralwidget.setObjectName("centralwidget")
            self.gridLayout_2 = QtWidgets.QGridLayout(self.centralwidget)
            self.gridLayout_2.setObjectName("gridLayout_2")
            self.gridLayout = QtWidgets.QGridLayout()
            self.gridLayout.setObjectName("gridLayout")
            self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
            self.lineEdit.setMaximumSize(QtCore.QSize(120, 16777215))
            self.lineEdit.setObjectName("lineEdit")
            self.gridLayout.addWidget(self.lineEdit, 0, 0, 1, 1)
            self.copy_button = QtWidgets.QPushButton(self.centralwidget)
            self.copy_button.setObjectName("copy_button")
            self.gridLayout.addWidget(self.copy_button, 1, 0, 1, 1)
            self.label = QtWidgets.QLabel(self.centralwidget)
            self.label.setMaximumSize(QtCore.QSize(200, 20))
            self.label.setAlignment(QtCore.Qt.AlignCenter)
            self.label.setObjectName("label")
            self.gridLayout.addWidget(self.label, 2, 0, 1, 1)
            self.gridLayout_2.addLayout(self.gridLayout, 0, 0, 1, 1)
            QLineEdit_test.setCentralWidget(self.centralwidget)
            self.menubar = QtWidgets.QMenuBar(QLineEdit_test)
            self.menubar.setGeometry(QtCore.QRect(0, 0, 300, 22))
            self.menubar.setObjectName("menubar")
            QLineEdit_test.setMenuBar(self.menubar)
            self.statusbar = QtWidgets.QStatusBar(QLineEdit_test)
            self.statusbar.setObjectName("statusbar")
            QLineEdit_test.setStatusBar(self.statusbar)
    
            self.retranslateUi(QLineEdit_test)
            QtCore.QMetaObject.connectSlotsByName(QLineEdit_test)
    
        def retranslateUi(self, QLineEdit_test):
            _translate = QtCore.QCoreApplication.translate
            QLineEdit_test.setWindowTitle(_translate("QLineEdit_test", "MainWindow"))
            self.copy_button.setText(_translate("QLineEdit_test", "Copy!"))
            self.copy_button.setShortcut(_translate("QLineEdit_test", "Return"))
            self.label.setText(_translate("QLineEdit_test", "N/A"))
    
  • adam
    adam over 6 years
    Thanks for the quick answer, I had indeed missed this option. Having said that, is it possible to replicate the same behaviour without the clearButton? By having the user click anywhere in the QLineEdit field? Also, if is not possible, can the colors of the clearButton be modified?
  • adam
    adam over 6 years
    Sorry about that. I'll come back to you as soon as I have tried your solution. Thank you.
  • eyllanesc
    eyllanesc over 4 years
    mmm, it is a solution but I do not think it is optimal since the mouseReleaseEvent: code.qt.io/cgit/qt/qtbase.git/tree/src/widgets/widgets/… method implements other things that with your solution do not cancel
  • Javier Escalona
    Javier Escalona over 4 years
    You can change mouseReleaseEvent by mousePressEvent
  • eyllanesc
    eyllanesc over 4 years
    the same problem: you eliminate the default behavior that causes secondary problems: code.qt.io/cgit/qt/qtbase.git/tree/src/widgets/widgets/…
  • Javier Escalona
    Javier Escalona over 4 years
    yes sure, it is a solution too simple to be the best, the parsimony principle does not apply here.
  • eyllanesc
    eyllanesc over 4 years
    My comment is to warn the community of the inconveniences of your solution.
  • Javier Escalona
    Javier Escalona over 4 years
    thanks for that, I was not realizing that I was replacing a method that had other functionalities