Python Forum
Adding Progressbar to button
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Adding Progressbar to button
#1
Hello Experts,
Need small suggestions, bellow my script does enable the Wi-Fi interface. But i would like to add,
If someone clicks the button then a progress bar will appear and it will run for 60 secs and after 60sec it will disappear.
Please advice me how can I achieve this goal.
Thank you in advance

import subprocess
from tkinter import *

window= Tk()

def wifiOnscript():
    subprocess.call(['netsh', 'interface', 'set', 'interface', 'Wi-Fi', 'enabled'])

wifiOnButton=Button(window,text="WiFi-ON",command=wifiOnscript, height=1, width=22)
wifiOnButton.grid(row=2,column=0,padx=40, pady=10)

window.mainloop()
I just to add the following script to my button, how can i do this?
pb = ttk.Progressbar(root, orient="horizontal", length=200, mode="determinate")
pb.pack()
pb.start(50)
Reply
#2
** Note ** change sleep to 1 for seconds, This ticks on 1/10 second
or for smoother operation, change line 35 to:
        for x in range(0, 120):
and sleep to .5

Here's my example:
import tkinter as tk
import tkinter.ttk as ttk
import time
import sys


class ProgressBar:
    def  __init__(self):
        self.root = tk.Tk()
        self.root.geometry('250x50+20+20')
        self.root.title('Sixty Seconds progress bar')

        self.max = 120
        self.step = tk.DoubleVar()
        self.step.set(0)
        self.progbar = ttk.Progressbar

        self.frame = tk.Frame()
        self.frame.pack(fill=tk.BOTH, padx=2, pady=2)
        btn = tk.Button(self.frame, text='Start', bd = 4, command=self.start_progbar)
        btn.pack()
        self.root.mainloop()

    def add_progbar(self):
        self.progbar = ttk.Progressbar(
            self.frame, 
            orient=tk.HORIZONTAL, 
            mode='determinate', 
            variable=self.step, 
            maximum=self.max)
        self.progbar.pack(fill=tk.X, expand=True)

    def start_progbar(self):
        self.add_progbar()
        for x in range(0, 120, 2):
            self.step.set(x)
            time.sleep(.1)
            self.root.update()
        self.progbar.destroy()


if __name__ == '__main__':
    ProgressBar()
Reply
#3
Quote:it will run for 60 secs and after 60sec it will disappear
How are you incrementing the progress bar? Nothing will happen until the subprocess returns so you will have to use Tkinter's after method to update the progress bar if you want it to update while the subprocess is still running. A simple example using a countdown timer to simulate whatever the subprocess does, and a different progress bar because that is what is already in this program.
    try:
        import Tkinter as tk
    except:
        import tkinter as tk

    class ProgressBar():
        def __init__(self, root):
            self.root=root
            self.root.geometry("75x50+1200+100")
            tk.Button(self.root, text="Quit", bg="red", command=self.root.destroy).pack()
            self.ctr=60  ## 60 seconds
            self.start_progress_bar()
            self.start_countdown()

        def start_progress_bar(self):
            """ create a simple progress bar widget on a canvas
            """
            self.top=tk.Toplevel(self.root, takefocus=True)
            self.top.title("Progress Bar")
            self.top.geometry("+1200+300")
            self.canvas = tk.Canvas(self.top, width=261, height=60, background='lightgray')
            self.canvas.pack()

            self.rc1 = self.canvas.create_rectangle(24, 20, 32, 50, outline='white', \
                                          fill='blue')
            self.start_x=20
            self.end_x=235
            self.this_x=self.start_x
            self.one_25th = (self.end_x-self.start_x)/25.0
            rc2 = self.canvas.create_rectangle(self.start_x, 20, self.end_x, 50,
                                           outline='blue', fill='lightblue')
            self.rc1 = self.canvas.create_rectangle(self.start_x, 20, self.start_x+7, 50,
                                           outline='white', fill='blue')

            self.update_scale()

        def start_countdown(self):
            """ a separate process in a separate GUI
            """
            self.top2=tk.Toplevel(self.root, bg="lightyellow")
            self.top2.geometry("100x25+1200+200")
            self.label_ctr = tk.IntVar()
            self.label_ctr.set(self.ctr)
            tk.Label(self.top2, textvariable=self.label_ctr, width=10,
                     font=("Verdans", 15)).pack()
            self.update()

        def update(self):
            if self.ctr > 0:
                self.label_ctr.set(self.ctr)
                self.ctr -= 1
                self.root.after(1000, self.update)  ## one second
            else:
                ## sleep for one second to allow any remaining after() to execute
                ## can also use self.root.after_cancel(id)
                self.root.after(1000, self.root.destroy)

        def update_scale(self):
            self.canvas.move(self.rc1, self.one_25th, 0)
            self.canvas.update()
            self.this_x += self.one_25th
            ## reverse direction at either end
            if (self.this_x >= self.end_x-12) or self.this_x <= self.start_x+7:
                self.one_25th *= -1

            ## only call after() while the countdown is running (self.ctr > 0)
            ## to avoid a dangling after() when the program terminates
            if self.ctr > 0:
                self.canvas.after(200, self.update_scale)

    root = tk.Tk()

    PB=ProgressBar(root)
    root.mainloop()
