使用 tkinter 为单独的程序编写 Python UI.这个程序的停止按钮基本上冻结了 UI 并继续执行脚本 [英] 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

查看:34
本文介绍了使用 tkinter 为单独的程序编写 Python UI.这个程序的停止按钮基本上冻结了 UI 并继续执行脚本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我编码的...

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

我正在寻找一种方法让我的程序停止另一个按钮运行的程序.我意识到这可能是一个自毁按钮".但我不知道如何用另一个按钮运行的脚本来做到这一点.非常感谢任何帮助!我尝试通过将 def ex_activation 放在 p.kill 中来杀死代码这不起作用...

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...

推荐答案

如果让另一个 python 脚本永远运行(有某种while True:),你就不能运行它像您一样在命令行上,因为它会在该脚本运行时冻结您的窗口.

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 脚本,您需要使用子进程库来完成.(在此处)

In order to run a python script on background you will need to do it with the subprocess library. (Find out here)

我还发现了另一个使用 问题 的答案code>check_ouput() 以便知道python程序何时完成.如果您想向 tkinter 应用程序发送状态,这也很有用:例如,您可以 print("33% Complete").您可以将其添加到 tkinter 的主循环中,以便您始终知道您的程序是否正在运行.

I also found an answer of another question that uses check_ouput() in order to know when the python program has finished. This can also be useful if you want to send a status to the tkinter app: you can print("33% Complete"), for example. You could add this in tkinter's main loop, so you always know if your program is running or not.

最后但并非最不重要的一点是,要终止该进程(使用停止按钮),您应该使用 os 并查找子进程的 ID.这里你也可以找到一个很好的例子.

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. Here you can also find a good example.

我会尝试这样的事情:

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

编辑

使用问题代码的示例代码.警告:我已经更改了 png 文件位置以进行测试,评论了应用程序图标,并且仅在 Windows 上进行了测试.

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.

重要的是删除主文件上的 mainloop() 并放置 update...() 以捕获键盘中断(我不知道为什么)正在杀死父进程和子进程.

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.

我邀请您尝试一下,在经过半小时的测试后,它会像我一样开心!

I invite you to try it and be as happy as I have been when it was working after half an hour of testing!!

文件 1:daemon.py - 此文件将永远运行.

File 1: daemon.py - this file will run forever.

from time import sleep
from sys import exit

while True:
    try:
        print("hello")
        sleep(1)
    except KeyboardInterrupt:
        print("bye")
        exit()

文件 2:tkinterapp.py - 名称不言自明

File 2: tkinterapp.py - The name is self-explainatory

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

这篇关于使用 tkinter 为单独的程序编写 Python UI.这个程序的停止按钮基本上冻结了 UI 并继续执行脚本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