简体   繁体   English

使用 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

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.

相关问题 使用tkinter 为Python 程序创建UI。Tkinter 中的按钮可以多次按下。 如何创建“一个过程”弹出窗口? - Creating a UI for Python Program using tkinter. The button in Tkinter can be pressed multiple times. How can I create a "One Process" Pop Up? 使用 Tkinter 创建 UI。 尝试调整按钮文本的字体并运行程序时,我收到此错误 - Creating a UI with Tkinter. When trying to adjust the font of my button text and I run the program, I get this error back 我正在使用 Tkinter 为外部程序编写 UI。如何将任何打印语句重定向到 tkinter 中的小部件? 几乎就像一个实时日志 - I am writing a UI for an external program using Tkinter. How could I redirect any print statements to widget in tkinter? Almost like a live log Python Tkinter。 无法将主题应用于程序的第二个窗口 - Python Tkinter. Cant apply theme for second window of program 单击“计算”按钮 Python Tkinter 后,我的程序立即冻结 - My program freezes as soon as I click the "Calculate" button Python Tkinter Python Tkinter 按钮在使用热键后冻结程序 - Python Tkinter button freezes program after using hotkey 按钮未出现在tkinter中。 (蟒蛇) - Button not appearing in tkinter. (python) Tkinter 停止程序执行按钮 - Tkinter Stop Program Execution Button Python Tkinter崩溃了,每次运行但程序仍在继续? Tkinter的最终抛光 - Python Tkinter Crashing, every run but program continues? Final polishing of Tkinter Tkinter画布冻结程序 - Tkinter Canvas Freezes Program
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM