How can i show the progressbar tkinter while executing another function - python

import camelot
import ghostscript
import os
from tkinter import *
from tkinter import Tk,Canvas,filedialog
from tkinter.ttk import Progressbar
def dataExtraction(file):
fileName=os.path.basename(file)
fileName=filename.replace('.pdf',"")
tables=camelot.read_pdf(file,pages='all')
finalData=pd.DataFrame()
for i,j in enumerate(tables):
data=tabs[i].df
finalData.append(data)
finalData.to_excel(filename+'.xlsx')
def tkWindow():
root=Tk()
w=root.winfo_screenwidth()
h=root.winfo_screenheight()
root.geometry("%d%d" % (w,h))
my_canvas=Canvas(root,width=w,height=h)
my_canvas.pack(fill=both,expand=True)
####upload button####
def openPdf():
global pdffile
pdffile=filedialog.askopenfilename()
return pdffile
upload=Button(root,
width=20,
pady=5,
text='Upload Pdf',
command=openPdf)
pdf_win=my_canvas.create_window(10,350,anchor='nw',window=upload)
###submit button###
def run():
dataExtraction(file)
runbtn=Button(root,
width=10,
pady=5,
command=threading.Thread(target=run).start)
run_win=my_canvas.create_window(550,590,anchor='nw',window=runbtn)
root.mainloop()
tkWindow()
I want to add a progressbar when i am calling dataExtraction function inside run and it will show the progress till the dataExtraction executed once done progressbar should automatically disappear. If anyone can suggest me how can i do that that will be great.

Related

simple window with an enter field

i'm a new programmer and there are certainly several errors but this shouldn't be difficult to spot. I need to create a simple window with a field named "Concorrente 1:" and an entry field displayed by function named lacopertina(). I don't understand where is the error:
import tkinter as tk
from tkinter import *
from tkinter.ttk import *
from tkinter import ttk
class schermoiniziale(tk.Frame):
def lacopertina():
print(gio1)
#return (tot1)
def __init__(self):
global gio1
#tot1=0
#schermo1=Tk()
self.gio1=tk.StringVar()
lab1=ttk.Label(self, text="Concorrente 1:")
lab1.pack()
ent1=ttk.Entry(self, textvariable=self.gio1)
ent1.pack()
pulsante = ttk.Button(self, text="Inizio", textvariable=self.gio1, command=self.lacopertina)
pulsante.pack()
def main():
schermoiniziale().mainloop()
if __name__== "__main__":
main()
I would suggest you to go through some tutorials on Python OOP.
I have modified your code as below with some comment:
# avoid using wildcard import
import tkinter as tk
from tkinter import ttk
class schermoiniziale(tk.Frame):
def __init__(self, master, **kw):
# need to call __init__() of inherited class
super().__init__(master, **kw)
self.gio1 = tk.StringVar()
lab1 = ttk.Label(self, text="Concorrente 1:")
lab1.pack()
ent1 = ttk.Entry(self, textvariable=self.gio1)
ent1.pack()
# removed textvariable=self.gio1 as I think you actually don't need it
pulsante = ttk.Button(self, text="Inizio", command=self.lacopertina)
pulsante.pack()
def lacopertina(self):
# use .get() to get the content of a StringVar
print(self.gio1.get())
def main():
# need to create the root window before creating other widget
root = tk.Tk()
# pass root window as the parent of the widget
frame = schermoiniziale(root)
frame.pack()
# start the tkinter mainloop
root.mainloop()
if __name__== "__main__":
main()

Stop function doesn't work using progressbar

