简体   繁体   English

当子进程在后台运行时,GUI上的Tk进度栏?

[英]Tk progress bar on GUI while a subprocess is running in the background?

I am developing a GUI using python. 我正在使用python开发GUI。 When a button on one tab of the GUI is clicked, an executable is to be run in the background. 单击GUI的一个选项卡上的按钮时,将在后台运行可执行文件。 While the executable is running, I would like to show a indeterminate progress bar oscillating on the input tab and when the subprocess is complete, the new tab should open up displaying the results from the text-files outputs of the subprocess. 当可执行文件运行时,我想在输入选项卡上显示一个不确定的进度条 ,当子流程完成时,新的选项卡应该打开,显示子流程的文本文件输出的结果。

However if I use thread function join() , the GUI freezes and the progress bar can't be shown. 但是,如果我使用线程函数join()则GUI冻结并且无法显示进度栏。 If I do not use join, the new tab opens, without waiting for the subprocess showing error since the output files do not exist. 如果不使用join,则新选项卡将打开,而不会等待子进程显示错误,因为输出文件不存在。

I don't have a previous experience with threading and queues. 我以前没有线程和队列经验。 I am not sure if I have understood the concepts properly. 我不确定我是否正确理解了这些概念。 I would appreciate any help. 我将不胜感激任何帮助。 This is a part of my code: 这是我的代码的一部分:

import Tkinter
from Tkinter import *
import subprocess

class myThread(threading.Thread):

    def __init__(self,thread_name,command):
        threading.Thread.__init__(self)
        self.thread_name=thread_name
        #self.queue=queue
        self.command=command

    def run(self):
        if self.thread_name=="Run":


           os.chdir( 'D:\\Projects\\' ) 
           subprocess.Popen( "executable.exe" ,shell=False)
           log.info('Execution started.')

class GUI(Frame):
    def __init__(self,parent):

    '''
    GUI design
    '''
        self.go_Button=Button(self.note,text="GO",command=self.submitted)
        self.go_Button.grid(row=13,column=4,pady=(20,10),in_=self.input_Tab)

    def submitted(self):
        #Defines the actions to be done after  the click of the GO button 
        #self.queue=Queue.Queue()
        self.go_Button.lower(self.input_Tab)
        progress=Progressbar(self.note,mode='indeterminate',length=500)
        progress.grid(row=13,columnspan=6,sticky=W+E,padx= (40,10),in_=self.input_Tab)

       self.t=myThread("Run",self.command)
       self.t.daemon=True
       self.t.start()
       progress.start()
       self.t.join() #waits for the thread to complete but freezes the tkinter GUI
       progress.stop()

       log.debug("Has finished the thread")
       self.note.select(self.output_Tab)
       self.uploadResults()
       progress.lower(self.input_Tab)
       self.go_Button.lift(self.input_Tab)

Thanks in advance..! 提前致谢..!

There is no need to create a thread or spawn another process using multiprocessing module. 无需使用多处理模块创建线程或生成另一个进程。 I created a subprocess.Popen object from the mainloop and created a while loop which checks if the process is alive and updates the root widget if the executable is running. 我从主循环创建了一个subprocess.Popen对象,并创建了一个while循环,该循环检查进程是否处于活动状态,并在可执行文件正在运行时更新根窗口小部件。 This ensures that the progress bar works until the subprocess is finished or killed. 这样可以确保进度条在子流程完成或终止之前一直有效。

self.progressBar=Progressbar(self.note,mode='indeterminate',length=500)
self.progressBar.grid(row=13,columnspan=6,sticky=W+E,padx=(40,10),in_=self.input_Tab)

os.chdir( 'D:\\Projects\\' ) 
self.proc=subprocess.Popen( "executable.exe" ,shell=False)
self.progressBar.start()

while self.proc.poll() is None:
      self.update()

self.progressBar.stop()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM