【问题标题】:使用 Tkinter(线程)打开 Notepad.exe
【发布时间】:2022-01-22 12:59:53
【问题描述】:

我正在尝试学习如何使用tkinter 进行线程化并遇到问题。我的主要计划是最终打开一个程序并利用热键浏览所述程序的菜单,以自动执行我正在执行的递归过程。我知道这不是最有效的方法,但这是唯一可用的方法是有原因的。

我目前正在尝试简单地编写一个记事本版本的代码,该代码将复制文本框用户输入字符串并将它们输入到记事本中。我听说我将需要使用线程来完成我的最终项目,但显然我没有正确地做某事,因为一旦记事本打开程序就不会继续。下面是代码:

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()

【问题讨论】:

    标签: python multithreading tkinter


    【解决方案1】:
    subprocess.call
    

    blocking function,因为它会等待它完成,在这种情况下,这意味着它会等到您关闭记事本后再继续进行自动化操作。

    你可能想要使用

    subprocess.Popen
    

    因为它在新进程中执行子程序,这意味着它将打开记事本,然后继续自动化。

    对于您的情况,您真的只需要将 call 更改为 Popen,这实际上是唯一需要的更改。

    有用:

    【讨论】:

    • 太棒了!非常感谢您提供的所有信息。你知道是否有理由调用程序而不是使用 Popen?
    • @Bear 没有理由使用call,因为它是older API,上面写着:您现在可以在许多情况下使用run(),但是很多现有代码调用这些函数。所以你可能真的想使用run。什么时候? Here 它说 调用子进程的推荐方法是对它可以处理的所有用例使用 run() 函数。对于更高级的用例,可以直接使用底层的 Popen 接口。 1/2
    • 而且这种情况更先进,因为不需要阻塞。同样看似run 本身使用Popen 反正因为它是The underlying process creation and management in this module,所以真的Popen 可以在任何情况下使用,但只建议使用run(“较新的”call)可能的。有关更详细的信息,我建议您阅读文档。如果您能接受答案是正确的,那也太好了。谢谢! 2/2
    • 很好的信息。非常感谢!
    猜你喜欢
    • 2019-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-13
    • 2019-05-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多