I'm trying to learn how to thread using tkinter
and running into issues. My main plan is to eventually open a program and utilize hotkeys to navigate through the menus of said program to automate a recursive process I'm doing. I understand this isn't the most efficient way to do this, but there are reasons why this is the only available approach.
I'm trying at the moment to simply write a notepad version of the code that will copy the textbox user entry strings and type them into notepad. I've heard I will need to use threading to do my final project, but clearly I'm not doing something correctly as once notepad opens the program doesn't proceed. Below is the code:
import subprocess
from tkinter import *
import time
import threading
from threading import Thread
"""Sleep function"""
def SleepSec(var):
time.sleep(var)
"""Hotkey function runs hotkeys to take measurement"""
def Notepad_Test():
mouse = pynput.mouse.Controller()
key = pynput.keyboard.Controller()
"""Open notepad program"""
subprocess.call(['C:\\Windows\\System32\\notepad.exe'],shell=True)
SleepSec(5)
"""Click on program window"""
mouse.position = (400,400)
mouse.click(pynput.mouse.Button.left, 1)
"""Sorting variables from inputs"""
intervalEntry = E1.get() #Interval time
dataEntry = dropVar.get() #RAW or Radiometric data
pathEntry = E2.get() #Path file
filenameEntry = E3.get() #filename
startNumEntry = E4.get() #Starting measurement number
countEntry = E5.get() #Number of measurements to take
commentEntry = E6.get() #Comments about measurement
SleepSec(1)
key.type(intervalEntry)
SleepSec(1)
key.press(pynput.keyboard.Key.enter.value)
SleepSec(1)
key.type(dataEntry)
SleepSec(1)
key.press(pynput.keyboard.Key.enter.value)
SleepSec(1)
key.type(pathEntry)
SleepSec(1)
key.press(pynput.keyboard.Key.enter.value)
SleepSec(1)
key.type(filenameEntry)
SleepSec(1)
key.press(pynput.keyboard.Key.enter.value)
SleepSec(1)
key.type(startNumEntry)
SleepSec(1)
key.press(pynput.keyboard.Key.enter.value)
SleepSec(1)
key.type(countEntry)
SleepSec(1)
key.press(pynput.keyboard.Key.enter.value)
SleepSec(1)
key.type(commentEntry)
SleepSec(1)
"""Create a GUI"""
root = Tk()
root.title('Measurement')
dropVar = StringVar(root)
options = [
"RAW",
"Radiometric"
]
dropVar.set(options[0])
"""Labels and entries for desired measurement parameters"""
L1 = Label(root, text = "Measurement Interval").grid(row = 0)
E1 = Entry(root, bd = 5)
E1.insert(10,"1")
E1.grid(row=0,column=1)
L2 = Label(root, text = "Pathname").grid(row = 1)
E2 = Entry(root, bd = 5)
E2.insert(10,"C:/Users/ASD User/Documents/ASD_data/test")
E2.grid(row=1,column=1)
L3 = Label(root, text = "Filename").grid(row = 2)
E3 = Entry(root, bd = 5)
E3.insert(10,"DefaultFilename")
E3.grid(row=2,column=1)
L4 = Label(root, text = "Measurement #").grid(row = 3)
E4 = Entry(root, bd = 5)
E4.insert(10,"0")
E4.grid(row=3,column=1)
L5 = Label(root, text = "Number of files to save").grid(row = 4)
E5 = Entry(root, bd = 5)
E5.insert(10,"30")
E5.grid(row=4,column=1)
L6 = Label(root, text = "Comment").grid(row = 5)
E6 = Entry(root, bd = 5)
E6.insert(10,"Comment here")
E6.grid(row=5,column=1)
O1 = OptionMenu(root, dropVar, *options).grid(row = 6)
"""Buttons for running measurement and quitting"""
B1 = Button(root,
text = 'Quit',
command = root.quit).grid(row = 7,
column = 0,
sticky=W,
pady=4)
B2 = Button(root,
text = "Measure", command= lambda: threading.Thread(target = Notepad_Test).start()).grid(row=7,
column=1,
sticky=W,
pady=4)
root.mainloop()
CodePudding user response:
subprocess.call
Is a blocking function because it waits for it to finish which in this case means that it waits until you close notepad before proceeding on with the automation.
You probably want to use
subprocess.Popen
because it Executes a child program in a new process, meaning that it will open notepad and then continue on with the automation.
For your case you really just need to change call
to Popen
, that is literally the only change required.
Useful: