How to create a download bar in python - python

So I am working on this program that is supposed to be downloading stuff from the web using tkinter and urllib.request but it is lacking a download bar(or a progress bar if that is the true word). So I found out that you can create a progress bar using TQDM but there are two problems: first of all, I didn't seem to find a way to use it in a tkinter program. Second of all, It doesn't show the download speed, you just set a limit and it fills up until it reaches that limit. I did a bit of research again and I found out that you can create a progress bar using ttk but it still has the second problem(It does not show the user's internet(download) speed and that how much of the file has been downloaded like chrome's download bar).
Can someone help me out on this?
My code(BTW if you have any suggestions how to make my program better I would appreciate it):
from tkinter import *
from tkinter import font as tkFont
import random
import urllib.request
import requests
from tqdm import tqdm
from tqdm.auto import tqdm
def printsth():
print("Yay it works! ")
def main_menu():
root = Tk()
# the top menu
num = IntVar()
# var = IntVar()
menu = Menu(root)
root.config(menu=menu)
submenu = Menu(menu)
menu.add_cascade(label="Settings", menu=submenu)
def custom_op():
custom = Tk()
custom.mainloop()
submenu.add_command(label="Customization ", command=custom_op)
def settings_op():
set_win = Tk()
set_win.mainloop()
submenu.add_command(label="Settings ", command=settings_op)
submenu.add_separator()
submenu.add_command(label="Exit", command=root.destroy)
# the edit menu
editmenu = Menu(menu)
menu.add_cascade(label="Edit", menu=editmenu)
editmenu.add_command(label="Redo...", command=printsth)
# the tool bar
toolbar = Frame(root, bg="light gray")
insert_button = Button(toolbar, text="Insert an image", command=printsth)
insert_button.pack(side=LEFT, padx=2, pady=2)
print_button = Button(toolbar, text="Print", command=printsth)
print_button.pack(side=LEFT, padx=2, pady=2)
toolbar.pack(side=TOP, fill=X)
# the download function
def download_image():
global formatname
if num.get() == 1:
name = random.randrange(1, 100000)
else:
name = str(name_entry.get())
formatname = str(format_entry.get())
'''if var.get() == 1:
operator = str(url_entry.get())
formatname = '.' + operator[-3] + operator[-2] + operator[-1]
else:
pass'''
fullname = str(name) + formatname
url = str(url_entry.get())
fw = open('file-size.txt', 'w')
file_size = int(requests.head(url, headers={'accept-encoding': ''}).headers['Content-Length'])
fw.write(str(file_size))
fw.close()
path = str(output_entry.get()) + "\\"
urllib.request.urlretrieve(url, path.replace("\\", "\\\\") + fullname)
# the status bar
status_bar = Label(root, text="Downloading...", bd=1, relief=SUNKEN, anchor=W)
status_bar.pack(side=BOTTOM, fill=X)
# the download frame
body_frame = Frame(root, bg="light blue")
download_button = Button(body_frame, text="Download! ", command=download_image, border=3, width=20, height=5)
download_design = tkFont.Font(size=12, slant='italic')
download_button['font'] = download_design
download_button.pack(side=LEFT, pady=5, padx=5)
body_frame.pack(side=LEFT, fill=Y)
# the main interaction menu
inter_frame = Frame(root)
url_entry = Entry(inter_frame)
label = Label(inter_frame, text="Enter the image URL: ")
file_format = Label(inter_frame, text="Choose your file format: ")
format_entry = Entry(inter_frame)
file_name = Label(inter_frame, text="File's name: ")
name_entry = Entry(inter_frame)
check_name = Checkbutton(inter_frame, text="Give a random name", variable=num)
# check_format = Checkbutton(inter_frame, text="Download with default format", variable=var)
output_path = Label(inter_frame, text="Choose output path: ")
output_entry = Entry(inter_frame)
file_name.pack(anchor=CENTER, expand=1)
name_entry.pack(anchor=CENTER, expand=1)
check_name.pack(anchor=CENTER, expand=1)
label.pack(anchor=CENTER, expand=1)
url_entry.pack(anchor=CENTER, expand=1)
file_format.pack(anchor=CENTER, expand=1)
format_entry.pack(anchor=CENTER, expand=1)
# check_format.pack(anchor=CENTER)
output_path.pack(anchor=CENTER, expand=1)
output_entry.pack(anchor=CENTER, expand=1)
inter_frame.pack(expand=1)
root.mainloop()
# the end!
main_menu()

This is code snippet from my tool for status bar
progress = ttk.Progressbar(self, orient=HORIZONTAL, length=400, mode='determinate')
progress.grid(row=3, column=0, pady=2, padx=2, columnspan=4, sticky=SW+SE)
progress.pack(side=BOTTOM, anchor=S, expand=YES)
progress["maximum"] = 100
progerss_part = 0
you can update progress by using
progress["value"] = x
Hope this will help you.

Related

Is there a way to add audio to Tkinter video player?

When I run this code a window pops up and I can upload a video of which I can play/stop/pause the video; however the video will not have sound. Is there any way I can solve this issue? I am new to Python. Thanks.
from tkinter import *
from tkinter.filedialog import askopenfile
from tkVideoPlayer import TkinterVideo
# customtkinter.set_appearance_mode("System") # Modes: system (default), light, dark
# customtkinter.set_default_color_theme("blue") # Themes: blue (default), dark-blue, green
# create box
window = Tk()
# title of the box, not the text in the box
window.title("Tkinter Play Videos in Video Player")
window.geometry("700x450")
window.configure(bg="white")
def open_file():
file = askopenfile(mode='r', filetypes=[
('Video Files', ["*.mp4"])])
if file is not None:
global filename
filename = file.name
global videoplayer
videoplayer = TkinterVideo(master=window, scaled=True)
videoplayer.load(r"{}".format(filename))
videoplayer.pack(expand=True, fill="both")
videoplayer.play()
def playAgain():
print(filename)
videoplayer.play()
def StopVideo():
print(filename)
videoplayer.stop()
def PauseVideo():
print(filename)
videoplayer.pause()
# center this label
lbl1 = Label(window, text="Video Player", bg="white",
fg="blue", font="none 24 bold")
lbl1.config(anchor=CENTER)
lbl1.pack()
openbtn = Button(window, text='Open', command=lambda: open_file())
openbtn.pack(side=TOP, pady=2)
playbtn = Button(window, text='Play Video', command=lambda: playAgain())
playbtn.pack(side=TOP, pady=3)
stopbtn = Button(window, text='Stop Video', command=lambda: StopVideo())
stopbtn.pack(side=TOP, padx=4)
pausebtn = Button(window, text='Pause Video', command=lambda: PauseVideo())
pausebtn.pack(side=TOP, padx=5)
window.mainloop()
The result video does not have audio.

Option menu alignment issue tkinter

I am trying to have two dropdown lists bellow two labels stating what they are. The problem is whenever i run it the second list is offset to the left. This takes place in the setupPage section and looks like so:
image of the issue
I have tried lots of combinations of sticky to no avail. Any help would be appreciated.
Code:
from tkinter import *
from tkinter import ttk
root = Tk()
def startPage(root):
content = ttk.Frame(root) #frame for plaing everything into
#frame = ttk.Frame(content, borderwidth=5, relief="sunken", width=200, height=100) #fram for plaxing images
lbl1 = ttk.Label(content, text="Is this a new or existing site?",font=("arial",12)) #setup of label for screen 1
yesvar = BooleanVar() #variables for check boxes later on
novar = BooleanVar()
yesvar.set(False)
novar.set(False)
one = ttk.Checkbutton(content, text="Yes", variable=yesvar, onvalue=True) #check buttons setup
two = ttk.Checkbutton(content, text="No", variable=novar, onvalue=True)
ok = ttk.Button(content, text="New", command = nextPage) #setup for buttons screen 1
cancel = ttk.Button(content, text="Existing")
content.grid(column=0, row=0) #intilises content
#frame.grid(column=0, row=0, columnspan=3, rowspan=2)
lbl1.grid(column=0, row=0, columnspan=3,pady=10,padx=10) #places the label asking the question with a gap either side for the window bindings
#name.grid(column=3, row=1, columnspan=2)
#one.grid(column=0, row=3)
#two.grid(column=1, row=3)
ok.grid(column=0, row=1,pady=10,padx=10) #places yes button 10 away from each edge
cancel.grid(column=1, row=1,pady=10,padx=10) #as above
def setupPage(root):
content = ttk.Frame(root) #frame for plaing everything into
#frame = ttk.Frame(content, borderwidth=5, relief="sunken", width=200, height=100) #fram for plaxing images
lbl1 = ttk.Label(content, text="Select meterial 1",font=("arial",12)) #setup of label for screen 1
lbl2 = ttk.Label(content, text = "Select meterial 2" ,font = ("arial",12))
content.grid(column=0, row=0)
lbl1.grid(column=0, row=0,columnspan=1, pady=10,padx=10)
lbl2.grid(column=1,row=0,columnspan=1,pady=10,padx=10)
clicked = StringVar()
clicked.set("lo2")
clicked2 = StringVar()
clicked2.set("lo2")
drop2 = OptionMenu(root, clicked2, "lo2", "mo3", "Lo2+mo3")
drop = OptionMenu(root, clicked, "lo2", "mo3", "Lo2+mo3")
drop.grid(column=0, row=1,pady=10,padx=10,sticky=NW)
drop2.grid(column=1, row=1,pady=10,padx=10,sticky=NW)
def nextPage():
global pagenum, root
for widget in root.winfo_children():
widget.destroy()
if pagenum == 1:
setupPage(root)
pagenum = 2
else :
startPage(root)
pagenum = 1
startPage(root)
pagenum = 1
root.mainloop()
The parent of the labels and the OptionMenus are different.
Changing the parents to root instead of content seems to work
from tkinter import *
from tkinter import ttk
root = Tk()
def startPage(root):
print("oi")
content = ttk.Frame(root) #frame for plaing everything into
#frame = ttk.Frame(content, borderwidth=5, relief="sunken", width=200, height=100) #fram for plaxing images
lbl1 = ttk.Label(content, text="Is this a new or existing site?",font=("arial",12)) #setup of label for screen 1
yesvar = BooleanVar() #variables for check boxes later on
novar = BooleanVar()
yesvar.set(False)
novar.set(False)
one = ttk.Checkbutton(content, text="Yes", variable=yesvar, onvalue=True) #check buttons setup
two = ttk.Checkbutton(content, text="No", variable=novar, onvalue=True)
ok = ttk.Button(content, text="New", command = nextPage) #setup for buttons screen 1
cancel = ttk.Button(content, text="Existing")
content.grid(column=0, row=0) #intilises content
#frame.grid(column=0, row=0, columnspan=3, rowspan=2)
lbl1.grid(column=0, row=0, columnspan=3,pady=10,padx=10) #places the label asking the question with a gap either side for the window bindings
#name.grid(column=3, row=1, columnspan=2)
#one.grid(column=0, row=3)
#two.grid(column=1, row=3)
ok.grid(column=0, row=1,pady=10,padx=10) #places yes button 10 away from each edge
cancel.grid(column=1, row=1,pady=10,padx=10) #as above
def setupPage(root):
#content = ttk.Frame(root) #frame for plaing everything into
#frame = ttk.Frame(content, borderwidth=5, relief="sunken", width=200, height=100) #fram for plaxing images
lbl1 = ttk.Label(root, text="Select meterial 1",font=("arial",12)) #setup of label for screen 1
lbl2 = ttk.Label(root, text = "Select meterial 2" ,font = ("arial",12))
#content.grid(column=0, row=0)
lbl1.grid(column=0, row=0,columnspan=1, pady=10,padx=10)
lbl2.grid(column=1,row=0,columnspan=1,pady=10,padx=10)
clicked = StringVar()
clicked.set("lo2")
clicked2 = StringVar()
clicked2.set("lo2")
drop2 = OptionMenu(root, clicked2, "lo2", "mo3", "Lo2+mo3")
drop = OptionMenu(root, clicked, "lo2", "mo3", "Lo2+mo3")
drop.grid(column=0, row=1,pady=10,padx=10,sticky=NW)
drop2.grid(column=1, row=1,pady=10,padx=10,sticky=NW)
def nextPage():
print("oi2")
global pagenum, root
for widget in root.winfo_children():
widget.destroy()
if pagenum == 1:
print("oi3")
setupPage(root)
pagenum = 2
else :
startPage(root)
pagenum = 1
startPage(root)
pagenum = 1
root.mainloop()