I'm writing a program in tkinter using Progressbar. But there is a problem when I added stop function it doesn't work. When I press "stop" button nothing happens, it should stop loading progressbar. I use Python version 3.8. The code below:
from tkinter import *
from tkinter import ttk
import time
root = Tk()
def run():
pb['maximum']=100
for i in range(101):
time.sleep(0.05)
pb['value']=i
pb.update()
def stop():
pb.stop()
runbutt = Button(root,text="Runprogr",command=run)
runbutt.pack()
stopbutt = Button(root,text="Stopbut",command=stop)
stopbutt.pack()
pb = ttk.Progressbar(root,length=300,orient="horizontal")
pb.pack()
root.geometry("300x300")
root.mainloop()
The cause is that pb.stop couldn't stop the function in run.it will also increase by itself.
You could use .after(ms, callback) to add the value(then you no longer need to use time.sleep()).
If you want to stop it,use .after_cancel():
from tkinter import *
from tkinter import ttk
import time
root = Tk()
root.add_value = None
def run():
def add():
if pb['value'] >= 100:
return
pb['value'] += 1
root.add_value = root.after(50, add)
if root.add_value: # to prevent increasing the speed when user pressed "Runprogr" many times.
return
root.add_value = root.after(50, add)
def stop():
if not root.add_value: # to prevent raising Exception when user pressed "Stopbut" button many times.
return
root.after_cancel(root.add_value)
root.add_value = None
runbutt = Button(root, text="Runprogr", command=run)
runbutt.pack()
stopbutt = Button(root, text="Stopbut", command=stop)
stopbutt.pack()
pb = ttk.Progressbar(root, length=300, orient="horizontal")
pb.pack()
root.geometry("300x300")
root.mainloop()

Tkinter Error: "_tkinter.TclError: invalid command name ".!frame.!entry" PYTHON

I get this error when I insert a value in the textbox.
I want to insert the date in the textbox when selecting it.
Error: _tkinter.TclError: invalid command name ".!frame.!entry"
This is my code:
main.py
from calenderUI import *
from tkinter import *
def Dateselected():
dateSelected=tkCalender()
return str(dateSelected)
def setData():
dateSel=tkCalender()
txtBoxDate.delete(0,END)
txtBoxDate.insert(0,dateSel)
return
root=Tk()
#Frame
miFrame=Frame(root,width=1200,height=2000)
miFrame.pack()
miFrame.config(bg="black")
miLabel=Label(miFrame, text="Date: ",fg="green", bg="black", font="Comic")
miLabel.grid(row=1,column=1,padx=10,pady=10)
txtBoxDate=Entry(miFrame)
txtBoxDate.grid(row=1,column=2,padx=10,pady=10,ipadx=40,ipady=2.5)
buttonDate=Button(miFrame, text="Date",command=lambda:setData())
buttonDate.grid(row=1,column=3,padx=10,pady=10)
root.mainloop()
calenderUI.py
from tkcalendar import Calendar
from tkinter import Tk
from tkinter import ttk
def tkCalender():
def print_sel():
print(cal.selection_get())
root = Tk()
cal=Calendar(root)
cal.pack()
ttk.Button(root, text="Select",command=print_sel).pack()
root.mainloop()
if __name__ == '__tkCalender__':
tkCalender()
Waiting for your help, thanks!
Error fixed, just remove root.mainloop() and some changes to insert the date in textbox (calenderUI.py)
main.py
from calenderUI import *
from tkinter import *
def Dateselected():
dateSelected=tkCalender()
return str(dateSelected)
def setData():
dateSel=tkCalender(txtBoxDate)
root=Tk()
#Frame
miFrame=Frame(root,width=1200,height=2000)
miFrame.pack()
miFrame.config(bg="black")
miLabel=Label(miFrame, text="Date: ",fg="green", bg="black", font="Comic")
miLabel.grid(row=1,column=1,padx=10,pady=10)
txtBoxDate=Entry(miFrame)
txtBoxDate.grid(row=1,column=2,padx=10,pady=10,ipadx=40,ipady=2.5)
buttonDate=Button(miFrame, text="Date",command=setData)
buttonDate.grid(row=1,column=3,padx=10,pady=10)
root.mainloop()
calenderUI.py
from tkcalendar import Calendar
from tkinter import *
dateSelected=""
def tkCalender(e):
def print_sel():
dateSelected=str(cal.selection_get())
txtBoxDate=e.delete(0,END)
txtBoxDate=e.insert(0,dateSelected)
return dateSelected
root = Tk()
cal=Calendar(root)
cal.pack()
ttk.Button(root, text="Select",command=print_sel).pack()
return str(print_sel())
if __name__ == '__tkCalender__':
tkCalender()

python starter screenshot using thread

after going through some stack overflow and external guides still was stuck with an odd problem thread starts but function not executing but used same type of setup in unity c# and visual studio C# windows application but works there fine any help would be appreciated
import tkinter
import threading
import PIL
import time
from datetime import datetime
from PIL import Image
import pyscreenshot as ImageGrab
from tkinter import *
from tkinter import messagebox
from tkinter import Tk, Label, Button, Entry
running=False
class app:
def __init__(self, master):
self.master = master
self.thread1=threading.Thread(target=self.screenshot)
master.title("Screenshot Taker")
Label(master, text="Interval between screenshots").grid(row=0,sticky=W)
self.E1=Spinbox(master, from_ = 5, to = 1000,state = "readonly")
self.E1.grid(row=0,column=2,padx=10)
Label(master, text="File prefix").grid(row=1,sticky=W)
self.E2=Entry(master)
self.E2.grid(row=1,column=2,padx=10)
self.B1=Button(master, text="start" ,command = self.start)
self.B1.grid(row=2,column=0,columnspan=3)
self.B2=Button(master, text="stop" ,command = self.stop)
self.B2.grid(row=2,column=1,columnspan=3)
def screenshot(self):
while(running):
im=ImageGrab.grab()
dt_string = datetime.now().strftime("%d_%m_%Y_%H_%M_%S")
name=str(self.E2.get())+str(dt_string)
logging.debug(name)
im.save(name+".png")
time.sleep(int(self.E1.get()))
def start(self):
running=True
self.thread1.start()
def stop(self):
running=False
self.thread1.join()
root = Tk()
app = app(root)
root.resizable(False, False)
root.mainloop()```
To access a global variable in python, you need to use "global var_name" in each function that needs to access it:
import tkinter
import threading
import PIL
import time
from datetime import datetime
from PIL import Image
import pyscreenshot as ImageGrab
from tkinter import *
from tkinter import messagebox
from tkinter import Tk, Label, Button, Entry
running=False
class app:
def __init__(self, master):
self.master = master
self.thread1=threading.Thread(target=self.screenshot)
master.title("Screenshot Taker")
Label(master, text="Interval between screenshots").grid(row=0,sticky=W)
self.E1=Spinbox(master, from_ = 5, to = 1000,state = "readonly")
self.E1.grid(row=0,column=2,padx=10)
Label(master, text="File prefix").grid(row=1,sticky=W)
self.E2=Entry(master)
self.E2.grid(row=1,column=2,padx=10)
self.B1=Button(master, text="start" ,command = self.start)
self.B1.grid(row=2,column=0,columnspan=3)
self.B2=Button(master, text="stop" ,command = self.stop)
self.B2.grid(row=2,column=1,columnspan=3)
def screenshot(self):
global running
while(running):
im=ImageGrab.grab()
dt_string = datetime.now().strftime("%d_%m_%Y_%H_%M_%S")
name=str(self.E2.get())+str(dt_string)
logging.debug(name)
im.save(name+".png")
time.sleep(int(self.E1.get()))
def start(self):
global running
running=True
self.thread1.start()
def stop(self):
global running
running=False
self.thread1.join()
root = Tk()
app = app(root)
root.resizable(False, False)
root.mainloop()

Open Tkinter multiple Windows with delay (Python)

I've been trying to open several Tkinter windows with a delay of couple seconds between each Tkinter window.
My Script so far :
import Tkinter as tk
import os
from PIL import Image, ImageTk
from win32api import GetSystemMetrics
from time import sleep
from random import uniform
root = tk.Tk()
tk.Label(root, text="this is the root window").pack()
root.geometry("10x10")
l = []
def showPic(i):
if(i<5):
loc = os.getcwd() + '\pictures\pic%s.jpg' % i
img = Image.open(loc)
img.load()
photoImg = ImageTk.PhotoImage(img)
l.append(photoImg)
window = tk.Toplevel()
window.geometry("750x750+%d+%d" % (uniform(0, GetSystemMetrics(0) - 750), uniform(0, GetSystemMetrics(1) - 750)))
tk.Label(window, text="this is window %s" % i).pack()
tk.Label(window, image=photoImg).pack()
root.after(1000, showPic(i+1))
else:
return
root.after(0, showPic(1))
root.mainloop()
I also tried using the sleep() and after() functions with no success.
It waits the time before preparing the window, but shows them all together, simultaniously, after the time I set
after expects function name without () and arguments
Using
root.after(1000, showPic(i+1))
is like
result = showPic(i+1)
root.after(1000, result)
You can use lambda
root.after(1000, lambda:showPic(i+1))
because it is almost like
def new_function():
showPic(i+1)
root.after(1000, new_function)
or
root.after(1000, showPic, i+1)

Categories

Resources