简体   繁体   中英

How do I get the text of an QLineEdit into a method?

I'm still not able to understand how to properly connect Qt_pushButton or Qt_LineEdit to methods. I would be so glad to get a explanation which even I do truly understand...

I've put together a pretty basic UI with Qt Designer. It contains a lineEdit called "lineEditTest" which I can indeed change by typing

self.lineEditTest.setText("changed Text")

However, I'm totally stuck with getting the text which the user entered back into my program. I would like to automatically submit the entered text into my function which sets a var to this value and returns it into my UI class. QLineEdit's signal editingFinished sounds perfect for that I guess? But it won't pass the text which the user entered into my function.

QLineEdit does have a property called "text" right? So it seems logical to me that I just have to pass another arg - apart from self - to my function called text.

My code does look like this but it obviously won't work at all:

from PyQt5 import QtWidgets, uic
import sys


class Ui(QtWidgets.QMainWindow):
    def __init__(self):
        super(Ui, self).__init__()
        uic.loadUi('test.ui', self)

        self.lineEditTest.setText("test")
        self.lineEditTest.editingFinished.connect(self.changeText(text))
        self.show()

    def changeText(self):
        currentText = text
        print (currentText)
        return currentText

app = QtWidgets.QApplication(sys.argv)
window = Ui()
app.exec_()

This will just crash with:

NameError: name 'text' is not defined`

The problem seems to be that the OP doesn't understand the logic of the signals and slots (I recommend you check here ). The signals are objects that emit information, and the slots are functions (generally callable ) that are connected to the signals to receive that information. And the information transmitted by the signal depends on each case, for example if you check the docs of editingFinished signal:

void QLineEdit::editingFinished()
This signal is emitted when the Return or Enter key is pressed or the line edit loses focus. Note that if there is a validator() or inputMask() set on the line edit and enter/return is pressed, the editingFinished() signal will only be emitted if the input follows the inputMask() and the validator() returns QValidator::Acceptable.

That signal does not send any information so do not expect to receive any information except knowing that the edition has ended by the user. So how can I get the text? Well, through the text() method of QLineEdit:

class Ui(QtWidgets.QMainWindow):
    def __init__(self):
        super(Ui, self).__init__()
        uic.loadUi("test.ui", self)

        self.lineEditTest.setText("test")
        self.lineEditTest.editingFinished.connect(self.changeText)
        self.show()

    def changeText(self):
        text = self.lineEditTest.text()
        print(text)

And how to do if the signal sends information? Then the slot (the function) that this connected will have as arguments to that information, for example if you use the textChanged signal that is emitted every time the text of the QLineEdit is changed, it should be as follows:

class Ui(QtWidgets.QMainWindow):
    def __init__(self):
        super(Ui, self).__init__()
        uic.loadUi("test.ui", self)

        self.lineEditTest.setText("test")
        self.lineEditTest.textChanged.connect(self.changeText)
        self.show()

    def changeText(self, text):
        print(text)
        # or
        # text = self.lineEditTest.text()
        # print(text)

The way you're binding your callback isn't correct. When you bind a callback (and this is true for other frameworks, not just for binding callbacks in PyQt), you want to bind the function which should be triggered when a certain event occurs. That's not what you're doing - you're explicitly invoking the callback self.changeText(text) (note: the parentheses invoke the function). So, you're invoking (calling) the function, evaluating it and placing the return value in ...editingFinished.connect() .

Don't explicitly invoke the function. Just pass the function's name. This makes sense if you think about it: we're passing a callable object to connect - this is the function which should be called at a later point in time, when the editingFinished event occurs.

You also don't need to pass lineEditTest 's text into the callback, since you can just get whatever text is in the widget via self.lineEditTest.text() from inside the callback.

from PyQt5.QtCore import pyqtSlot
from PyQt5.QtWidgets import QMainWindow


class MainWindow(QMainWindow):

    def __init__(self):

        from PyQt5 import uic

        super(MainWindow, self).__init__()

        uic.loadUi("mainwindow.ui", self)

        self.lineEditTest.setPlaceholderText("Type something...")
        self.lineEditTest.editingFinished.connect(self.on_line_edit_finished_editing)

    @pyqtSlot()
    def on_line_edit_finished_editing(self):
        text = self.lineEditTest.text()
        print(f"You finished editing, and you entered {text}")


def main():
    from PyQt5.QtWidgets import QApplication

    application = QApplication([])
    window = MainWindow()

    window.show()

    return application.exec()


if __name__ == "__main__":
    import sys
    sys.exit(main())

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM