Modify text in QLineEdit when modifying the value of an instance variable / attribute

0

I'm trying to send the value of QLineEdit from one module to another in another module at the press of a button, but it does not work (just do not change the text in the second QLineEdit ).

This is my code:

Module1

from PyQt5.QtWidgets import QMainWindow, QApplication
from PyQt5 import uic
from main2 import Main2

class Main(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)
        uic.loadUi("main1.ui",self)


        self.otra = Main2()
        self.boton.clicked.connect(self.dato)

    def dato(self):
        self.otra.variable = self.lineEdit_0.text()
        self.otra.show()



app= QApplication([])
m = Main()
m.show()
app.exec_()

Main2

from PyQt5.QtWidgets import QMainWindow, QApplication
from PyQt5 import uic


class Main2(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)
        uic.loadUi("main2.ui",self)

        self.variable = None
        self.lineEdit.setText(self.variable)




#app= QApplication([])
#m = Main()
#m.show()
#app.exec_()
    
asked by Mystic_Force 13.08.2018 в 06:34
source

1 answer

3

First, you really do not want to "send value to a variable in another module", what you want is to modify an instance attribute of an object whose class is defined in another module. It really does not matter where the class is defined, the important thing is the otra object that instances from it.

The problem is that you assign as text of QLineEdit the value of variable in only in __init__ , this means that when you instantiate the class with self.otra = Main2() during the initialization of it the text of QlineEdit pass to be the value of self.variable at this time, but this does not create any link between the two, if after you change self.variable the text of QlineEdit will not change.

You could simply modify the text of QLineEdit of otra directly:

self.otra.lineEdit.setText(self.lineEdit_0.text())

But if you want to use an instance attribute, the solution is to use a property that allows you to modify the QLineEdit when you assign a new value to it in the "setter":

import sys
from PyQt5 import QtCore, QtGui, QtWidgets



class Main2(QtWidgets.QMainWindow):

    def __init__(self):
        super().__init__()
        self.resize(300, 200)
        self.centralwidget = QtWidgets.QWidget(self)
        self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
        self.lineEdit.setGeometry(QtCore.QRect(20, 84, 260, 32))
        self.setCentralWidget(self.centralwidget)

        self._variable = None  # Variable "privada", de uso interno.

    @property
    def variable(self):
        return self._variable

    @variable.setter
    def variable(self, text):
        self._variable = text
        self.lineEdit.setText(text)


class Main(QtWidgets.QMainWindow):

    def __init__(self):
        super().__init__()
        self.resize(800, 600)
        self.centralwidget = QtWidgets.QWidget(self)
        self.boton = QtWidgets.QPushButton(self.centralwidget, text="Aceptar")
        self.boton.setGeometry(QtCore.QRect(370, 280, 88, 34))
        self.lineEdit_0 = QtWidgets.QLineEdit(self.centralwidget)
        self.lineEdit_0.setGeometry(QtCore.QRect(210, 240, 411, 32))
        self.setCentralWidget(self.centralwidget)

        self.otra = Main2()
        self.boton.clicked.connect(self.dato)

    def dato(self):
        self.otra.variable = self.lineEdit_0.text()
        self.otra.show()



if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    m = Main()
    m.show()
    sys.exit(app.exec_())

You could even create your own signal and issue it when the attribute is modified, signal that you can connect to the slots you want later:

import sys
from PyQt5 import QtCore, QtGui, QtWidgets



class Main2(QtWidgets.QMainWindow):

    variable_changed = QtCore.pyqtSignal()

    def __init__(self):
        super().__init__()
        self.resize(300, 200)
        self.centralwidget = QtWidgets.QWidget(self)
        self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
        self.lineEdit.setGeometry(QtCore.QRect(20, 84, 260, 32))
        self.setCentralWidget(self.centralwidget)

        self._variable = None  
        self.variable_changed.connect(self.on_changed)

    @property
    def variable(self):
        return self._variable

    @variable.setter
    def variable(self, text):
        self._variable = text
        self.variable_changed.emit()

    @QtCore.pyqtSlot()
    def on_changed(self):
        self.lineEdit.setText(self._variable)

However, the association is not reciprocal, that is, if a value is reassigned to the attribute the content of the QlineEdit changes, but if the QLineEdit is modified the attribute is not modified. If you want this to happen, you should connect the signal textChanged to a slot that takes care of properly modify the attribute, one possibility is:

import sys
from PyQt5 import QtCore, QtGui, QtWidgets



class Main2(QtWidgets.QMainWindow):

    def __init__(self):
        super().__init__()
        self.resize(300, 200)
        self.centralwidget = QtWidgets.QWidget(self)
        self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
        self.lineEdit.setGeometry(QtCore.QRect(20, 84, 260, 32))
        self.setCentralWidget(self.centralwidget)

        self._variable = None  # Variable "privada", de uso interno.
        self.lineEdit.textChanged.connect(self._lineEdit_changed)

    @property
    def variable(self):
        return self._variable

    @variable.setter
    def variable(self, text):
        self.lineEdit.setText(text)

    @QtCore.pyqtSlot()    
    def _lineEdit_changed(self):
        self._variable = self.lineEdit.text()

Main2 is defined in the same module to facilitate the reproduction but as commented it is irrelevant that it is declared in another module and the amounts. You should not confuse the concept of module with the concepts of class and instance of class / object belonging to the paradigm of object-oriented programming. A rough module is just a file that allows storing code and structuring our application. In a module we can define multiple functions, classes, variables, etc. and we can execute it directly as a script or import it into another module to reuse the code defined in it.

    
answered by 13.08.2018 / 12:25
source