Trouble with progressbar in tkinter - python

This is my code
janela_barra=Toplevel()
janela_barra.title("Processando...")
janela_barra["bg"]="light grey"
janela_barra.minsize(width=400, height=80)
janela_barra.maxsize(width=400, height=80)
comprimento = janela_barra.winfo_screenwidth()
altura = janela_barra.winfo_screenheight()
x = (comprimento/2)-(400/2)
y = (altura/2)-(80/2)
janela_barra.geometry("400x80+%d+%d" % (x, y))
janela_barra.iconbitmap('icon6.ico')
pb = ttk.Progressbar(janela_barra, orient=HORIZONTAL, length=200, mode='determinate')
pb.grid(column=0,row=0)
pb["value"]=0
pb["maximum"]=100
and then there is this inside a for:
for i in range(0,tamanho):
pb["value"]=i
pb.update()
where tamanho is the number of iterations of a for(420 right now), but the thing is, it only opens a windows and then closes, i can't see the progressbar actually function, no matter how much i increase tamanho

Just add sleep (from module time) in your loop, you will see the progression. Here is an example:
from tkinter import Tk, Button, Toplevel
from tkinter import ttk
from time import sleep
root = Tk()
def fct_run_for():
top=Toplevel(root)
top.title("Progression")
pb = ttk.Progressbar(top, orient="horizontal", length=200, mode='determinate')
pb.grid(column=0,row=0)
pb["value"]=0
pb["maximum"]=100
for i in range(100):
pb["value"] += 1
pb.update()
sleep(0.1)
Button(root, text="Run", command=fct_run_for).pack()
root.mainloop()

Related

Making a window UI scroll down and deleting labels from frame

