Search code examples
pythonpyqtmenubarqlineedit

QLineEdit returns empty string


I'm trying to access the text written in a QLineEdit from another class, but it is returning an empty string.

Here is a minimalistic functional piece of code (Python 2.7):

import sys

from PyQt5 import QtWidgets, QtGui, QtCore
from PyQt5.QtWidgets import *

class MainWindow(QMainWindow):

    def __init__(self):
        super(MainWindow, self).__init__()

        self.createmenus()
        self.initui()

        self.central_widget = QStackedWidget()
        self.setCentralWidget(self.central_widget)

        testWidgets = Container0()
        self.central_widget.addWidget(testWidgets)

    def initui(self):
        self.setWindowTitle("TestWindow")
        self.show()

    def createmenus(self):
        viewFile = self.menuBar().addMenu("File")

        expMenu = QMenu("Export", self)
        expAct = QAction("Save", self)
        expMenu.addAction(expAct)

        expMenu.triggered[QAction].connect(self.export_config)

        viewFile.addMenu(expMenu)

    def export_config(self):
        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        fileName, _ = QFileDialog.getSaveFileName(self, "Save as", "C:/", "Text (*.txt);;All Files (*)",
                                              options=options)
        if fileName:
            Export().export(fileName)

class Container0(QWidget):
    def __init__(self):
        super(QWidget, self).__init__()

        self.mainlayout = QVBoxLayout(self)
        self.vbox_layout = QVBoxLayout()

        self.text1 = QLineEdit()
        print self.text1

        self.vbox_layout.addWidget(self.text1)
        self.mainlayout.addLayout(self.vbox_layout)

class Export():
    def export(self, path):
        tw = Container0()

        t1 = tw.text1
        t1text = t1.text()

        print t1
        print t1text
        print path

if __name__ == '__main__':
    app = QApplication([])
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())

About the code:

First of all I create my QMainWindow, which calls the functions initui and createmenus. In the next class Container0 I implement the QLineEdit widget. I separated the classes because the application I'm writing has several windows and a toolbar with "next" and "back" buttons, which change the centralWidget to the class I saved the window I want to display next. (I hope this wasnt't a bad idea)

What I want to achieve

Currently when I write something into the QLineEdit and then go to the Menu "File -> Export -> Save" and insert a path, the code calls the class Export and its function export, which should read the string I wrote in the QLineEdit and print it among the path. The problem is that my output from my QLineEdit is an empty string. Furthermore, the function Export seems to create another instance from the QLineEdit. Note the different memory locations when I call print self.text1:

<PyQt5.QtWidgets.QLineEdit object at 0x0000000002968B88>
<PyQt5.QtWidgets.QLineEdit object at 0x0000000002968DC8>
<PyQt5.QtWidgets.QLineEdit object at 0x0000000002968DC8>
                                                        ### <- This is the empty line
C:/123

This makes me wonder how I can call the QLineEdit string without creating another instance. Furthermore, is this a correct way to handle multiple windows?

TL,DR: QLineEdit returns an empty string. It should not. Suggestions about the code structure are also welcome. Thanks!


Solution

  • Each time you use the following expression:

    some_variable = Container0()
    

    you are creating a new container, so in your case the container created in the __init__ of MainWindow is different from the one created in the export method of Export. Therefore, even if you place text in the main window, there is no text in the other Container.

    The solution is to make testWidgets member of the class and pass the text content to export:

    import sys
    
    from PyQt5 import QtWidgets, QtGui, QtCore
    from PyQt5.QtWidgets import *
    
    class MainWindow(QMainWindow):
    
        def __init__(self):
            super(MainWindow, self).__init__()
    
            self.createmenus()
            self.initui()
    
            self.central_widget = QStackedWidget()
            self.setCentralWidget(self.central_widget)
    
            self.testWidgets = Container0()
            self.central_widget.addWidget(self.testWidgets)
    
        def initui(self):
            self.setWindowTitle("TestWindow")
            self.show()
    
        def createmenus(self):
            viewFile = self.menuBar().addMenu("File")
    
            expMenu = QMenu("Export", self)
            expAct = QAction("Save", self)
            expMenu.addAction(expAct)
    
            expMenu.triggered[QAction].connect(self.export_config)
    
            viewFile.addMenu(expMenu)
    
        def export_config(self):
            options = QFileDialog.Options()
            options |= QFileDialog.DontUseNativeDialog
            fileName, _ = QFileDialog.getSaveFileName(self, "Save as", "C:/", "Text (*.txt);;All Files (*)",
                                                  options=options)
            if fileName:
                Export().export(fileName, self.testWidgets.text1.text())
    
    class Container0(QWidget):
        def __init__(self):
            super(QWidget, self).__init__()
    
            self.mainlayout = QVBoxLayout(self)
            self.vbox_layout = QVBoxLayout()
    
            self.text1 = QLineEdit()
            print(self.text1)
    
            self.vbox_layout.addWidget(self.text1)
            self.mainlayout.addLayout(self.vbox_layout)
    
    class Export():
        def export(self, path, t1text):
            print(t1text)
            print(path)
    
    if __name__ == '__main__':
        app = QApplication([])
        window = MainWindow()
        window.show()
        sys.exit(app.exec_())