Updating label text in frame when job is finished

When pressing "Ping test" you get a new 'main window' with input and submit button.
when Submit is clicked, a file is created on the desktop and writes the output result of ping command.
right now, when I enter an address and click submit, I only see the menu frame and the main frame, the output frame shows up when the proccess is finished.
how can I make the output frame show "Pinging..." when I click the Submit button and update the label to "Ping Complete!" when its finished?
here's my code:
import tkinter as tk
import subprocess as sub
import easygui
import os
root = tk.Tk()
root.geometry("400x300")
# ===== Frame 1 - Left Menu =====
frame = tk.LabelFrame(root, text="Menu",height=80, width=40,
padx=5, pady=5, relief="solid")
frame.place(x=10, y=0)
# Show files button
showfilesButton = tk.Button(frame, text="Show Files", padx=5, pady=5,
command=lambda: showFiles())
showfilesButton.grid(row=1, column=0)
# ConvertURL button
convertURL = tk.Button(frame, text="Ping Test", padx=5, pady=5,
command=lambda: testPing.getURL())
convertURL.grid(row=2, column=0)
# Quit Button
endProgram = tk.Button(frame, text="Quit", padx=5, pady=5,
command=lambda: terminate())
endProgram.grid(row=3, column=0)
class testPing():
def __init__(self, host):
self.host = host
self.clearFile = clearFile
self.label = label
def getURL():
frame2 = tk.LabelFrame(root, text="Main Window", height=350, width=300, padx=30, pady=30)
frame2.pack()
urlLabel = tk.Label(frame2, text="Enter URL : ", padx=5, pady=5)
urlLabel.place(x=-30, y=-30)
urlInputBox = tk.Entry(frame2)
urlInputBox.pack()
clearLabel = tk.Label(frame2, text="Clear File?", padx=5, pady=5)
clearLabel.place(x=-30, y=20)
clearFile = tk.BooleanVar()
clearFile.set(False)
clearFileRadioYes = tk.Radiobutton(frame2, text="yes", value=True, var=clearFile,
command=lambda: testPing.callback(clearFile.get()))
clearFileRadioYes.place(x=-30, y=45)
clearFileRadioNo = tk.Radiobutton(frame2, text="no", value=False, var=clearFile,
command=lambda: testPing.callback(clearFile.get()))
clearFileRadioNo.place(x=20, y=45)
urlSubmitButton = tk.Button(frame2, text="Submit",
command=lambda: testPing.pingURL(urlInputBox.get(), clearFile.get()))
urlSubmitButton.pack(side=tk.RIGHT)
def callback(clearFile):
bul = clearFile
print(bul)
def pingURL(host, clearFile):
outputLabel = tk.LabelFrame(root, text="Output", height=35, width=150,
padx=5, pady=5, relief="solid")
outputLabel.place(x=0, y=150)
file = fr'c:/users/{os.getlogin()}/Desktop/ping.txt'
label = tk.Label(outputLabel, text=f'Pinging {host} ...')
label.grid(row=0, column=0)
clear = clearFile
if clear == True:
with open(file, 'w+') as output:
output.truncate(0)
sub.call(['ping', f'{host}'], stdout=output)
else:
with open(file, 'a') as output:
sub.call(['ping', f'{host}'], stdout=output)
output.close()
# testPing.changeLabel(host)
def changeLabel(host):
myLabel = tk.Label.config(text=f"Ping to {host} Complete!")
myLabel.pack()
def terminate():
exit()
def showFiles():
path = easygui.diropenbox() # Opens a folder dialog box.
folder = path
filelocation = f"c:\\Users\\{os.getlogin()}\\Desktop\\showFilesResult.txt"
filenames = os.listdir(folder) # Get the file names in the folder.
# Writing to file
with open(filelocation, 'a') as file:
for name in filenames:
file.write(f"Name: {name}\nFolder Path: {folder}\n!------------------------------!\n")
print("Done!")
root.mainloop()
Instead of calling changeLabel(), you can simply put:
output.close()
label.configure(text=f'Ping to {host} complete!')
# testPing.changeLabel(host)
But remember about updating your label first, if you don't at the end only complete label will be visible.
label = tk.Label(outputLabel, text=f'Pinging {host} ...')
label.grid(row=0, column=0)
label.update()
An additional tip, don't use different GUI creators in one project. If you only using easygui to get the path, check Tkinter methods -> askopenfilename and asksaveasfilename.

