【问题标题】:Creating a UI for another Python program. How do I make a printing label in tkinter for Python 3?为另一个 Python 程序创建 UI。如何在 tkinter 中为 Python 3 制作打印标签?
【发布时间】:2020-08-14 20:52:56
【问题描述】:

我正在为另一个 python 程序创建一个 UI,它本质上只是为项目创建了一个交互式组件。目标是有一个特定的标签,从按钮运行的 python 程序更新(打印语句)。这是我在我的 UI 中编写的...


import tkinter as ttk
import subprocess
import sys
import time
import os
import tkinter.font as font
from tkinter.ttk import *

app = ttk.Tk()

app.geometry("400x400")
app.configure(bg='gray')

photo = ttk.PhotoImage(file=r"C:\Users\ex\ex_button_active.png")
myFont = font.Font(family='Helvetica', size=20, weight='normal')

ttk.Label(app, text='Ex', bg='gray', font=(
    'Verdana', 15)).pack(side=ttk.TOP, pady=10)
app.iconbitmap(r'C:\Users\ex\ex_icon.ico')


def ex_activation():
    global pro
    print("Running program!")
    pro = subprocess.Popen("python programex.py", shell=True)


def ex_stop():
    global pro
    print("Stopping Program... Please Wait!")
    os.kill(pro.pid, 0)


ex_activation_button = ttk.Button(app, bg='black', image=photo, width=120, height=120, command=ex_activation)

ex_stop_button = ttk.Button(app, bg='Gray', text='Stop Program', width=12, command=ex_stop, height=3)

ex_stop_button['font'] = myFont

app.title("Ex")
ex_activation_button.pack(side=ttk.TOP)
ex_stop_button.pack(side=ttk.LEFT)

# app.mainloop()
while True:
    try:
        app.update()
        app.update_idletasks()
    except KeyboardInterrupt:
        pass

如果有人知道如何在我的代码中实现This StackOverflow Post,我将非常感谢您的帮助和支持。

编辑 acw1668 这些是我运行的一些测试,在 Pycharm 运行窗口而不是 UI 中得到了一些奇怪的数字。

Running program!
3528
Stopping Program 3528 ... Please Wait!
monitor done
Running program!
144
Stopping Program 144 ... Please Wait!
monitor done
Running program!
14008
Stopping Program 14008 ... Please Wait!
monitor done
Running program!
21748
Stopping Program 21748 ... Please Wait!
monitor done

【问题讨论】:

  • 大声笑,我从我的回答中认出了这段代码,至少是其中的一部分:stackoverflow.com/questions/63388925/… 无论如何,这是一个很酷的功能,所以让我尝试一下 :)
  • @EricRoy 谢谢 :) 我对 tkinter 还是很陌生。如果您很好奇,UI 是用于虚拟助手项目的。
  • 虚拟助手会根据提出的问题打印数据。它也会说话,但打印数据是一个重要部分。
  • 这是一件好事。我希望我的回答能帮助你更多地了解 tkinter :)
  • @EricRoy 我在回复时忘了告诉你,哈哈

标签: python python-3.x tkinter label


【解决方案1】:

我使用了您的代码的简化版本。要在 tkinter 应用程序中获取打印状态,我想到的最简单的方法是使用第三个文件:在我的例子中,log.txt

daemon.pylog() 一些输出(自定义函数)到文本文件而不是打印它。在 tkinter 主循环中,应用程序将不断检查对该文件的更改。

请注意,使用 file.readline(),我只阅读一行,因为 tkinter Labels 更喜欢这样。如果您计划使用更多行,则可以将标签更改为文本区域。

无论如何:这是代码。我希望它能在你的项目中工作!

# FILE 1: daemon.py

from time import sleep
from sys import exit

def log(s): # This will be the equivalent to the print function
    with open("log.txt", "w") as fileout:
        fileout.write(s)

x = 0
while True:
    try:
        log("seconds elapsed: " + str(x))
        x+=1
        sleep(1)
    except KeyboardInterrupt:
        log("Stopping with x =" + str(x))
        exit()
# FILE 2: log.txt

# You can leave this file empty, but you must create a file named 'log.txt'.
# FILE 3: mainapp.py

import tkinter as tk
import subprocess
import os

def ex_activation():
    print("Running")
    global pro
    pro = subprocess.Popen("python daemon.py", shell=True)

def ex_stop():
    print("Stopped") # I just dont know why, but this print can't be removed.
    global pro
    os.kill(pro.pid, 0)

app = tk.Tk()

ex_activation_button = tk.Button(app, text="run", command=ex_activation)
ex_stop_button = tk.Button(app, text="stop", command=ex_stop)
lab = tk.Label(app, text="If you see this, an error occurred")

with open("log.txt", "w+") as fileinout:
    fileinout.write("Click run to start the execution!")
    lab.config(text=fileinout.readline())

ex_activation_button.pack()
ex_stop_button.pack()
lab.pack()

# app mainloop
while True:
    try:
        app.update()
        app.update_idletasks()
        with open( "log.txt", "r" ) as filein:
            lab.config(text=filein.readline())
    except KeyboardInterrupt:
        pass

【讨论】:

  • Hey Eric Roy :) 上面的程序对我来说很有意义,但我的虚拟助手会无限运行,直到遇到错误或我按下停止。这意味着它确实有一个whileTrue:,也使得它有点难以融入到程序中。虽然这确实有 100% 的意义,而且我确实理解你是如何到达那里的 :) 我只是不知道如何使用 2 whileTrue's?你有什么想法吗?
  • 我的意思是,我想我可以做一个嵌套的 while 循环,但我的程序中的 while 循环有一个 else 语句。是否可以使用 else 语句进行嵌套的 while 循环。
  • 您只需将您的while True: 内容放入try: 语句中。不要忘记将所有print() 替换为log()。如果您的程序也因错误而停止,您可以记下是哪个错误(ValueError,AttributeError,...)并将其添加到 except 语句中,这样您就不会在屏幕上看到丑陋的异常。
  • 您好,埃里克,感谢您的回复。我只想提一下,它测量运行程序时经过的秒数,并将其放入 log.txt 中并更新它。但是,我的想法是从 daemon.py 获取任何打印语句,以作为标签显示在 gui 上。我是不是用错了程序?我为您在这篇文章上花费了您的时间深表歉意,我每天都在学习更多关于 tkinter 的知识:)
  • 是的,这就是我创建函数 log() 的原因,如果你在你的守护进程的所有 print() 中替换它,它将显示在标签上的每一行。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-18
  • 2018-08-19
  • 1970-01-01
相关资源
最近更新 更多