Reply
#4
I present only a working example, It's up to you to implement your update logic.
Reply
#5
(Feb-06-2019, 05:23 PM)Larz60+ Wrote: ** Note ** change sleep to 1 for seconds, This ticks on 1/10 second
or for smoother operation, change line 35 to:
        for x in range(0, 120):
and sleep to .5

Here's my example:
import tkinter as tk
import tkinter.ttk as ttk
import time
import sys


class ProgressBar:
    def  __init__(self):
        self.root = tk.Tk()
        self.root.geometry('250x50+20+20')
        self.root.title('Sixty Seconds progress bar')

        self.max = 120
        self.step = tk.DoubleVar()
        self.step.set(0)
        self.progbar = ttk.Progressbar

        self.frame = tk.Frame()
        self.frame.pack(fill=tk.BOTH, padx=2, pady=2)
        btn = tk.Button(self.frame, text='Start', bd = 4, command=self.start_progbar)
        btn.pack()
        self.root.mainloop()

    def add_progbar(self):
        self.progbar = ttk.Progressbar(
            self.frame, 
            orient=tk.HORIZONTAL, 
            mode='determinate', 
            variable=self.step, 
            maximum=self.max)
        self.progbar.pack(fill=tk.X, expand=True)

    def start_progbar(self):
        self.add_progbar()
        for x in range(0, 120, 2):
            self.step.set(x)
            time.sleep(.1)
            self.root.update()
        self.progbar.destroy()


if __name__ == '__main__':
    ProgressBar()

Hello Thanks for your reply, Looks a very advanced coding, I am a newbie. I Just want to let my user know that code is working and wait for 60sec.
to achieve this do I have to use probe bar, can I use just simple timer
Reply
#6
progbar is just the name assigned to the instance of ttk.Progressbar
Suggest you run this code and try to comprehend what's happining
It does everything that you said you needed.
The main parts you need to understand are start_progbar and add_progbar
the rest is just code needed to present the progress bar, and a start button, which is what you said you wanted.
Reply
#7
(Feb-07-2019, 01:15 AM)Larz60+ Wrote: progbar is just the name assigned to the instance of ttk.Progressbar
Suggest you run this code and try to comprehend what's happining
It does everything that you said you needed.
The main parts you need to understand are start_progbar and add_progbar
the rest is just code needed to present the progress bar, and a start button, which is what you said you wanted.

Hello Larz60, Thanks for your reply.
why i need to use class methods for Progressbar,

pb = ttk.Progressbar(root, orient="horizontal", length=200, mode="determinate")
pb.pack()
pb.start(50)
why i cannot use just simple progress bar? i don't need anything fancy. i just when user clicks the button, it will show the user that Script is running and it will take 60sec to finish the job, after 60 sec, Progressbar will end and ready for next task.
Reply
#8
Quote:why i need to use class methods for Progressbar,
you don't need to use class, I'm just more comfortable using classes for everything

