首页 > 解决方案 > 在python中将函数输出链接到GUI

问题描述

您好我正在尝试编写一个简单的程序,在后台工作时查找特定可执行文件的工作时间。这个位在 IDE 的 shell 中工作,但是我不知道如何将 shell 输出连接到 GUI,以便它刷新并以秒为单位显示程序正在运行的时间。

[我尝试过 StringVar 但失败了]

如果有人会帮助它会很可爱

以下是如上所述仅部分有效的代码:

import time
from tkinter import * # Another GUI-Framework is PYQT5
import wmi
import sys

c = wmi.WMI()
Task_List = []


class AppButtons:
    # A variable and a List for the gatering of currently running processes

    def __init__(self, master):
        main_frame = Frame(master)
        main_frame.pack()

        '''
        #Program title
        self.Label = Label(main_frame, text='The time monitoring app')
        self.Label.config(font=("Courier", 30), anchor=CENTER)
        self.Label.grid(row=0, column=0)
        '''


        # Program start
        self.strat_timer = Button(main_frame, text='Beggin the app running time monitoring!!!', command=self.main_timer)
        self.strat_timer.config(font=("Courier", 12))
        self.strat_timer.grid(row=1, column=0,pady=10, sticky=E+W) # pady and padx add space btw the widgets in the x and y directions corespondingly

        # Program termination
        self.end_timer = Button(main_frame, text='Terminate the app timmer', command=self.timer_kill)
        self.end_timer.config(font=("Courier", 12))
        self.end_timer.grid(row=1, column=1,pady=10, sticky=E+W)

        # Output description
        self.time_overwatch_label1 = Label(main_frame, bg='red' ,width=60, height=1 , text='Program: WorldOfTanks.exe | Running time:')
        self.time_overwatch_label1.grid(row=2, column=0,)

        self.time_overwatch_label2 = Label(main_frame, bg='Yellow',width=60, height=1 , text='Program: chrome.exe | Running time:')
        self.time_overwatch_label2.grid(row=3, column=0)

        self.time_overwatch_label3 = Label(main_frame, bg='red',width=60, height=1 , text='Program: pycharm64.exe | Running time:')
        self.time_overwatch_label3.grid(row=4, column=0)


        # Output part
        self.output1 = Label(main_frame, bg='red' ,width=60, height=1, text=self.main_timer)
        self.output1.grid(row=2, column=1)

        self.output2 = Text(main_frame, bg='Yellow', width=60, height=1)
        self.output2.grid(row=3, column=1)

        self.output3 = Text(main_frame, bg='red', width=60, height=1)
        self.output3.grid(row=4, column=1)

    # gives the list of currently running processes using the WMI library
    def running_tasks(self):
        Task_List.clear()
        for process in c.Win32_Process():
            Task_List.append(process.Name)
        return Task_List

    def program_search(self):
        self.running_tasks()
        if any('WorldOfTanks.exe' in s for s in Task_List):
            return True
        else:
            return False

    # Main fuction which is responsible for the output of the timmer (in this example of WorldOfTanks.exe)
    # This fuction cosists of "running_tasks" and "task_search". It should be called from the GUI window
    def main_timer(self):
        start_time = time.time()
        while True:
            if self.program_search() is True:
                print('WoT is Running for', "--- %s seconds ---" % (time.time() - start_time))
                continue
            if time.time() - start_time < 21:
                print("World of Tanks wasn't running")
                break
            if self.program_search() is False:
                print('WorldOfTanks.exe was running for', "--- %s seconds ---" % (time.time() - start_time))
                break


    def timer_kill(self):
        sys.exit()


root = Tk()

# Title of the window is displayed on the uppermost bar
root.title("The Time Monitoring App")

# Initializes the class
b = AppButtons(root)

root.mainloop()

标签: pythonuser-interfacetkinter

解决方案


最明智的方法是StringVar()为三个运行时间创建三个并将它们链接到标签。time.sleep(.5)在循环的每次迭代中(如果包含 a等待半秒再运行它,可能要求不高),更新所有字符串变量。

创建和链接字符串变量:

    self.t1 = StringVar()
    self.t1.set("No time recorded for WoT") ## Set to no output before the button is pressed

    self.output1 = Label(main_frame, bg='red' ,width=60, height=1, textvariable=self.t1)
    self.output1.grid(row=2, column=1)

更新它们的值:

def main_timer(self):
    start_time = time.time()
    while True:
        time.sleep(0.5)
        if self.program_search() is True:
            self.t1.set('WoT is Running for', "--- %s seconds ---" % (time.time() - start_time))
            continue
        if time.time() - start_time < 21:
            self.t1.set("World of Tanks wasn't running")
            break
        if self.program_search() is False:
            self.t1.set('WorldOfTanks.exe was running for', "--- %s seconds ---" % (time.time() - start_time))
            break

每当您更改self.t1方法中的值时.main_timer(),标签将被更新,因为它直接链接到此 StringVar。 重要提示:如果您希望标签的文本自动更改,则必须使用textvariable而不是设置标签的文本。text


推荐阅读