Specify a file path from QFileDialog as another argument in QProcess?

Hello everyone! I would like to have a possibility to start and stop an imported file that contains a running loop (in fact, it contains a Python “threading” inside a while-loop). This imported file in turn requires input data/files. Here is a reproducible code:

from PyQt5.QtWidgets import (QApplication, QMainWindow, QPushButton, QPlainTextEdit,QVBoxLayout, QWidget, QProgressBar, QFileDialog)
from PyQt5.QtCore import QProcess
import sys
import re

progress_re = re.compile("Total complete: (\d+)%")

def simple_percent_parser(output):
    m = progress_re.search(output)
    if m:
        pc_complete = m.group(1)
        return int(pc_complete)


class MainWindow(QMainWindow):

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

        self.p = None

        self.btn = QPushButton("Execute")
        self.btn.pressed.connect(self.start_process)

        self.btn1 = QPushButton("Stop")
        self.btn1.pressed.connect(self.stop_process)

        self.dButton = QPushButton("Select a File")
        self.dButton.clicked.connect(self.getfile)


        self.text = QPlainTextEdit()
        self.text.setReadOnly(True)

        self.progress = QProgressBar()
        self.progress.setRange(0, 100)

        l = QVBoxLayout()
        l.addWidget(self.btn)
        l.addWidget(self.btn1)
        l.addWidget(self.dButton)
        l.addWidget(self.text)

        w = QWidget()
        w.setLayout(l)

        self.setCentralWidget(w)

    def message(self, s):
        self.text.appendPlainText(s)

    def start_process(self):
        if self.p is None:
            self.message("Executing process")
            self.p = QProcess()
            self.p.readyReadStandardOutput.connect(self.handle_stdout)
            self.p.readyReadStandardError.connect(self.handle_stderr)
            self.p.finished.connect(self.process_finished)
            self.p.start("python", ['dummy_script2.py'])

    def handle_stderr(self):
        data = self.p.readAllStandardError()
        stderr = bytes(data).decode("utf8")
        progress = simple_percent_parser(stderr)
        if progress:
            self.progress.setValue(progress)
        self.message(stderr)

    def handle_stdout(self):
        data = self.p.readAllStandardOutput()
        stdout = bytes(data).decode("utf8")
        self.message(stdout)

    def process_finished(self):
        self.message("Process finished.")
        self.p = None

    def stop_process(self):
        self.message("Process finished.")
        self.p = None


    def getfile(self):
        # global fileName
        filename = QFileDialog.getOpenFileName()
        fileName = filename[0]
        return fileName


app = QApplication(sys.argv)

w = MainWindow()
w.show()

app.exec_()

dummy_script2.py:

import time 


def run(filePath):
    count =0
    while True:
        count = count + 1
        print(count)
        print(filePath)
        time.sleep(1)


run(filePath)

So, I have no problem running the imported file (if it doesn’t require input) and getting the file path from QFileDialog. But I have a problem passing the path to that file. I will appreciate any tips and help!

Hi @Dara welcome to the forum!

To pass arguments into a process your options are either (1) passing them on the command line (as strings) (2) passing them in environment variables (also as strings) or (3) passing them via a file (e.g. serialized to JSON).

Since you’re passing a path, which is a string, I’d say #1 is the easiest option.

You can access command line arguments using sys.argv (after import sys) which gives a list of the arguments received. Modify your second script to add the following, as it will make it easier to debug.

import sys
print(sys.argv)

Then to pass arguments modify your main application to do the following.

self.p.start("python", ['dummy_script2.py', filePath])

… where filePath is the path you want to pass to your script. You’ll need to modify your main code to get that variable available at that point.

Once you do that, if you run it you should see the arguments being printed out as a list of strings. From there you can get the filepath argument with standard Python list operations e.g. getting the last argument with

filePath = sys.argv[-1]

Hope that helps!