[英]Writing a Python UI for a seperate program with tkinter. The stop button for this program basically freezes the UI and continues with the script
Here is what I coded...这是我编码的...
import tkinter as tk
import subprocess
import sys
import time
import os
import tkinter.font as font
from tkinter.ttk import *
app = tk.Tk()
app.geometry("400x400")
app.configure(bg='gray')
photo = tk.PhotoImage(file=r"C:\Users\ex\ex_button_active.png")
myFont = font.Font(family='Helvetica', size=20, weight='normal')
tk.Label(app, text='EX', bg='gray', font=(
'Verdana', 15)).pack(side=tk.TOP, pady=10)
app.iconbitmap(r'C:\Users\ex\ex_icon.ico')
start = time.time()
cmd = sys.executable + " -c 'import time; time.sleep(2)' &"
subprocess.check_call(cmd, shell=True)
assert (time.time() - start) < 1
p = subprocess.Popen(cmd, shell=True)
def ex_activation():
#Python Code
#Python Code...
def ex_stop():
sys.exit(ex_activation) #This area is basically where I have a button to terminate the other script running.
#I have tried sys.exit() and had the same result
ex_activation_button = tk.Button(app,
bg='black',
image=photo,
width=120,
height=120,
command=ex_activation)
ex_stop_button = tk.Button(app,
bg='Gray',
text='ex',
width=12,
command=ex_stop
height=3)
ex_stop_button['font'] = myFont
app.title("Example")
ex_activation_button.pack(side=tk.TOP)
ex_stop_button.pack(side=tk.LEFT)
app.mainloop()
I am looking for a way to get my program to stop the program the other button runs.我正在寻找一种方法让我的程序停止另一个按钮运行的程序。 I realized that this maybe be a "self destruct button" but I don't know how to do this with the script the other button runs.
我意识到这可能是一个“自毁按钮”,但我不知道如何使用另一个按钮运行的脚本来做到这一点。 Any help greatly appreciated!
非常感谢任何帮助! I tried killing the code by putting the
def ex_activation
in the p.kill This did not work...我尝试通过将
def ex_activation
放在 p.kill 中来杀死代码这不起作用......
If the other python script is made to run forever (has some kind of while True:
), you can't run it on the command line as you did, because it will freeze your window while that script is running.如果另一个 python 脚本永久运行(有某种
while True:
),您不能像以前那样在命令行上运行它,因为它会在该脚本运行时冻结您的 window。
In order to run a python script on background you will need to do it with the subprocess library.为了在后台运行 python 脚本,您需要使用子进程库来执行此操作。 (Find out here )
(在这里找到)
I also found an answer of another question that uses check_ouput()
in order to know when the python program has finished.我还找到了另一个问题的答案,该问题使用
check_ouput()
来了解 python 程序何时完成。 This can also be useful if you want to send a status to the tkinter app: you can print("33% Complete")
, for example.如果您想向 tkinter 应用程序发送状态,这也很有用:例如,您可以
print("33% Complete")
。 You could add this in tkinter's main loop, so you always know if your program is running or not.您可以将其添加到 tkinter 的主循环中,这样您就始终知道您的程序是否正在运行。
And last but not least, to kill that process (using the stop button), you should do it using os
, and looking for the subprocess' ID.最后但并非最不重要的一点是,要终止该进程(使用停止按钮),您应该使用
os
来执行此操作,并查找子进程的 ID。 Here you can also find a good example. 在这里你也可以找到一个很好的例子。
I would try something like this:我会尝试这样的事情:
cmd = "exec python file.py"
p = subprocess.Popen(cmd, shell=True)
# Continue running tkinter tasks.
tk.update()
tk.update_idletasks() # These both lines should be inside a while True
# Stop secondary program
p.kill()
EDIT编辑
Example code using your question's code.使用您的问题代码的示例代码。 WARNING: I have changed the png file location for testing, commented the app icon, and tested ONLY on Windows.
警告:我已更改用于测试的 png 文件位置,注释了应用程序图标,并且仅在 Windows 上进行了测试。
It's important to remove the mainloop()
on the main file and put update...()
in order to catch the keyboardInterrupt that (I don't know why) is killing both parent and child process.删除主文件上的
mainloop()
并放入update...()
以捕获键盘中断(我不知道为什么)正在杀死父进程和子进程,这一点很重要。
I invite you to try it and be as happy as I have been when it was working after half an hour of testing!!我邀请您尝试它,并在经过半小时的测试后像我一样开心!
File 1: daemon.py - this file will run forever.文件 1:daemon.py - 这个文件将永远运行。
from time import sleep
from sys import exit
while True:
try:
print("hello")
sleep(1)
except KeyboardInterrupt:
print("bye")
exit()
File 2: tkinterapp.py - The name is self-explainatory文件 2:tkinterapp.py - 名称不言自明
import tkinter as tk
import subprocess
import sys
import time
import os
import tkinter.font as font
from tkinter.ttk import *
app = tk.Tk()
app.geometry("400x400")
app.configure(bg='gray')
photo = tk.PhotoImage(file=r"C:\Users\royal\github\RandomSketches\baixa.png")
myFont = font.Font(family='Helvetica', size=20, weight='normal')
tk.Label(app, text='EX', bg='gray', font=(
'Verdana', 15)).pack(side=tk.TOP, pady=10)
# app.iconbitmap(r'C:\Users\ex\ex_icon.ico')
def ex_activation():
global pro
print("running!")
pro = subprocess.Popen("python daemon.py", shell=True)
def ex_stop():
global pro
print("stopping!")
os.kill(pro.pid, 0)
ex_activation_button = tk.Button(app,
bg='black',
image=photo,
width=120,
height=120,
command=ex_activation)
ex_stop_button = tk.Button(app,
bg='Gray',
text='ex',
width=12,
command=ex_stop, # BE CAREFUL You were missing a "," here !!!
height=3)
ex_stop_button['font'] = myFont
app.title("Example")
ex_activation_button.pack(side=tk.TOP)
ex_stop_button.pack(side=tk.LEFT)
# app.mainloop()
while True:
try:
app.update()
app.update_idletasks()
except KeyboardInterrupt:
pass
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.