Search code examples
backgroundcommandpython-idlemultiprocess

Run Python with IDLE on a Windows machine, put a part of the code on background so that IDLE is still active to receive command


class PS():

    def __init__(self):
          self.PSU_thread=Process(target=self.read(199),)
          self.PSU_thread.start()

    def read():
         while running:
              "read the power supply"

    def set(current):
          "set the current"


if __name__ == '__main__':
    p=PS()

Basically the idea of the code is to read the data of the power supply and at the same time to have the IDLE active and can accept command to control it set(current). The problem we are having is once the object p is initialized, the while loop will occupy the IDLE terminal such that the terminal cannot accept any command any more.

We have consider to create a service, but does it mean we have to make the whole code into a service?

Please suggest me any possible solutions, we want it to run but still be able to receive my command from IDLE.


Solution

  • Idle, as its name suggests, is a program development environment. It is not meant for production running, and you should not use it for that, especially not for what you describe. Once you have a program written, just run it with Python.

    It sounds like what you need is a gui program, such as one based on tkinter. Here is a simulation of what I understand you to be asking for.

    import random
    import tkinter as tk
    
    root = tk.Tk()
    
    psu_volts = tk.IntVar(root)
    tk.Label(root, text='Mock PSU').grid(row=0, column=0)
    psu = tk.Scale(root, orient=tk.HORIZONTAL, showvalue=0, variable=psu_volts)
    psu.grid(row=0, column=1)
    
    def drift():
        psu_volts.set(psu_volts.get() + random.randint(0, 8) - 4)
        root.after(200, drift)
    drift()
    
    volts_read=tk.IntVar(root)
    tk.Label(root, text='PSU Volts').grid(row=1, column=0)
    tk.Label(root, textvariable=volts_read).grid(row=1, column=1)
    
    def read_psu():
        volts_read.set(psu_volts.get())
        root.after(2000, read_psu)
    read_psu()
    
    lb = tk.Label(root, text="Enter 'from=n' or 'to=n', where n is an integer")
    lb.grid(row=2, column=0, columnspan=2)
    envar = tk.StringVar()
    entry = tk.Entry(textvariable=envar)
    entry.grid(row=3, column=0)
    def psu_set():
        try:
            cmd, val = envar.get().split('=')
            psu[cmd.strip()] = val
            psu_volts.set((psu['to']-psu['from'])//2)
        except Exception:
            pass
        envar.set('')
    tk.Button(root, text='Change PSU', command=psu_set).grid(row=3, column=1)
    
    root.mainloop()
    

    Think of psu as a 'black box' and psu_volts.get and .set as the means of interacting with the box. You would have to substitute your in read and write code. Copy and save to a file. This either run it with Python or open in Idle to change it and run it.