功能运行时不确定进度条 [英] Indeterminate Progress bar while function is running

查看:23
本文介绍了功能运行时不确定进度条的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 GUI,它有两个按钮和一个堆叠在单列上的进度条.每个按钮调用一个不同的函数,这需要一些时间来执行.我希望进度条在有人单击两个按钮中的任何一个时移动并继续移动(不确定)直到功能完成然后停止.我知道我需要使用多线程,但我似乎无法正确编写代码!

I have a GUI which has two buttons and a progressbar stacked on a single column. Each button calls a different function which takes some time to execute. I want the progress bar to move when someone clicks any of the two buttons and keep moving (indeterminately) until the function finishes and then stop. I know I need to use multi-threading but I can't seem to get the code right!

代码

from tkinter import Tk
import time 
from tkinter import *
from tkinter import Button
from tkinter import Frame
from tkinter import ttk
import threading


def sample_function():
    time.sleep(2)  # SAMPLE FUNCTION BEING CALLED

def prepare_clicked():
    sample_function()  

def social_clicked():

    sample_function()

def anomaly_clicked():
    sample_function()             



window = Toplevel() # Tried using Tk but I am using image to design each buttons through the button config in my actual code and tk throws error
topFrame = Frame(window)
topFrame.pack()

prepare_btn = Button(topFrame, command=prepare_clicked,text='Button1')
anomaly_btn = Button(topFrame,command=anomaly_clicked,text='Button2')
social_btn = Button(topFrame, command=social_clicked,text='Button3')
processing_bar = ttk.Progressbar(topFrame, orient='horizontal', mode='indeterminate')



window.rowconfigure((0,1), weight=1)  # make buttons stretch when
window.columnconfigure((0,3), weight=1)  # when window is resized
prepare_btn.grid(row=0, column=1, columnspan=1, sticky='EWNS')
anomaly_btn.grid(row=1, column=1, columnspan=1, sticky='EWNS')
social_btn.grid(row=2, column=1, columnspan=1, sticky='EWNS')
processing_bar.grid(row=3, column=1, columnspan=1, sticky='EWNS')


window.mainloop()

推荐答案

我已将线程添加到您的代码中.我假设您不希望任何按钮在功能进行中时可按下.如果您不需要它,只需去掉 run_function 中改变 <​​code>btn['state'] 的 for 循环.我还修复了行 &列配置代码,以便小部件展开 &当用户调整窗口大小时收缩.我摆脱了邪恶的明星"导入.

I've added threading to your code. I assume you don't want any of the buttons to be pressable while a function is in progress. If you don't need that, just get rid of the for loops in run_function that change btn['state']. I've also fixed the row & column configuration code so that the widgets expand & contract when the user resizes the window. And I got rid of the evil "star" import.

import tkinter as tk
from tkinter import ttk
import time
from threading import Thread

def sample_function():
    time.sleep(2)

def run_function(name, func):
    # Disable all buttons
    for btn in buttons:
        btn['state'] = 'disabled'

    processing_bar.start(interval=10)
    print(name, 'started')
    func()
    processing_bar.stop()
    print(name, 'stopped')

    # Enable all buttons
    for btn in buttons:
        btn['state'] = 'normal'

def run_thread(name, func):
    Thread(target=run_function, args=(name, func)).start()

def prepare_clicked():
    run_thread('prepare', sample_function)

def social_clicked():
    run_thread('social', sample_function)

def anomaly_clicked():
    run_thread('anomaly', sample_function)


window = tk.Tk()
#window = tk.Toplevel()

topFrame = tk.Frame(window)

# Tell the Frame to fill the whole window
topFrame.pack(fill=tk.BOTH, expand=1)

# Make the Frame grid contents expand & contract with the window
topFrame.columnconfigure(0, weight=1)
for i in range(4):
    topFrame.rowconfigure(i, weight=1)

prepare_btn = tk.Button(topFrame, command=prepare_clicked, text='Button1')
anomaly_btn = tk.Button(topFrame,command=anomaly_clicked, text='Button2')
social_btn = tk.Button(topFrame, command=social_clicked, text='Button3')
buttons = [prepare_btn, anomaly_btn, social_btn]

processing_bar = ttk.Progressbar(topFrame, orient='horizontal', mode='indeterminate')

prepare_btn.grid(row=0, column=0, columnspan=1, sticky='EWNS')
anomaly_btn.grid(row=1, column=0, columnspan=1, sticky='EWNS')
social_btn.grid(row=2, column=0, columnspan=1, sticky='EWNS')
processing_bar.grid(row=3, column=0, columnspan=1, sticky='EWNS')

window.mainloop()

<小时>

更新

这是新的改进版本,带有一个按顺序运行所有功能的全部"按钮.享受!

Here's the new improved version, with an 'All' button that runs all the functions, in order. Enjoy!

import tkinter as tk
from tkinter import ttk
import time
from threading import Thread

def prepare_func():
    print('prepare started')
    time.sleep(2)
    print('prepare stopped')

def anomaly_func():
    print('anomaly started')
    time.sleep(2)
    print('anomaly stopped')

def social_func():
    print('social started')
    time.sleep(2)
    print('social stopped')

def all_func():
    print('all started')
    show_and_run(prepare_func, buttons['Prepare'])
    show_and_run(anomaly_func, buttons['Anomaly'])
    show_and_run(social_func, buttons['Social'])
    print('all stopped')

def show_and_run(func, btn):
    # Save current button color and change it to green
    oldcolor = btn['bg']
    btn['bg'] = 'green'

    # Call the function
    func()

    # Restore original button color
    btn['bg'] = oldcolor

def run_function(func, btn):
    # Disable all buttons
    for b in buttons.values():
        b['state'] = 'disabled'

    processing_bar.start(interval=10)
    show_and_run(func, btn)
    processing_bar.stop()

    # Enable all buttons
    for b in buttons.values():
        b['state'] = 'normal'

def clicked(func, btn):
    Thread(target=run_function, args=(func, btn)).start()

window = tk.Tk()
#window = tk.Toplevel()

topFrame = tk.Frame(window)

# Tell the Frame to fill the whole window
topFrame.pack(fill=tk.BOTH, expand=1)

# Make the Frame grid contents expand & contract with the window
topFrame.columnconfigure(0, weight=1)
for i in range(4):
    topFrame.rowconfigure(i, weight=1)

button_data = (
    ('Prepare', prepare_func),
    ('Anomaly', anomaly_func),
    ('Social', social_func),
    ('All', all_func),
)

# Make all the buttons and save them in a dict
buttons = {}
for row, (name, func) in enumerate(button_data):
    btn = tk.Button(topFrame, text=name)
    btn.config(command=lambda f=func, b=btn: clicked(f, b))
    btn.grid(row=row, column=0, columnspan=1, sticky='EWNS')
    buttons[name] = btn
row += 1

processing_bar = ttk.Progressbar(topFrame, 
    orient='horizontal', mode='indeterminate')
processing_bar.grid(row=row, column=0, columnspan=1, sticky='EWNS')

window.mainloop()

这篇关于功能运行时不确定进度条的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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