Python Forum
run executable in separate process thread
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
run executable in separate process thread
#1
I want to be able to call and run an executable in a separate thread so when running it the Python GUI application does not freeze up.

I'm not sure how to do this.

I have a single button on my gui form for testing called buttonLaunch which when clicked will call a module named 'Launch'. My sample code is below. How can I get the executable to run in separate thread?

#!/usr/bin/python3

#OoeyGUI MESS v2.0
#Copyright 2015 - 2019
#Chris Schneider [SHIFT838]
#http://shift838.99er.net

import os
import os.path
import sys
import subprocess
import serial.tools.list_ports
import xml.etree.ElementTree as ET
import platform

from PyQt5.QtCore import QThread, pyqtSignal
from PyQt5 import QtCore, QtGui, QtWidgets, QtSerialPort, uic
from PyQt5.QtWidgets import QFileDialog, QMessageBox, QInputDialog, QLineEdit
from os import path

LOCAL_DIR = os.path.dirname(os.path.realpath(__file__)) + "/"

class Main(QtWidgets.QMainWindow):

    def __init__(self):

        super().__init__()

        self.ui = uic.loadUi(LOCAL_DIR + "test.ui", self)
        self.ui.buttonLaunch.clicked.connect(self._Launch)

        self.show()

    def _Launch(self, clicked):
        os.system("java -jar c:/tiimagetool/tiimagetool.jar")
		
if __name__ == '__main__':

    ogv = "2.0 BETA Build 012919"

    app = QtWidgets.QApplication([])
    gui = Main()
    gui.setWindowTitle("OoeyGUI Mess v" + ogv)
    gui.show()
    sys.exit(app.exec_())

guess I should have searched a bit harder. I was able to use subprocess.Popen(executabe here)
SHIFT838
http://shift838.99er.net

Telnet BBS:
fusionbbs.ddns.net:9640
Reply
#2
With PyQt you should use QProcess instead of subprocess. It will automatically create a separate thread for the process. Here is an example if you want to monitor the output:

#!/usr/bin/python3
import sys
from PyQt5 import QtWidgets, QtCore


class Slave(QtCore.QProcess):
    def __init__(self, parent=None):
        super().__init__()
        self.readyReadStandardOutput.connect(self.stdoutEvent)
        self.readyReadStandardError.connect(self.stderrEvent)

    def stdoutEvent(self):
        stdout = self.readAllStandardOutput()
        self.echo(stdout)

    def stderrEvent(self):
        stderr = self.readAllStandardError()
        self.echo(stderr)

    def echo(self, data):
        data = bytes(data).decode("utf8")
        if data:
            print(data, end="")


class Main(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        self.slave = Slave()
        self.slave.start("/home/user/my_process")


if __name__ == '__main__':
    app = QtWidgets.QApplication([])
    gui = Main()
    sys.exit(app.exec_())
Else, it can be as simple as

self.process = QtCore.QProcess()
self.process.start("command")
# or
self.process.startDetached("command")
With start() you can add blocking call (waitForFinished) and monitor the process state(). With startDetached(), it returns a boolean to tell if the process could be launched or not.
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020