How to receive the size of the file that the user wants to retrieve using urllib in python

I am basically a newbie in python and I am building this downloader program in python using tkinter and urllib.request and it is quite done but as a final touch I wanted to add a progress bar to show how much the file is downloaded. I found out that I can add a progress bar using TQDM but first I should have gotten the size of the file that the user wants to downloaded to show how much the program has downloaded it and I didn't find anything! Can anyone help me out?
My code(BTW if you have any idea how to make my code better I would appreciate it):
from tkinter import *
from tkinter import font as tkFont
import random
import urllib.request
def printsth():
print("Yay it works! ")
def main_menu():
root = Tk()
# the top menu
num = IntVar()
var = IntVar()
menu = Menu(root)
root.config(menu=menu)
submenu = Menu(menu)
menu.add_cascade(label="File", menu=submenu)
submenu.add_command(label="New project...", command=printsth)
submenu.add_command(label="New ", command=printsth)
submenu.add_separator()
submenu.add_command(label="Exit", command=root.destroy)
# the edit menu
editmenu = Menu(menu)
menu.add_cascade(label="Edit", menu=editmenu)
editmenu.add_command(label="Redo...", command=printsth)
# the tool bar
toolbar = Frame(root, bg="light gray")
insert_button = Button(toolbar, text="Insert an image", command=printsth)
insert_button.pack(side=LEFT, padx=2, pady=2)
print_button = Button(toolbar, text="Print", command=printsth)
print_button.pack(side=LEFT, padx=2, pady=2)
toolbar.pack(side=TOP, fill=X)
# the status bar
status_bar = Label(root, text="This is only an example...", bd=1, relief=SUNKEN, anchor=W)
status_bar.pack(side=BOTTOM, fill=X)
# the download frame
def download_image():
global formatname
if num.get() == 1:
name = random.randrange(1, 10000)
else:
name = str(name_entry.get())
formatname = str(format_entry.get())
'''if var.get() == 1:
operator = str(url_entry.get())
formatname = '.' + operator[-3] + operator[-2] + operator[-1]
else:
pass'''
fullname = str(name) + formatname
url = str(url_entry.get())
urllib.request.urlretrieve(url, fullname)
body_frame = Frame(root, bg="light blue")
download_button = Button(body_frame, text="Download! ", command=download_image, border=3, width=20, height=5)
download_design = tkFont.Font(size=12, slant='italic')
download_button['font'] = download_design
download_button.pack(side=LEFT, pady=5, padx=5)
body_frame.pack(side=LEFT, fill=Y)
# the main interaction menu
inter_frame = Frame(root)
url_entry = Entry(inter_frame)
label = Label(inter_frame, text="Enter the image URL: ")
file_format = Label(inter_frame, text="Choose your file format: ")
format_entry = Entry(inter_frame)
file_name = Label(inter_frame, text="File's name: ")
name_entry = Entry(inter_frame)
check_name = Checkbutton(inter_frame, text="Give a random name", variable=num)
check_format = Checkbutton(inter_frame, text="Download with default format", variable=var)
file_name.pack(anchor=CENTER, expand=1)
name_entry.pack(anchor=CENTER, expand=1)
check_name.pack(anchor=CENTER, expand=1)
label.pack(anchor=CENTER, expand=1)
url_entry.pack(anchor=CENTER, expand=1)
file_format.pack(anchor=CENTER, expand=1)
format_entry.pack(anchor=CENTER, expand=1)
# check_format.pack(anchor=CENTER)
inter_frame.pack(expand=1)
root.mainloop()
# the end!
main_menu()
To get the size do a HEAD requests:
file_size = int(requests.head('https://www.cs.cmu.edu/~./enron/enron_mail_20150507.tar.gz', headers={'accept-encoding': ''}).headers['Content-Length'])
Or a GET requests (may be incorrect):
file size = int(requests.get('https://www.cs.cmu.edu/~./enron/enron_mail_20150507.tar.gz').headers['Content-Length'])

