I have a download button when clicked it calls a download function that downloads a video from a media url using wget
example of a video url http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4
from tkinter import *
window = Tk()
name = Entry(window, width=10)
name.grid(column=0, row=0, sticky=W)
url = Entry(window, width=10)
url.grid(column=0, row=1, sticky=W)
dl_button = Button(window, text='download', command=dl) #*********
dl_button.grid(column=2, row=0, sticky=W)
status_lable = Label(window, text='Ready')
status_lable.grid(column=0, row=1, sticky=W)
bar = Progressbar(window, length=200)
bar.grid(column=1, row=1, sticky=W)
window.mainloop()
the dl function opens up 2 threads one for the download and one for the gui, the gui has a progress bar, that i want to be updated alongside the download:
import threading
from tkinter.ttk import Progressbar
import wget
def dl():
def wg():
wget.download(
url.get(), 'C:/Users/Desktop/downloads/'+name.get()+'.mp4')
def update_progress():
status_lable.config(text='Downloading...')
# also update the progress bar, based on the progress of the download from wget
dl_thread = threading.Thread(target=wg)
progress_thread = threading.Thread(target=update_progress)
dl_thread.start()
progress_thread.start()
is this doable, is it doable with somthing other than wget, or is it simply just not doable?
thx.
ok after along research alot of trial and error, i managed to make it,
here's a demo code:
import threading
from tkinter.ttk import Progressbar
import wget
from tkinter import *
def dl():
def update_progress_bar(block_num, block_size, total_size):
bar.config(value=block_num, maximum=block_size)
# when done downloading remove the progress bar
if block_num == block_size:
bar.destroy()
print("Download Complete")
def wg():
wget.download('http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4',
'C:/Users/hanno/Desktop/egybest python/downloads/' + 'koko'+'.mp4', bar= update_progress_bar)
dl_thread = threading.Thread(target=wg)
dl_thread.start()
window = Tk()
dl_button = Button(window, text='download', command=dl)
dl_button.grid(column=2, row=0, sticky=W)
bar = Progressbar(window, length=200)
bar.grid(column=1, row=2)
window.mainloop()
its all about the bar parameter in wget, it takes a function and calles it every block of the download, and sends it the full size of the file, the number of blocks the full size is divided into, and the current block number, then you can update the progress bar for every block inside the called function as shown in the code, good luck all.
important:
I've been told in the comments that calling tkinter methods from an outside thread may cause the the program to crash, I couldn't find any other solution for this problem online or on my own.
thank you #TheLizzard and #Rory
Related
I'm creating a tkinter gui that I would like to run. This app will do some house cleaning of sorts. It would check files, check for updates, give the user some information etc. Then I would like it to start another tkinter application and then close it self.
import tkinter as tk
import os
def StartProgram():
os.startfile("C:/WINDOWS/system32/notepad.exe")
root = tk.Tk()
frame = tk.Frame(root)
frame.pack()
button = tk.Button(frame, text="QUIT", fg="red", command= lambda: quit())
button.pack( side=tk.LEFT)
button2 = tk.Button(frame,text="Start my exe", command=lambda: StartProgram())
button2.pack(side=tk.LEFT)
root.maxsize(200,200)
root.minsize(200,200)
root.mainloop()
The problem I have so far is when I attempt to close the original app it closes the one it started as well.
EDIT: I also tried root.destroy(), root.quit()
Any suggestion how I might correct this?
So, I made a small canvas window with tkinter which has 2 buttons, One is a start button, the other is a stop button. (I'll attach the GUI tkinter code down below. I wont add the Selenium part because I don't want to confuse anyone with mushed up code.) The start button calls a function thats threaded and that launches my "Reporting_Backbone.py" which is a selenium/pyautogui bot that does a bunch of stuff. My problem is that the stop button does not stop the "Reporting_Backbone.py". In the stop button function I've tried sys.exit() but the selenium and the GUI stay open (and running), I've tried daemons (which I might not have been using them correctly because that did nothing)I've tried setting the stop button function to a lambda (which just freezes the GUI, but not the selenium part) and I've tried setting up some kind of a killswitch as a last resort but honestly this thing wont die, its like Thanos fused with Majin Buu. It just keeps running. How do I make it so that the stop button works? I I'm hoping someone can help me with a solution and explanation. I am still new to coding but I am really loving it, if possible I would really like to understand what I am doing wrong. Thank you.
enter code here
import tkinter as tk
from PIL import Image, ImageTk
import time
import os
import threading
import sys
root = tk.Tk()
#Canvas for GUI
canvas = tk.Canvas(root, width=600, height=800)
canvas.grid(columnspan=3, rowspan=4)
canvas.configure(bg="#b9be9c")
#Button Starting
def start_report():
time.sleep(0.5)
start_text.set("Armed!")
os.system("python Reporting_Backbone.py")
#Button Stopping
def stop_craigslist():
stop_text.set('Stopped')
time.sleep(3)
sys.exit()
#Logo
logo = Image.open('Logo.png')
logo = ImageTk.PhotoImage(logo)
logo_label = tk.Label(image=logo)
logo_label.image = logo
#playing logo in window
logo_label.grid(column=1, row=0)
logo_label.configure(bg="#b9be9c")
#instructions
instructions = tk.Label(root, text="Click the 'Start' Button to begin.")
instructions.grid(columnspan=3, column=0, row=1)
instructions.configure(font=("Helvetica", 25) ,bg="#b9be9c")
#Start Button
start_text = tk.StringVar()
start_btn = tk.Button(root, textvariable=start_text, command=threading.Thread(target=start_report).start, font=("Helvetica", 18), fg="black", height=2, width=15)
start_text.set("Start")
start_btn.grid(column=1, row=2)
#Stop Button
stop_text = tk.StringVar()
stop_btn = tk.Button(root, textvariable=stop_text, command=threading.Thread(target=stop_craigslist).start, font=("Helvetica", 18), fg="black", height=2, width=15) #If I set this to a lambda function the Tkinter GUI Freezes up on me
stop_text.set("Stop")
stop_btn.grid(column=1, row=3)
root.mainloop()
You cannot stop the task created by threading.Thread(). Use subprocess instead:
import subprocess
...
proc = None
def start_report():
global proc
if proc and not proc.poll():
print("process is still running")
return
proc = subprocess.Popen([sys.executable, "Reporting_backbone.py"])
start_text.set("Armed!")
def stop_craigslist():
global proc
if proc:
proc.terminate()
proc = None
stop_text.set('Stopped')
...
start_btn = tk.Button(root, ..., command=start_report, ...)
...
stop_btn = tk.Button(root, ..., command=stop_craigslist, ...)
...
Lets say I have two python files. Both with an GUI. First is "Main" second is "Calculator". From Main I will start Calculator. So I have to import calculator. In Calculator I will do a calculation. Lets keep I easy an say 1+1=2. Now I want to "send" this Result to an Text in Main.
How do I do that without an circular import? I cant find an good tutorial/example for that!
My code so far:
Main:
from tkinter import *
import Test_2
window = Tk()
window.title("First Window")
def start():
Test_2.start_second()
Input1 = Entry(window)
Input1.grid(row=0,column=0, padx=10, pady=5)
Start = Button(window,text="Start", command=start)
Start.grid(row=1,column=0, padx=10, pady=5)
window.mainloop()
Second:
from tkinter import *
def start_second():
window2 = Tk()
window2.title("Second Window")
def send():
x = Input.get()
Input2 = Entry(window2)
Input2.grid(row=0,column=0, padx=10, pady=5)
Send = Button(window2,text="Send", command=send)
Send.grid(row=1,column=0, padx=10, pady=5)
window2.mainloop()
This code does exactly what you asked for (as opposed to what I suggested in the comment; but anyway, you either get a value from a module function or you send a reference for it to alter)
I tried to follow your structure.
Basically it is a matter of sending the parent window and the first entry as parameters to the second window creation function. Don't call mainloop two times, just once in the end, and use Toplevel for all other windows after the main Tk one. This is not to say that I like the use of an inner function and of the lambda, for readability, but lambdas are necessary in tkinter everytime you want to send parameters to a command callback, otherwise it will get called right way in command definition.
tkinter_w1.py (your main.py)
from tkinter import Tk, ttk
import tkinter as tk
from tkinter_w2 import open_window_2
root = Tk()
entry1 = ttk.Entry(root)
button1 = ttk.Button(root, text='Open Window 2',
command=lambda parent=root, entry=entry1:open_window_2(parent, entry))
entry1.pack()
button1.pack()
root.mainloop()
tkinter_w2.py (your Test_2.py)
from tkinter import Tk, ttk, Toplevel
import tkinter as tk
def open_window_2(parent, entry):
def send():
entry.delete(0,tk.END)
entry.insert(0,entry2.get())
window2 = Toplevel(parent)
entry2 = ttk.Entry(window2)
button2 = ttk.Button(window2, text='Send', command=send)
entry2.pack()
button2.pack()
How can I visualize an url of an image with tkinter ("http://images.amazon.com/images/P/0374157065.01.LZZZZZZZ.jpg").I would like to place it in the last column of the program, in standard size, I tried many guides but none of them ever worked. Thanks very mutch
Why not bind a URL to a Label like this?
from tkinter import *
import webbrowser
def callback(event):
webbrowser.open_new(r"http://www.your-image.com")
root = Tk()
link = Label(root, text="The image", fg="blue", cursor="hand2")
link.pack()
link.bind("<Button-1>", callback)
root.mainloop()
I have been studying on using Tkinter to open exe files from the one Tkinter software. My end product was a Windows 7 exe file that ran all the exe files from the one Tkinter software that was converted to exe file.
I will explain my code going from top to bottom
This is my Tkinter Template of sorts
from Tkinter import *
from PIL import Image, ImageTk
import os
class App:
def __init__(self, master):
self.frame = Frame(master)
I added a image to give users information How to use the software
img = Image.open("data.gif")
intro = ImageTk.PhotoImage(img)
right = Label(None, image=intro)
right.grid(row=0, column=0, columnspan=4)
right.image=intro
then I added Buttons to the grid, calling every button self.b realy confused people here at stack overflow. you will read the comments soon.
self.b = Button(self.frame, bg="red", fg="white", font=("Helvetica", 14), text = ' \n confilextracter \n ', command = self.openFile1)
self.b.grid(row = 1, column=0)
self.b = Button(self.frame, bg="red", fg="white", font=("Helvetica", 14), text = ' \n confileditor \n ', command = self.openFile2)
self.b.grid(row = 1, column=1)
self.b = Button(self.frame, bg="red", fg="white", font=("Helvetica", 14), text = ' \n confilerehasher \n ', command = self.openFile3)
self.b.grid(row = 1, column=2)
self.b = Button(self.frame, bg="red", fg="white", font=("Helvetica", 14), text = ' \n Turn off the Shed \n ', command = self.openFile4)
self.b.grid(row = 1, column=3)
self.frame.grid()
Next I had to give the buttons jobs to carry out, renaming exe files realy confused people here at stack overflow. sorry about that.
def openFile1(self):
os.startfile("confilextracter.exe")
def openFile2(self):
os.startfile("confileditor.exe")
def openFile3(self):
os.startfile("confilerehasher.exe")
I realy wanted the last button code corrected witch I found the answer myself because everyone else was busy sorting out all the other parts of this code as you will see soon enough. at this point in time this next button has errors in it.
def openFile4(self):
self.b.configure(command = self.b.destroy)
Then I closed the file
root = Tk()
app = App(root)
mainloop()
Using the os module:
from Tkinter import *
import os
class App:
def __init__(self, master):
self.frame = Frame(master)
self.b = Button(self.frame, text = 'Open', command = self.openFile)
self.b.grid(row = 1)
self.frame.grid()
def openFile(self):
os.startfile(_filepath_)
root = Tk()
app = App(root)
root.mainloop()
This is what I did to make things work,
I took f3ar3dlegend example code (scroll up) and started working on it as it worked pretty good.
Lets talk about the top lines of code and work our way down for a full breakdown.
from Tkinter import *
from PIL import Image, ImageTk
import os
from Tkinter import, this tells pyhton to load the GUI drivers. from PIL import Image, ImageTK tell Python to load Pyhton image library so we can use color photos. import os this to my understanding loads drivers so Python can run outside programs from a python app calling them into action.
The first thing I did was to add a image to f3ar3dlegend's code to give my users a information page with this code,
class App:
def __init__(self, master):
self.frame = Frame(master)
img = Image.open("data.gif")
intro = ImageTk.PhotoImage(img)
right = Label(None, image=intro)
right.grid(row=0, column=0, columnspan=4)
right.image=intro
One line of code was stoping me image from apearing for a good 24 hours was just simply missing code
right.image=intro
This line of code stops your image being garbage collected (what ever that means) I just know I added it and my photos should up when put inside a def.
The Next thing I put a lot of work into was Button formating, you know width size color Font. Figgering out to use self.frame was pure guesswork I just kept trying ideas until one of my trys worked. I also have this whole thing on a Python Tkinter Grid so the image went on row 0 and column spaned 4 or 5 colums to make way for more buttons. These Buttons all went on row 1 not row 0. I found I could call all the buttons self.b as long as the command was to a different def the code was error free.
self.b = Button(self.frame, bg="darkred", width=18, fg="white", font=("Arial", 14), text = ' \n confilextracter \n ', command = self.openFile1)
self.b.grid(row = 1, column=0)
self.b = Button(self.frame, bg="red", width=17, fg="white", font=("Arial", 14), text = ' \n confileditor \n ', command = self.openFile2)
self.b.grid(row = 1, column=1)
The next thing I did was def's as buttons don't work without these. What made stock overflow think I was uploading a virus was that I changed the programe names to make me understand my programing better.
def openFile1(self):
os.startfile("confilextracter.exe")
def openFile2(self):
os.startfile("confileditor.exe")
It works like this. openFile1 is a Button callout. You press the button and it gives out a callout and the matching def obeys the anser to the call. os.startfile is a new term to me but it simply means operating system start file. ("confileditor.exe") is saying the string name of the file you need is between (" ") put the two together and the file runs in its own window.
The last bit of this software i peaced together and then said I can do more with this. I started off using f3ar3dlegend example code again.
root = Tk()
app = App(root)
mainloop()
This basicly turns everything off so Python knows it's time to display stuff and mainloop tells Tkinter to wait for me to do stuff. Problem was the software was opening sometime half on the page and at other times anywhere on the screen so I added this code to put the software at the top left of the screen.
app = App(root)
root.geometry('+0+0')
mainloop()
One last thing I did was to get a button to Exit the software at the click of a button after trying 5 or 6 trys I got Tkinter to destroy the software window with the push of a button. the code is.
self.b = Button(self.frame, bg="red", width=18, fg="white", font= ("Arial", 14), text = ' \n Turn off the Shed \n ', command = self.openFile4)
self.b.grid(row = 1, column=3)
def openFile4(self):
root.destroy()
I have seen counless examples on stack overflow of people using root.destory wrongy, is it any wonder I tinkered with it for 1 hour to get it just right.
One very important lesson I did learn about putting programs online so people can download them is You need to contact Customber support of your host and Demand a link to there TOS terms of service because if you don't understand TOS your probably breaking international laws to do with publishing. Thank you.