Sam
Sam

Reputation: 33

How to pass values from one window to another PyQT

I have a PyQT5 webscraper program that uses two windows. The second window is a config window in which you enter the url to scrape, however I have no idea how to actually return the url so the main window has access to it.

class SpiderConfWindow(QMainWindow, Ui_SpiderSettings):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.ui = Ui_SpiderSettings()
        self.ui.setupUi(self)
        self.ui.btnConfirm.clicked.connect(self.confirm)

    def confirm(self):
        return self.ui.entryUrl.text()


class MainWindow(QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.spider_conf_w = SpiderConfWindow()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.url = None
        self.ui.btnSpiderSettings.triggered.connect(self.spider_settings)

    def spider_settings(self):
        self.spider_conf_w.show()

I want SpiderConfWindow.confirm to set MainWindow's url attribute

Upvotes: 1

Views: 5977

Answers (1)

jfaccioni
jfaccioni

Reputation: 7509

The proper way to do send data across widgets is to use Qt's signals and slots mechanism.

Once you have everything appropriately hooked up, an event (like clicking SpiderConfWindow's button) will trigger the emission of a signal containing some data. This signal will be handled by a slot - likely a method in your MainWindow class that know how to deal with the data.

Since I don't have access to the code of your GUI, here's an alternative minimal example showcasing this behavior. The SubWindow widget spawns when clicking the button in the MainWindow widget, and then emits its submitClicked signal (a string) when the submit button is clicked. This signal is connected to the MainWindow's on_sub_window_confirm, which works as the slot that deals with the incoming data.

import sys

from PyQt5 import QtCore as qtc
from PyQt5 import QtWidgets as qtw


class SubWindow(qtw.QWidget):
    submitClicked = qtc.pyqtSignal(str)  # <-- This is the sub window's signal
    
    def __init__(self, parent=None):
        super().__init__(parent)
        layout = qtw.QVBoxLayout()
        self.setLayout(layout)
        self.line_edit = qtw.QLineEdit(placeholderText="Enter URL here:")
        self.btn = qtw.QPushButton("Submit")
        layout.addWidget(self.line_edit)
        layout.addWidget(self.btn)
        self.btn.clicked.connect(self.confirm)

    def confirm(self):  # <-- Here, the signal is emitted *along with the data we want*
        self.submitClicked.emit(self.line_edit.text())
        self.close()


class MainWindow(qtw.QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.sub_window = None  # placeholder attribute for the sub window
        layout = qtw.QVBoxLayout()
        self.setLayout(layout)
        self.label = qtw.QLabel("Current URL: None")
        self.btn = qtw.QPushButton("Get new URL...")
        layout.addWidget(self.label)
        layout.addWidget(self.btn)
        self.btn.clicked.connect(self.show_sub_window)

    def show_sub_window(self):  # <-- Here, we create *and connect* the sub window's signal to the main window's slot
        self.sub_window = SubWindow()
        self.sub_window.submitClicked.connect(self.on_sub_window_confirm)
        self.sub_window.show()
    
    def on_sub_window_confirm(self, url):  # <-- This is the main window's slot
        self.label.setText(f"Current URL: {url}")


if __name__ == "__main__":
    app = qtw.QApplication(sys.argv)
    gui = MainWindow()
    gui.show()
    sys.exit(app.exec_())

Upvotes: 5

Related Questions