Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for Python
  4. How to access a value (global) from another file?
QtWS25 Last Chance

How to access a value (global) from another file?

Scheduled Pinned Locked Moved Unsolved Qt for Python
qt for pythonpython
12 Posts 2 Posters 1.1k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • D Offline
    D Offline
    Dara1
    wrote on last edited by
    #1

    Hello, I would like to have a program that is split into three files: 1. Main file with the entire layout and connections; 2. Worker file; 3. File where the output of the Worker file is called (and later plotted).

    How can I access the output of the worker file if my program is structured like this?

    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)
                params = ['dummy_script2.py', 'PATH_TO_THE_FILE']
                self.p.start("python", params)
    
        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
    import sys
    
    
    def run(filePath):
        global x
        count =0
        while True:
            count = count + 1
            x = 2*count
            return x
            time.sleep(1)
    
    run(sys.argv[1])
    

    call_output.py:

    from dummy_script2.py import *
    print(x)
    

    I would be happy to receive any tips and help!

    JonBJ 1 Reply Last reply
    0
    • D Dara1

      Hello, I would like to have a program that is split into three files: 1. Main file with the entire layout and connections; 2. Worker file; 3. File where the output of the Worker file is called (and later plotted).

      How can I access the output of the worker file if my program is structured like this?

      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)
                  params = ['dummy_script2.py', 'PATH_TO_THE_FILE']
                  self.p.start("python", params)
      
          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
      import sys
      
      
      def run(filePath):
          global x
          count =0
          while True:
              count = count + 1
              x = 2*count
              return x
              time.sleep(1)
      
      run(sys.argv[1])
      

      call_output.py:

      from dummy_script2.py import *
      print(x)
      

      I would be happy to receive any tips and help!

      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by
      #2

      @Dara1
      What is " the output of the worker file"? You talk about "How to access a value (global) from another file?". If you mean the global x you have in dummy_script2.py then given that you execute that script as a separate process (Qt QProcess, would be same if you used Python calls to run it) there is no chance of actually accessing any variables in the script.

      • Either bring your Python script's code directly into your PyQt project so you can access things from there;
      • Or if you run a subprocess let it output whatever you want back and you can read and parse that via the connections you already have to subprocess's stdout/stderr. Or you could do some other kind of IPC, like sockets, but stdout/err seems fine here.
      D 2 Replies Last reply
      2
      • JonBJ JonB

        @Dara1
        What is " the output of the worker file"? You talk about "How to access a value (global) from another file?". If you mean the global x you have in dummy_script2.py then given that you execute that script as a separate process (Qt QProcess, would be same if you used Python calls to run it) there is no chance of actually accessing any variables in the script.

        • Either bring your Python script's code directly into your PyQt project so you can access things from there;
        • Or if you run a subprocess let it output whatever you want back and you can read and parse that via the connections you already have to subprocess's stdout/stderr. Or you could do some other kind of IPC, like sockets, but stdout/err seems fine here.
        D Offline
        D Offline
        Dara1
        wrote on last edited by
        #3

        @JonB "If you mean the global x you have in dummy_script2.py" - I meant exactly this (global x)

        • Either bring your Python script's code directly into your PyQt project so you can access things from there; - this script is quite long and I want to avoid mixing everything together...
        • Or if you run a subprocess let it output whatever you want back and you can read and parse that via the connections you already have to subprocess's stdout/stderr. Or you could do some other kind of IPC, like sockets, but stdout/err seems fine here. - I actually print an output (to check if everything is working correctly) and I didn't even think about using it this way. I just tested it and it works as expected.

        Thank you very much for the help :)

        1 Reply Last reply
        0
        • JonBJ JonB

          @Dara1
          What is " the output of the worker file"? You talk about "How to access a value (global) from another file?". If you mean the global x you have in dummy_script2.py then given that you execute that script as a separate process (Qt QProcess, would be same if you used Python calls to run it) there is no chance of actually accessing any variables in the script.

          • Either bring your Python script's code directly into your PyQt project so you can access things from there;
          • Or if you run a subprocess let it output whatever you want back and you can read and parse that via the connections you already have to subprocess's stdout/stderr. Or you could do some other kind of IPC, like sockets, but stdout/err seems fine here.
          D Offline
          D Offline
          Dara1
          wrote on last edited by
          #4

          @JonB is there a way (and if it is safe enough for the program) to redirect the stdout to another file? Suppose, I want to have a real-time plot using this value?

          JonBJ 1 Reply Last reply
          0
          • D Dara1

            @JonB is there a way (and if it is safe enough for the program) to redirect the stdout to another file? Suppose, I want to have a real-time plot using this value?

            JonBJ Offline
            JonBJ Offline
            JonB
            wrote on last edited by JonB
            #5

            @Dara1
            Of course.

            Assuming you mean the stdout from your QProcess see void QProcess::setStandardOutputFile(const QString &fileName, QIODeviceBase::OpenMode mode = Truncate). Then the subprocess's stdout goes to file instead of to your readyReadStandardOutput.

            If you instead mean the redirecting the stdout of your host [not dummy_script2.py] Qt program (e.g. where its Python print() statements go) then that's different, so say if that is what you meant.

            D 1 Reply Last reply
            0
            • JonBJ JonB

              @Dara1
              Of course.

              Assuming you mean the stdout from your QProcess see void QProcess::setStandardOutputFile(const QString &fileName, QIODeviceBase::OpenMode mode = Truncate). Then the subprocess's stdout goes to file instead of to your readyReadStandardOutput.

              If you instead mean the redirecting the stdout of your host [not dummy_script2.py] Qt program (e.g. where its Python print() statements go) then that's different, so say if that is what you meant.

              D Offline
              D Offline
              Dara1
              wrote on last edited by
              #6

              @JonB Indeed, I mean if it is possible to redirect the output to call_output.py.

              Actually, I have a pyqtgraph which is also quite messy and I want to have it in a separate file. I don't know if that's a good idea as I already see how it slows down the speed of my app...

              JonBJ 1 Reply Last reply
              0
              • D Dara1

                @JonB Indeed, I mean if it is possible to redirect the output to call_output.py.

                Actually, I have a pyqtgraph which is also quite messy and I want to have it in a separate file. I don't know if that's a good idea as I already see how it slows down the speed of my app...

                JonBJ Offline
                JonBJ Offline
                JonB
                wrote on last edited by
                #7

                @Dara1
                I don't even know if/how/where you call call_output.py:. Atm your QProcess runs dummy_script2.py directly. If you change that to run call_output.py (is that what you intend?) then it's being run via QProcess and you can use setStandardOutputFile() (or readAllStandardOutput()) on that to grab the print(x) it executes.

                D 1 Reply Last reply
                0
                • JonBJ JonB

                  @Dara1
                  I don't even know if/how/where you call call_output.py:. Atm your QProcess runs dummy_script2.py directly. If you change that to run call_output.py (is that what you intend?) then it's being run via QProcess and you can use setStandardOutputFile() (or readAllStandardOutput()) on that to grab the print(x) it executes.

                  D Offline
                  D Offline
                  Dara1
                  wrote on last edited by
                  #8

                  @JonB I apologize a lot, I think I wasn't that much clear in explanation... I hope this sketch helps a bit. Unbenannt.png

                  So, I need all three files, where the information is passed from one to another. The plotting is done via pyqtgraph, which widget is embedded to the main.py file.

                  JonBJ 1 Reply Last reply
                  0
                  • D Dara1

                    @JonB I apologize a lot, I think I wasn't that much clear in explanation... I hope this sketch helps a bit. Unbenannt.png

                    So, I need all three files, where the information is passed from one to another. The plotting is done via pyqtgraph, which widget is embedded to the main.py file.

                    JonBJ Offline
                    JonBJ Offline
                    JonB
                    wrote on last edited by JonB
                    #9

                    @Dara1
                    Your picture is pretty :), but I'm afraid I have no clear idea of what you are really trying to do.

                    And just for example, I note you have a script, dummy_script2.py, which defines a method named run. That uses a global x, for no discernible reason much. It has a while True loop. Yet that has an unconditional return statement in it (not yield). So (a) it only runs through once, (b) the time.sleep(1) is never executed and (c) it simply always returns the value 2. That's it. And if you invoke call_output.py that will simply print(2). And call_output.py only executes run() once. And dummy_script2.py also takes a parameter of a file path which it does not use.

                    You will need to await someone else who understands what you are saying/trying to achieve.

                    All I will say is if the idea of (some combination of) dummy_script2.py and call_output.py is to produce a stream of points to plot, run a QProcess (with one or the other of them) which spits out the desired points to stdout and your main Qt program can read that output as it arrives and plot some points. [Maybe what you intend is that call_output.py repeatedly gets dummy_script2.py to generate some data returned from a function and call_output.py just print()s that to stdout? In which case you want QProcess to run call_output.py not dummy_script.py?] I don't know about either your file path or your global x. And if you run dummy_script2.py as a sub-process you cannot also somehow do call_output.py separately and have it access anything (like global x) from dummy_script.py.

                    D 1 Reply Last reply
                    0
                    • JonBJ JonB

                      @Dara1
                      Your picture is pretty :), but I'm afraid I have no clear idea of what you are really trying to do.

                      And just for example, I note you have a script, dummy_script2.py, which defines a method named run. That uses a global x, for no discernible reason much. It has a while True loop. Yet that has an unconditional return statement in it (not yield). So (a) it only runs through once, (b) the time.sleep(1) is never executed and (c) it simply always returns the value 2. That's it. And if you invoke call_output.py that will simply print(2). And call_output.py only executes run() once. And dummy_script2.py also takes a parameter of a file path which it does not use.

                      You will need to await someone else who understands what you are saying/trying to achieve.

                      All I will say is if the idea of (some combination of) dummy_script2.py and call_output.py is to produce a stream of points to plot, run a QProcess (with one or the other of them) which spits out the desired points to stdout and your main Qt program can read that output as it arrives and plot some points. [Maybe what you intend is that call_output.py repeatedly gets dummy_script2.py to generate some data returned from a function and call_output.py just print()s that to stdout? In which case you want QProcess to run call_output.py not dummy_script.py?] I don't know about either your file path or your global x. And if you run dummy_script2.py as a sub-process you cannot also somehow do call_output.py separately and have it access anything (like global x) from dummy_script.py.

                      D Offline
                      D Offline
                      Dara1
                      wrote on last edited by
                      #10

                      @JonB thank you very much :)

                      These are the parts of my real code...
                      main file

                      class MainWindow(QMainWindow):
                          def __init__(self):
                              super(MainWindow, self).__init__()
                              self.ui = Ui_MainWindow() <-- GUI loaded from another file
                              self.ui.setupUi(self)
                      
                          def start_process(self):
                              if self.p is None:
                                  self.p = QProcess()
                                  self.p.readyReadStandardOutput.connect(self.handle_stdout)
                                  params = ['file.py', arg1, arg2, arg3]
                                  self.p.start("python", params)
                      
                          def handle_stdout(self):
                              data = self.p.readAllStandardOutput()
                              stdout = bytes(data).decode("utf8")
                              self.message(stdout)
                      

                      and in plot_routine file I have:

                      class  CustomWidget(pg.GraphicsLayoutWidget):
                      this is a pyqtgraph class for plotting 
                          def __init__(self):
                                  pg.GraphicsLayoutWidget.__init__(self, **kargs)
                                  self.setParent(parent)
                                  self.setWindowTitle('pyqtgraph example: Scrolling Plots')   
                          
                          def plot_plot(self):
                              plot(stdout) 
                      
                      if __name__ == '__main__':
                          w = CustomWidget()
                          w.show()
                          QtWidgets.QApplication.instance().exec_()
                      

                      The question is how can I pass stdout value from main file to the plot_routine?

                      JonBJ 1 Reply Last reply
                      0
                      • D Dara1

                        @JonB thank you very much :)

                        These are the parts of my real code...
                        main file

                        class MainWindow(QMainWindow):
                            def __init__(self):
                                super(MainWindow, self).__init__()
                                self.ui = Ui_MainWindow() <-- GUI loaded from another file
                                self.ui.setupUi(self)
                        
                            def start_process(self):
                                if self.p is None:
                                    self.p = QProcess()
                                    self.p.readyReadStandardOutput.connect(self.handle_stdout)
                                    params = ['file.py', arg1, arg2, arg3]
                                    self.p.start("python", params)
                        
                            def handle_stdout(self):
                                data = self.p.readAllStandardOutput()
                                stdout = bytes(data).decode("utf8")
                                self.message(stdout)
                        

                        and in plot_routine file I have:

                        class  CustomWidget(pg.GraphicsLayoutWidget):
                        this is a pyqtgraph class for plotting 
                            def __init__(self):
                                    pg.GraphicsLayoutWidget.__init__(self, **kargs)
                                    self.setParent(parent)
                                    self.setWindowTitle('pyqtgraph example: Scrolling Plots')   
                            
                            def plot_plot(self):
                                plot(stdout) 
                        
                        if __name__ == '__main__':
                            w = CustomWidget()
                            w.show()
                            QtWidgets.QApplication.instance().exec_()
                        

                        The question is how can I pass stdout value from main file to the plot_routine?

                        JonBJ Offline
                        JonBJ Offline
                        JonB
                        wrote on last edited by JonB
                        #11

                        @Dara1
                        Maybe I'm missing the point, but stdout is just a string (Python str) variable, right? So either directly call a method in CustomWidget passing it as a parameter or maybe emit a signal with it as a parameter where there is a slot attaching that to a method in CustomWidget?

                        D 1 Reply Last reply
                        0
                        • JonBJ JonB

                          @Dara1
                          Maybe I'm missing the point, but stdout is just a string (Python str) variable, right? So either directly call a method in CustomWidget passing it as a parameter or maybe emit a signal with it as a parameter where there is a slot attaching that to a method in CustomWidget?

                          D Offline
                          D Offline
                          Dara1
                          wrote on last edited by
                          #12

                          @JonB thank you!
                          Sometimes it happens that everything gets mixed up in my head: Python, PyQt... and I'm no longer sure if I can do something straightforward. I'll try to call the method directly

                          1 Reply Last reply
                          0

                          • Login

                          • Login or register to search.
                          • First post
                            Last post
                          0
                          • Categories
                          • Recent
                          • Tags
                          • Popular
                          • Users
                          • Groups
                          • Search
                          • Get Qt Extensions
                          • Unsolved