0

I am trying to understand why I cannot pass a parameter to my Slot function. I defined a showMessage(・・・) function so I can reuse it with a different message from a different Signal source. However the code below does not work. How could I fix the code so that it shows the text of the QLineEdit right above the pressed QPushButton when QMessageBox is shown.

import sys

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

class Window(QtWidgets.QMainWindow):
    def __init__(self):
        super(Window, self).__init__()

        self.mainWidget = QWidget()
        mainLayout = QVBoxLayout(self.mainWidget)

        lineEdit_1 = QLineEdit()
        button_1 = QPushButton("Show Message 1")

        lineEdit_2 = QLineEdit()
        button_2 = QPushButton("Show Message 2")

        mainLayout.addWidget(lineEdit_1)
        mainLayout.addWidget(button_1)
        mainLayout.addWidget(lineEdit_2)
        mainLayout.addWidget(button_2)

        button_1.clicked.connect(lambda state, \
                                 msg=self.mainWidget.layout().itemAt(0).widget().text(), \
                                 srcIndex=0: self.showMessage(msg, srcIndex))
        button_2.clicked.connect(lambda state, \
                                 msg=self.mainWidget.layout().itemAt(2).widget().text(), \
                                 srcIndex=2: self.showMessage(msg, srcIndex))

        self.setCentralWidget(self.mainWidget)
        self.show()

    def showMessage(self, message, srcIndex):
        print("Debug Print (%d): %s" % (srcIndex, self.mainWidget.layout().itemAt(srcIndex).widget().text()))
        msgBox = QMessageBox()
        msgBox.setWindowTitle("Message")
        msgBox.setIcon(QMessageBox.Information)
        msgBox.setText("\"" + str(message) + "\"")
        msgBox.setStandardButtons(QMessageBox.Yes)
        rtnVal = msgBox.exec()

if __name__ == "__main__":
    app = QApplication(sys.argv)
    GUI = Window()
    sys.exit(app.exec_())

enter image description here

I did check the following entry but I do not think it solves my problem:

mak
  • 197
  • 9

1 Answers1

2

The next:

button_1.clicked.connect(lambda state, \
                                 msg=self.mainWidget.layout().itemAt(0).widget().text(), \
                                 srcIndex=0: self.showMessage(msg, srcIndex))

equals:

msg=self.mainWidget.layout().itemAt(0).widget().text()
srcIndex=0
button_1.clicked.connect(lambda state, msg=msg, srcIndex=srcIndex: self.showMessage(msg, srcIndex))

In reality you are passing the text when the window is being built and not the text that you have when the button is pressed.

The best thing is to create an intermediate function that gets the text:

    button_1.clicked.connect(lambda state, lineedit=lineEdit_1: self.foo(lineedit))
    button_2.clicked.connect(lambda state, lineedit=lineEdit_2: self.foo(lineedit))

def foo(self, lineedit):
    self.showMessage(lineedit.text())

def showMessage(self, message):
    msgBox = QMessageBox()
    msgBox.setWindowTitle("Message")
    msgBox.setIcon(QMessageBox.Information)
    msgBox.setText("\"" + str(message) + "\"")
    msgBox.setStandardButtons(QMessageBox.Yes)
    rtnVal = msgBox.exec()
eyllanesc
  • 235,170
  • 19
  • 170
  • 241
  • Thank you for the working code as well as your explanation for why the code did not work. I understand now. Lastly, thank you for editing my question. For you information, I changed part of my title and question due to wording error but it shouldn't change its meaning or the validity of your answer. I hope the changes are more clearer and for the better. – mak Sep 21 '21 at 09:56