Without class:
import tkinter as tk
import tkinter.ttk as ttk
import time


root = tk.Tk()
root.geometry('250x50+20+20')
root.title('Sixty Seconds progress bar')
max = 120
step = tk.DoubleVar()
step.set(0)

frame = tk.Frame()
frame.pack(fill=tk.BOTH, padx=2, pady=2)

progbar = ttk.Progressbar

def add_progbar():
    progbar = ttk.Progressbar(
        frame, 
        orient=tk.HORIZONTAL, 
        mode='determinate', 
        variable=step, 
        maximum=max)
    progbar.pack(fill=tk.X, expand=True)

def start_progbar():
    add_progbar()
    for x in range(0, 120):
        step.set(x)
        time.sleep(.5)
        root.update()

btn = tk.Button(frame, text='Start', bd = 4, command=start_progbar)
btn.pack()
root.mainloop()
Reply
#9
(Feb-07-2019, 03:55 AM)Larz60+ Wrote:
Quote:why i need to use class methods for Progressbar,
you don't need to use class, I'm just more comfortable using classes for everything

Without class:
import tkinter as tk
import tkinter.ttk as ttk
import time


root = tk.Tk()
root.geometry('250x50+20+20')
root.title('Sixty Seconds progress bar')
max = 120
step = tk.DoubleVar()
step.set(0)

frame = tk.Frame()
frame.pack(fill=tk.BOTH, padx=2, pady=2)

progbar = ttk.Progressbar

def add_progbar():
    progbar = ttk.Progressbar(
        frame, 
        orient=tk.HORIZONTAL, 
        mode='determinate', 
        variable=step, 
        maximum=max)
    progbar.pack(fill=tk.X, expand=True)

def start_progbar():
    add_progbar()
    for x in range(0, 120):
        step.set(x)
        time.sleep(.5)
        root.update()

btn = tk.Button(frame, text='Start', bd = 4, command=start_progbar)
btn.pack()
root.mainloop()


Thanks for your reply, can you please take a look my code and see what i can do to stop my bar after 60 sec??
import subprocess
from tkinter import *
from tkinter import ttk
window= Tk()

def wifiOnscript():
    # subprocess.call(['netsh', 'interface', 'set', 'interface', 'Wi-Fi', 'enabled'])
    pb = ttk.Progressbar(window, orient="horizontal", length=200, mode="determinate", )
    pb.grid()
    pb.start(50)

wifiOnButton=Button(window,text="WiFi-ON",command=wifiOnscript, height=1, width=22)
wifiOnButton.grid(row=2,column=0,padx=40, pady=10)

window.mainloop()
Reply
#10
Please study and understand my code, It has everything that you requested:
Start button
progress bar that runs for 60 seconds then stops.
your code is missing critical components.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Centering and adding a push button to a grid window, TKinter Edward_ 15 4,380 May-25-2023, 07:37 PM
Last Post: deanhystad
  [Tkinter] progressbar DPaul 9 2,779 Sep-01-2021, 12:50 PM
Last Post: deanhystad
  adding button status updates to countdown counter knoxvilles_joker 7 3,342 Apr-18-2021, 01:59 AM
Last Post: knoxvilles_joker
  Progressbar with start and stop jelo34 3 4,876 Nov-30-2020, 03:36 AM
Last Post: deanhystad
  [Tkinter] Progressbar value update issue Roshan 7 3,258 Apr-22-2020, 04:02 PM
Last Post: deanhystad
  [Tkinter] Can't get progressbar to update frednet 0 1,629 Feb-24-2020, 10:53 PM
Last Post: frednet
  [PySimpleGui] How to alter mouse click button of a standard submit button? skyerosebud 3 4,949 Jul-21-2019, 06:02 PM
Last Post: FullOfHelp
  [WxPython] Adding a Window to a Button wxPython ShashankDS 4 3,783 Apr-23-2019, 06:53 PM
Last Post: Yoriz
  tkinter- adding a new window after clicking a button built on the gui ShashankDS 2 6,547 Apr-18-2019, 12:48 PM
Last Post: ShashankDS

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020