I am making a random generator for my friends and I'm stuck trying to make a scroll down option. So if you generate more the window can show, a scroll down window should be possible. But I can't seem to get any to work. I've tried many online tutorials.
And my second issue with my code is that I can't clear the generated labels from the window. I got it working that it expands the window.
from cProfile import label
from pickle import FRAME
import random
import tkinter as tk
from tkinter import BOTH, DISABLED, LEFT, RIGHT, VERTICAL, Y, Frame, Label, filedialog, Text
import os
from tkinter import ttk
from tkinter.font import NORMAL
from tkinter.messagebox import YES
root = tk.Tk()
root.title('guesser')
#Pelin arvonta ohjelma !
def delete():
for child in root.children.values():
info = child.grid_info()
if info['column'] == 0:
child.grid_forget()
def arvonta():
global label
list1 = []
lista = ["Valorant","Rainbow","Vampire: The masquerade","Playerunknown's battlegrounds","Fortnite","Left 4 Dead 2","Counter strike Global offensive","Realm roayale","Black ops 1 zombies/multiplayer","Black ops 2 zombies/multiplayer","Black ops 3 zombies/multiplayer"]
numero = random.randint(0, 10)
hahmo = (lista[numero])
list1.append(hahmo)
for app in list1:
label = tk.Label(frame, text=app, bg="red",font=('Helvetica',20))
label.pack()
def valorant():
list2 = []
lista2 = ["Brimstone","Viper","Omen","Killjoy","Cypher","Sova","Sage","phoenix","Jett","Reyna","Raze","Raze","Breach","Skye","Yoru","Astra","Kay/o","Chamber","Neon","Fade"]
numero = random.randint(0, 19)
randomValorantagent=(lista2[numero])
list2.append(randomValorantagent)
for app in list2:
label = tk.Label(frame, text=app, bg="red",font=('Helvetica',20))
label.pack()
def quitter():
quit()
canvas = tk.Canvas(root,height=700,width=700,bg="#263D42")
canvas.pack(side=LEFT,fill=BOTH,expand=1)
frame = tk.Frame(root,bg="green")
frame.place(relwidth=0.8,relheight=0.8,relx=0.1,rely=0.1)
frame.pack(fill=BOTH,expand=1)
my_scrollbar = ttk.Scrollbar(frame, orient=VERTICAL, command=canvas.yview)
my_scrollbar.pack(side=RIGHT, fill=Y)
# Configure The Canvas
canvas.configure(yscrollcommand=my_scrollbar.set)
canvas.bind('<Configure>', lambda e: canvas.configure(scrollregion = canvas.bbox("all")))
# Create ANOTHER Frame INSIDE the Canvas
second_frame = Frame(canvas)
# Add that New frame To a Window In The Canvas
canvas.create_window((0,0), window=second_frame, anchor="nw")
#rlls the game
openfile = tk.Button(second_frame,text="Roll a game",padx=10,pady=5,fg="white",bg="#263D42", command=arvonta)
openfile.pack()
#rolls a valorant agent
valorantA = tk.Button(second_frame,text='Roll valorant agent',padx=10,pady=5,fg="white",bg="#263D42",command=valorant)
valorantA.pack()
# stops program
stop = tk.Button(second_frame,text="Quit",padx=10,pady=5,fg="white",bg="#263D42",command=quitter)
stop.pack()
# deletes all info from screen.
deletor = tk.Button(second_frame,text="delete info",padx=10,pady=5,fg="white",bg="#263D42",command=delete)
deletor.pack()
root.mainloop()```
The following does most of what you want. I wrote it some time ago to test Scrollbars because they are wonky IMHO
from tkinter import *
from functools import partial
class ButtonsTest:
def __init__(self):
self.top = Tk()
self.top.title("Click a button to remove")
self.top.geometry("425x200+50+50")
Label(self.top, text=" Click a button to remove it ",
bg="lightyellow", font=('DejaVuSansMono', 12)
).grid(row=0, sticky="nsew")
Button(self.top, text='Exit', bg="orange", width=9,
command=self.top.quit).grid(row=1,column=0,
sticky="nsew")
self.add_scrollbar()
self.button_dic = {}
self.buttons()
self.top.mainloop()
##-------------------------------------------------------------------
def add_scrollbar(self):
self.canv = Canvas(self.top, relief=SUNKEN)
self.canv.config(width=400, height=200)
self.top_frame = Frame(self.canv, height=100)
##---------- scrollregion has to be larger than canvas size
## otherwise it just stays in the visible canvas
self.canv.config(scrollregion=(0,0, 400, 500))
self.canv.config(highlightthickness=0)
ybar = Scrollbar(self.top, width=15, troughcolor="lightblue")
ybar.config(command=self.canv.yview)
## connect the two widgets together
self.canv.config(yscrollcommand=ybar.set)
ybar.grid(row=3, column=2, sticky="ns")
self.canv.grid(row=3, column=0)
self.canv.create_window(1,0, anchor=NW,
window=self.top_frame)
##-------------------------------------------------------------------
def buttons(self):
b_row=1
b_col=0
for but_num in range(1, 51):
## create a button and send the button's number to
## self.cb_handler when the button is pressed
b = Button(self.top_frame, text = str(but_num), width=5,
command=partial(self.cb_handler, but_num))
b.grid(row=b_row, column=b_col)
## dictionary key=button number --> button instance
self.button_dic[but_num] = b
b_col += 1
if b_col > 4:
b_col = 0
b_row += 1
##----------------------------------------------------------------
def cb_handler( self, cb_number ):
print("\ncb_handler", cb_number)
self.button_dic[cb_number].grid_forget()
##===================================================================
BT=ButtonsTest()

How to move image down each time button is pressed Tkinter

I am trying to create a tkinter application where every time you press a button an image moves down a certain number of pixels. For example, the first time it is placed at y=30 and then the next time the button is pressed it is placed at y=60 etc. Is there any way to do this? I do not want to use the pack() method as I need to place the image in a specific location on the screen using x and y coordinates.
import calendar
import tkinter as tk
from tkinter import ttk
root = tk.Tk()
root.geometry('800x800')
def display():
box_image = tk.PhotoImage(file='apple.png')
panel2 = tk.Label(root, image=box_image, bg='#f7f6f6')
panel2.image = box_image
panel2.place(x=30, y=30 + 30) #i was thinking about doing something like adding 30 each time but this didn't work
button = tk.Button(root, text="click me", command=display)
button.place(x=0, y=0)
root.mainloop()
do the following :
import calendar
import tkinter as tk
from tkinter import ttk
root = tk.Tk()
root.geometry('800x800')
x = 30
y = 30
box_image = tk.PhotoImage(file=r'apple.png')
def display():
global x , y
panel2 = tk.Label(root, image=box_image, bg='#f7f6f6')
panel2.place(x=x+30, y=y+30)
x = x+30
y = y+30
button = tk.Button(root, text="click me", command=display)
button.place(x=0, y=0)
root.mainloop()

How to update the ttk progress bar on tkinter

I've got a program that does some simple webscraping. I'm working on giving it to my coworkers to use, but they are unfamiliar with code so I'd like to make a GUI. I've started using tkinter, and I'm currently working on making a progress bar showing where the program is at (it can take up to a couple hours to run). My problem is that I can't seem to get the progress bar to update, and all the online sources use Tkinter, which is an old version. Here is my code:
I've tried updating progressBar['value'] to whatever number I want, but that hasn't been working.
from tkinter import *
from tkinter import ttk
import time
def clicked(progressBar): # runs a couple functions and updates the progress bar when the button is clicked
num = 0
for item in range(5):
# functions go here
num += 10
progressBar['value'] = num
time.sleep(2)
window = Tk()
window.title("Welcome to my app")
window.geometry('600x400')
progressBar = ttk.Progressbar(window, orient='horizontal', length=300, mode='determinate', maximum=100, value=0)
progressBar.grid(columnspan=3, row=2, sticky=(W, E))
btn = Button(window, text="Click me!", command=clicked(progressBar))
btn.grid(column=1, row=1)
window.mainloop()
The tkinter window doesn't open up until 10 seconds after I run the program, and it has the progress bar already at 50% full. I'd like for the bar to slowly increment up, AFTER the button has been clicked. Any advice would be helpful! Thank you!
There are two problems with the code:
command=clicked(progressBar) indeed calls the function promptly.So simply use command=clicked. There is no need to pass progressBar as the argument since the function gets it from global scope.
while the function clicked() is running, GUI freezes. After 5*2sec, progressBar updates to 5*10 abruptly. To update the widgets in a loop, use update_idletastk method:
import tkinter as tk
from tkinter import ttk
import time
def clicked():
num = 0
for item in range(5):
num += 10
progressBar['value'] = num
window.update_idletasks()
time.sleep(2)
window = tk.Tk()
progressBar = ttk.Progressbar(window, orient='horizontal', length=300, mode='determinate', maximum=100, value=0)
progressBar.grid(columnspan=3, row=2, sticky=(tk.W, tk.E))
btn = tk.Button(window, text="Click me!", command=clicked)
btn.grid(column=1, row=1)
window.mainloop()

Is it possible to make progress bar under two buttons

Is it possible to make a Progressbar under two Buttons of "water+" and "water -", Such that when I push Button water+ the Progressbar process one step and when I push Button water- the Progressbar move a step back.
Thank you for all.
Yes, it is possible to set a Progressbar to subtract and add processes depending on the Button presses or on triggered event.
Here is an sample code.
import tkinter as tk
import tkinter.ttk as ttk
root = tk.Tk()
progressbar = ttk.Progressbar(root, length=200, maximum=10, value=5)
progressbar.grid(row=1)
process = tk.IntVar(value=5)
def add_water():
if process.get() < progressbar['maximum']:
process.set( process.get() + 1)
progressbar['value'] = process.get()
def sub_water():
if process.get() > 0:
process.set( process.get() - 1)
progressbar['value'] = process.get()
add = ttk.Button(root, text='Water +', command=add_water)
sub = ttk.Button(root, text='Water -', command=sub_water)
label = ttk.Label(root, textvariable=process)
label.grid(row=0)
add.grid(row=0, sticky='e')
sub.grid(row=0, sticky='w')
root.mainloop()

How to update a progress bar in a loop?

What is the easy method to update Tkinter progress bar in a loop?
I need a solution without much mess, so I can easily implement it in my script, since it's already pretty complicated for me.
Let's say the code is:
from Tkinter import *
import ttk
root = Tk()
root.geometry('{}x{}'.format(400, 100))
theLabel = Label(root, text="Sample text to show")
theLabel.pack()
status = Label(root, text="Status bar:", bd=1, relief=SUNKEN, anchor=W)
status.pack(side=BOTTOM, fill=X)
root.mainloop()
def loop_function():
k = 1
while k<30:
### some work to be done
k = k + 1
### here should be progress bar update on the end of the loop
### "Progress: current value of k =" + str(k)
# Begining of a program
loop_function()
Here's a quick example of continuously updating a ttk progressbar. You probably don't want to put sleep in a GUI. This is just to slow the updating down so you can see it change.
from Tkinter import *
import ttk
import time
MAX = 30
root = Tk()
root.geometry('{}x{}'.format(400, 100))
progress_var = DoubleVar() #here you have ints but when calc. %'s usually floats
theLabel = Label(root, text="Sample text to show")
theLabel.pack()
progressbar = ttk.Progressbar(root, variable=progress_var, maximum=MAX)
progressbar.pack(fill=X, expand=1)
def loop_function():
k = 0
while k <= MAX:
### some work to be done
progress_var.set(k)
k += 1
time.sleep(0.02)
root.update_idletasks()
root.after(100, loop_function)
loop_function()
root.mainloop()

Categories