0

The problem:

I would like to use this with an ESP32, to automate cli insructions. I have two buttons, the "Lets Go!!" button and the "Connect" button. "Connect" triggers def run which triggers def test and the command "rfq tty -P /dev/ttyUSB0", which will have some output displayed in the text box. I would like to use "Lets Go!!" to issue commands to that same thread/instance since it will be connected to the ESP32 with the "Connect" button.

Other:

I was able to adapt the terminal output found here (Redirect terminal output to tkinter). This is a work in progress, so the combo boxes don't trigger anything at this point. In the future I would like to .get() their values, and pass them as strings via the "Connect" button above.

Thank you for any help. Here is my code:

import tkinter as tk
from tkinter import messagebox, ttk
import sys
import subprocess
import threading 

# --- classes ---

class Redirect():

    def __init__(self, widget, autoscroll=True):
        self.widget = widget
        self.autoscroll = autoscroll

    def write(self, text):
        self.widget.insert('end', text)
        if self.autoscroll:
            self.widget.see("end")  # autoscroll

# --- functions ---

def run():
    threading.Thread(target=test).start()

def test():

    p = subprocess.Popen("rfq tty -P /dev/ttyUSB0".split(), stdout=subprocess.PIPE, bufsize=1, text=True)
    while p.poll() is None:
        msg = p.stdout.readline().strip() # read a line from the process output
        if msg:
            print(msg)

# --- main ---    

root = tk.Tk()

# - Frame with Text
width= root.winfo_screenwidth()
height= root.winfo_screenheight()
root.geometry("%dx%d" % (width, height))

frame = tk.Frame(root)
frame.pack(expand=True, fill='both')

serial = tk.Text(frame, width=50, height=1)
serial.place(x=48, y=7)

txrx = ttk.Combobox(
        frame,
        state="readonly",
        values=["Tx", "Rx"]
    )

txrx.place(x=50, y=50)
rxtxlabel= tk.Label(frame, text="Tx/Rx")
rxtxlabel.place(in_=txrx, relx=0, x=0, rely=1.5)

freq = ttk.Combobox(
        frame,
        state="readonly",
        values=["315","433","868"]
    )
freq.place(in_=txrx, relx=1.0, x=20, rely=0)
freqlabel= tk.Label(frame, text="Freq")
freqlabel.place(in_=freq, relx=0, x=0, rely=1)

mod = ttk.Combobox(
        frame,
        state="readonly",
        values=["OOK","2-FSK","4-FSK", "MSK"]
    )
mod.place(in_=freq, relx=1.0, x=20, rely=0)
modlabel= tk.Label(frame, text="Modulation")
modlabel.place(in_=mod, relx=0, x=0, rely=1)

text = tk.Text(frame, width=width, height=20)
text.place(x=0, y=300)

old_stdout = sys.stdout    
sys.stdout = Redirect(text)

# - rest -

button = tk.Button(root, text='Lets Go!!', command=run)
button.place(in_=mod, relx=1, x=0, rely=0, y=210)

button = tk.Button(root, text='connect', command=run)
button.place(in_=serial, relx=1, x=10, rely=0, y= -4)

root.mainloop()

# - after close window -

sys.stdout = old_stdout
  • I may have gotten it? I changed Def Test to Def Test (variable) and put the variable as a string in the input of the function. For Def run since it will be only used at the start I hardcoded the string in target=test(variable) since the thread starts test. I may go back and use a .get to establish that string. For the Connect button it goes through both run and test. For lets go I passed a string to only test(variable). I get output from both test sources using ping as a tester. I am unsure if it is in the same instance. I assume so but I need to get my esp together to test. – Swordfish II Jan 23 '23 at 00:47
  • Putting the .get in from the text box was stupid easy. – Swordfish II Jan 23 '23 at 02:20

1 Answers1

0

This works as tested with ping on both buttons. I am unsure if they are in the same instance though. I need to put together my esp32 setup to really test.

import tkinter as tk
from tkinter import messagebox, ttk
import sys
import subprocess
import threading 

# --- classes ---

class Redirect():

    def __init__(self, widget, autoscroll=True):
        self.widget = widget
        self.autoscroll = autoscroll

    def write(self, text):
        self.widget.insert('end', text)
        if self.autoscroll:
            self.widget.see("end")  # autoscroll

# --- functions ---

def run():
    text = serial.get(1.0, "end-1c")
    threading.Thread(target=test("%s" % text)).start()
    
def test(variable):
    
    p = subprocess.Popen(("%s" % variable).split(), stdout=subprocess.PIPE, bufsize=1, text=True)
    while p.poll() is None:
        msg = p.stdout.readline().strip() # read a line from the process output
        if msg:
            print(msg)

# --- main ---    

root = tk.Tk()

# - Frame with Text
width= root.winfo_screenwidth()
height= root.winfo_screenheight()
root.geometry("%dx%d" % (width, height))

frame = tk.Frame(root)
frame.pack(expand=True, fill='both')

serial = tk.Text(frame, width=50, height=1)
serial.place(x=48, y=7)

txrx = ttk.Combobox(
        frame,
        state="readonly",
        values=["Tx", "Rx"]
    )

txrx.place(x=50, y=50)
rxtxlabel= tk.Label(frame, text="Tx/Rx")
rxtxlabel.place(in_=txrx, relx=0, x=0, rely=1.5)

freq = ttk.Combobox(
        frame,
        state="readonly",
        values=["315","433","868"]
    )
freq.place(in_=txrx, relx=1.0, x=20, rely=0)
freqlabel= tk.Label(frame, text="Freq")
freqlabel.place(in_=freq, relx=0, x=0, rely=1)

mod = ttk.Combobox(
        frame,
        state="readonly",
        values=["OOK","2-FSK","4-FSK", "MSK"]
    )
mod.place(in_=freq, relx=1.0, x=20, rely=0)
modlabel= tk.Label(frame, text="Modulation")
modlabel.place(in_=mod, relx=0, x=0, rely=1)

text = tk.Text(frame, width=width, height=20)
text.place(x=0, y=300)

old_stdout = sys.stdout    
sys.stdout = Redirect(text)

# - rest -

button = tk.Button(root, text='Lets Go!!', command=lambda: test('ping -c 4 google.com'))
button.place(in_=mod, relx=1, x=0, rely=0, y=210)

button = tk.Button(root, text='connect', command=run)
button.place(in_=serial, relx=1, x=10, rely=0, y= -4)

root.mainloop()

# - after close window -

sys.stdout = old_stdout
  • 1
    Users find it difficult to understand code only answers with no explanation. Please add some description explaining what is does and how it solves the problem or add comments in the source code at appropriate places. – Azhar Khan Jan 24 '23 at 06:06