Clear QLineEdit on click event

adam picture adam · Oct 10, 2017 · Viewed 13.7k times · Source

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"))

Answer

eyllanesc picture eyllanesc · Oct 10, 2017

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_())