0

I made a widget that prompts the user to browse and select a filepath. I would like to copy this filepath string such that I can keep the string once the first widget is closed. In this way, I can pass this string to other widgets that I have not yet coded.

The code snippet below will successfully prompt the user and will show the correct filepath via gui. But, the print statement outputs None instead of the filepath string. The print statement refers to the line print("\n .. FPATH:\n{}\n".format(file_selection_widget.fpath)). My question is: why is this happening? I tried changing self.close() from the inner scope to file_selection_widget.close() in the outer scope (in __main__), but this causes the user prompt to fail; I'm not sure what else could be wrong here.

import sys
from PyQt5 import QtWidgets #, QtGui, QtCore

class FileSelectionWidget(QtWidgets.QWidget):

    """
    This class allows the user to select the input
    data file to be read via gui.
    """

    def __init__(self, parent=None):
        self._fpath = None
        super().__init__(parent)
        button = QtWidgets.QPushButton("Click here and select the data file you want to read")
        button.clicked.connect(self.on_clicked)
        lay = QtWidgets.QVBoxLayout(self)
        lay.addWidget(button)

    @property
    def fpath(self):
        return self._fpath

    def on_clicked(self):
        self.prompt_input_file()
        self.prompt_verification()

    def prompt_input_file(self):
        fpath, _ = QtWidgets.QFileDialog.getOpenFileName(
            None, 'Select input file', '/home', '',
            options=QtWidgets.QFileDialog.DontUseNativeDialog)
        self._fpath = fpath
        self.close()

    def prompt_verification(self):
        alert = QtWidgets.QMessageBox()
        alert.setText('The input filepath you selected is: \n{}'.format(self.fpath)) # shows correct filepath
        alert.exec()

if __name__ == '__main__':

    ## initialize application
    app = QtWidgets.QApplication(sys.argv)

    ## select path of input data file
    file_selection_widget = FileSelectionWidget()
    file_selection_widget.show()

    print("\n .. FPATH:\n{}\n".format(file_selection_widget.fpath)) ## shows incorrect filepath

    ## ... back end loads data file and processes data
    ## ... more gui

    ## exit application
    sys.exit(app.exec_())
zeebeel
  • 15
  • 1
  • 4

1 Answers1

0

Try this:

import sys
from PyQt5 import QtWidgets #, QtGui, QtCore

class FileSelectionWidget(QtWidgets.QWidget):

    """
    This class allows the user to select the input
    data file to be read via gui.
    """

    def __init__(self, parent=None):
        self._fpath = None
        super().__init__(parent)
        button = QtWidgets.QPushButton("Click here and select the data file you want to read")
        button.clicked.connect(self.on_clicked)
        lay = QtWidgets.QVBoxLayout(self)
        lay.addWidget(button)

    @property
    def fpath(self):
        return self._fpath

    def on_clicked(self):
        self.prompt_input_file()
        self.prompt_verification()

    def prompt_input_file(self):
        fpath, _ = QtWidgets.QFileDialog.getOpenFileName(
            None, 'Select input file', '/home', '',
            options=QtWidgets.QFileDialog.DontUseNativeDialog)
        self._fpath = fpath
        print("Your Selected Path :\n{}\n".format(file_selection_widget.fpath)) ## shows incorrect filepath
        self.close()
        

    def prompt_verification(self):
        alert = QtWidgets.QMessageBox()
        alert.setText('The input filepath you selected is: \n{}'.format(self.fpath)) # shows correct filepath
        alert.exec()

if __name__ == '__main__':

    app = QtWidgets.QApplication(sys.argv)
    file_selection_widget = FileSelectionWidget()
    file_selection_widget.show()
    sys.exit(app.exec_())
Dhurjati Riyan
  • 116
  • 1
  • 3
  • 13
  • I understand that putting the `print` statement in the application loop before running `self.close()` will work. Thank you for showing an example of this. But, my question is about how to *pass* this string to the outer scope (where it can be printed) or to another widget. Otherwise, [this solution](https://stackoverflow.com/questions/6784084/how-to-pass-arguments-to-functions-by-the-click-of-button-in-pyqt/38777350#38777350) will also print. – zeebeel Apr 25 '21 at 10:20