Get text using entry.get() in tkinter and store into variable

Below is code:
import os
from tkinter.filedialog import askopenfilename
from tkinter import *
#~~~~ FUNCTIONS~~~~
def open_file_1():
global file_path_1
filename_1 = askopenfilename()
file_path_1 = os.path.dirname(filename_1) + filename_1
entry_1.delete(0, END)
entry_1.insert(0, file_path_1)
return file_path_1
def open_file_2():
global file_path_2
filename_2 = askopenfilename()
file_path_2 = os.path.dirname(filename_2) + filename_2
entry_3.delete(0, END)
entry_3.insert(0, file_path_2)
return file_path_2
def title_name_1():
global title_1
title_1=str(entry_4.get())
return title_1
def title_name_2():
global title_2
title_2=str(entry_5.get())
return title_2
def process_file(content):
print(file_path_1)
print(file_path_2)
print(title_1)
print(title_2)
#~~~~~~ GUI ~~~~~~~~
root = Tk()
root.title('Test Project')
root.geometry("698x220+350+200")
mf = Frame(root)
mf.pack()
f1 = Frame(mf, width=600, height=250)
f1.pack(fill=X)
f3 = Frame(mf, width=600, height=250)
f3.pack(fill=X)
f4 = Frame(mf, width=600, height=250)
f4.pack(fill=X)
f5 = Frame(mf, width=600, height=250)
f5.pack(fill=X)
f2 = Frame(mf, width=600, height=250)
f2.pack()
file_path_1 = StringVar
file_path_2 = StringVar
title_1 = StringVar
title_2 = StringVar
Label(f1,text="Select File 1").grid(row=0, column=0, sticky='e')
Label(f3,text="Select File 2").grid(row=0, column=0, sticky='e')
Label(f4,text="Title1").grid(row=0, column=0, sticky='e')
Label(f5,text="Title2").grid(row=0, column=0, sticky='e')
entry_1 = Entry(f1, width=50, textvariable=file_path_1)
entry_1.grid(row=0,column=1,padx=2,pady=2,sticky='we',columnspan=25)
Button(f1, text="Browse", command=open_file_1).grid(row=0, column=27, sticky='ew', padx=8, pady=4)
entry_3 = Entry(f3, width=50, textvariable=file_path_2)
entry_3.grid(row=0,column=1,padx=2,pady=2,sticky='we',columnspan=25)
Button(f3, text="Browse", command=open_file_2).grid(row=0, column=27, sticky='ew', padx=8, pady=4)
entry_4 = Entry(f4, width=50,textvariable=title_1)
entry_4.grid(row=0,column=1,padx=5,pady=2,sticky='we',columnspan=25)
entry_5 = Entry(f5, width=50,textvariable=title_2)
entry_5.grid(row=0,column=1,padx=5,pady=2,sticky='we',columnspan=25)
Button(f2, text="Submit", width=32, command=lambda: process_file(content)).grid(sticky='ew', padx=10, pady=70)
root.mainloop()
I want to get these 4 fields(file_path_1, file_path_2, Title1, Title2) and store them so that can be used for further manipulation.I am using Browse to select files and user will enter text for Title1 and Title2.I am new to this, so didn't have much idea.
You are complicating your life unnecessarily by using StringVar(). StringVar's are mostly useful if you attach observer callbacks to them...
Most of the time for Entry widgets, it is better to get their content with the .get() method just before using it:
def process_file():
# Get Entry box content
filename_1 = entry_1.get()
# Do something with it
print(filename_1)

Categories

Resources