Péter Leéh
Péter Leéh

Reputation: 2119

How can I share data between classes in PyQt?

In my PyQt5 Application I want to add an Import data window in order to make sure delimiter, skiprows, etc.. is correctly set before trying to import data from a file. Obviously I want this to happen in a separate window. I'm not going to post the full code there, just a quick example which is similar.

In this example there are two windows: the main and the import window. I'd like to send simple text from import window to mainwindow. My problem is I can't really access the created instance of MainWindow, because that happens in main.py. Here is the code:

main.py

import sys
from logic import MainProgram
from PyQt5 import QtWidgets

def main():
    app = QtWidgets.QApplication(sys.argv)
    my_interface = MainProgram()
    my_interface.show()
    sys.exit(app.exec_())

if __name__ == "__main__":
    main()

logic.py

from PyQt5.QtWidgets import QFileDialog
from PyQt5 import QtWidgets, QtCore

from mainwindow_ui import Ui_MainWindow
from import_ui import Ui_ImportPage

class MainProgram(QtWidgets.QMainWindow, Ui_MainWindow):

    def __init__(self, parent=None):
        super(MainProgram, self).__init__(parent)
        self.setupUi(self)
        self.open.clicked.connect(self.open_import_page)

    def open_import_page(self):
        self.window1 = ImportPage(self)
        self.window1.show()


class ImportPage(QtWidgets.QMainWindow, Ui_ImportPage):
    def __init__(self, parent=None):
        super(ImportPage, self).__init__(parent)
        self.setupUi(self)
        self.get.clicked.connect(self.get_text)

    def get_text(self):
        print(self.line.text()) # <--- this is want I want to send back to MainProgram class

if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    my_interface = MainProgram()
    my_interface.show()
    sys.exit(app.exec_())

mainwindow_ui.py

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(800, 600)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
        self.verticalLayout.setObjectName("verticalLayout")
        self.open = QtWidgets.QPushButton(self.centralwidget)
        self.open.setObjectName("open")
        self.verticalLayout.addWidget(self.open)
        self.line2 = QtWidgets.QLineEdit(self.centralwidget)
        self.line2.setPlaceholderText('Recieved from import page')
        self.verticalLayout.addWidget(self.line2)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 26))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.open.setText(_translate("MainWindow", "Open import page"))


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

import_ui.py

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_ImportPage(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("Import")
        MainWindow.resize(800, 600)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
        self.verticalLayout.setObjectName("verticalLayout")
        self.get = QtWidgets.QPushButton('Send data to MainWindow', self.centralwidget)
        self.verticalLayout.addWidget(self.get)
        self.line = QtWidgets.QLineEdit(self.centralwidget)
        self.line.setObjectName("open")
        self.line.setPlaceholderText('Type here what you want to send to MainWindow')
        self.verticalLayout.addWidget(self.line)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 26))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "Import"))

if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_ImportPage()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

Should I change the structure of the code to achieve this? Is there anything I'm missing? Thank you for answering.

Upvotes: 1

Views: 705

Answers (1)

eyllanesc
eyllanesc

Reputation: 243947

You can access the ImportPage instance in MainProgram as you create it in that scope. So you should make the necessary connections and get the text:

class MainProgram(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super(MainProgram, self).__init__(parent)
        self.setupUi(self)
        self.open.clicked.connect(self.open_import_page)
        self.window1 = ImportPage(self)
        self.window1.get.clicked.connect(self.on_clicked)

    def open_import_page(self):
        self.window1.show()

    def on_clicked(self):
        print(self.window1.line.text())

Upvotes: 1

Related Questions