I have a tkinter application, with a text widget in it.
The I tried to add a paste function:
def paste(self):
self.text.insert('insert', self.text.clipboard_get())
But when the clipboard has no content, it pastes None.
I tried using a if condition to fix this:
if self.text.clipboard_get() == 'None':
...
It fixes some errors, but when the clipboard has 'None', it won't paste.
So how can I fix this?
Thanks for any help!
Here clipboard_get() with an empty clipboard raise an error.
import tkinter as tk
from tkinter import ttk
root = tk.Tk()
text = tk.Text()
text.clipboard_clear()
try:
clip_text = text.clipboard_get()
print(clip_text)
except tk.TclError:
print('clipboard is empty')
from pytube import YouTube
from tkinter import filedialog
from tkinter import ttk
from tkinter import*
import threading
import re
class Application:
def __init__(self,root):
self.root=root
self.root.grid_rowconfigure(0,weight=2)
self.root.grid_columnconfigure(0,weight=1)
self.root.config(bg="#ffdddd")
top_label=Label(self.root,text="YouTube download manager",fg="blue",font=("ALGERIAN",70))
top_label.grid(pady=(0,10))
link_label=Label(self.root,text="Please paste your YouTube video link",bg="black",fg="red",font=("Agency FB",30))
link_label.grid(pady=(0,20))
self.YoutubeEntryVar=StringVar()
self.YoutubeEntry=Entry(self.root,width=70,textvariable=self.YoutubeEntryVar,font=("Lucida Console",25),fg="blue")
self.YoutubeEntry.grid(pady=(0,20),ipady=5)
self.YoutubeEntryError=Label(self.root,text="",font=("Colonna MT",20),fg="green")
self.YoutubeEntryError.grid(pady=(0,8))
self.YoutubeFileSave=Label(self.root,text="Choose Directory",font=("Agency FB",20),fg="black")
self.YoutubeFileSave.grid(pady=(0,8))
self.YoutubeButton=Button(self.root,text="Directory",font=("Colonna MT",20),command=self.FileDirectory)
self.YoutubeButton.grid(pady=(10,3),ipady=5)
self.FileLocation=Label(self.root,text="",font=("Harlow Solid Italic",20))
self.FileLocation.grid()
self.DownloadSelect=Label(self.root,text="Choose the format to download",font=("Century Gothic",20))
self.DownloadSelect.grid()
self.DownloadChoice=[("Audio MP3",1),("Video MP4",2)]
self.Choice=StringVar()
self.Choice.set(1)
for text,mode in self.DownloadChoice:
self.YoutubeChoice=Radiobutton(self.root,text=text,font=("Candara",10),variable=self.Choice,value=mode)
self.YoutubeChoice.grid()
self.DownloadButton=Button(self.root,text="Download",font=("Lucida Console",10),command=self.checkLink)
self.DownloadButton.grid(pady=(5,5))
def checkLink(self):
self.youtubeMatch=re.match("https://www.youtube.com/",self.YoutubeEntryVar.get())
if(not self.youtubeMatch):
self.YoutubeEntryError.config(text="Please choose a valid YouTube link !!")
elif(not self.FolderName):
self.FileLocation.config(text="Please choose a directory !!",fg="red")
elif(self.youtubeMatch and self.FolderName):
self.downloadFile()
def downloadFile(self):
self.newWindow=Toplevel(self.root)
self.root.withdraw()
self.newWindow.state("zoomed")
self.newWindow.grid_rowconfigure(0,weight=2)
self.newWindow.grid_columnconfigure(0,weight=1)
self.app=Second(self.newWindow,self.YoutubeEntryVar.get(),self.FolderName,self.Choice.get())
def FileDirectory(self):
self.FolderName=filedialog.askdirectory()
if(len(self.FolderName)>0):
self.FileLocation.config(text=self.FolderName,fg="green")
return True
else:
self.FileLocation.config(text="Please choose a directory !!",fg="red")
class Second:
def __init__(self,downloadWindow,youtubeLink,foldername,FileChoice):
self.downloadWindow=downloadWindow
self.youtubeLink=youtubeLink
self.foldername=foldername
self.FileChoice=FileChoice
self.yt=YouTube(self.youtubeLink)
if(FileChoice=='1'):
self.videoType=self.yt.streams.filter(only_audio=True).first()
self.MaxfileSize=self.videoType.filesize
if(FileChoice=='2'):
self.videoType=self.yt.streams.first()
self.MaxfileSize=self.videoType.filesize
self.Loading=Label(self.downloadWindow,text="Download in Progress.........",font=("Agency FB",40))
self.Loading.grid()
self.percent=Label(self.downloadWindow,text="0",font=("Agency FB",20))
self.percent.grid()
self.progressBar=ttk.Progressbar(self.downloadWindow,length=500,orient='horizontal',mode='indeterminate')
self.progressBar.grid(pady=(50,0))
self.progressBar.start()
threading.Thread(target=self.yt.register_on_progress_callback(self.show_Pregress)).start()
threading.Thread(target=self.downloadfile).start()
def downloadfile(self):
if(self.FileChoice=='1'):
self.yt.streams.filter(only_audio=True).first().download(self.foldername)
if(self.FileChoice=='2'):
self.yt.streams.filter().first().download(self.foldername)
def show_Pregress(self,streams=None,Chunks=None,filehandle=None,bytes_remaining=None):
percentCount = float("%0.2f"% (100 - (100*(bytes_remaining/self.MaxfileSize))))
if(percentCount<100):
self.percent.config(text=str(percentCount))
else:
self.progressBar.stop()
self.Loading.forget()
self.progressBar.forget()
self.downloadfinished=Label(self.downloadWindow,text="Download Finished",font=("ALGERIAN",20))
self.downloadfinished.grid(pady(150,0))
self.downloadfile=Label(self.downloadWindow,text=self.yt.title,font=("ALGERIAN",20))
self.downloadfile.grid(pady(50,0))
if __name__=="__main__":
window=Tk()
window.title("YouTube Download Manager")
window.state("zoomed")
app=Application(window)
mainloop()
Most probably your function:
def show_Pregress(self,streams=None,Chunks=None,filehandle=None,bytes_remaining=None):
percentCount = float("%0.2f"% (100 - (100*(bytes_remaining/self.MaxfileSize))))
Is called without passing a value for bytes_remaining which ends up in doing a division of None by self.MaxfileSize
See here for how to register a progress_bar callback with pytube:
How to add progress bar?
I want to make a simple GUI that will allow user to pick an excel file to load the data from that will later be used for math calculations. Both modules work correctly when separate. But when I try to use my GUI as an import into my main file I am unable to access the needed var without calling the class method which in turn iterates it. It is troublesome because it is supposed to use this function only after the button press.
Is there something fundamentally wrong that I am doing?
GUI script
import tkinter as tk
import tkinter.filedialog as tkf
class TestClass():
def __init__(self, master):
frame = tk.Frame(master)
frame.pack()
self.dialogButton = tk.Button(frame, text="choose", command=self.chooseFile)
self.dialogButton.pack(side=tk.BOTTOM)
def chooseFile(self):
global filename
filename = tkf.askopenfilename()
print(filename)
Import script
import tkinterTest as tt
import tkinter as tk
root = tk.Tk()
classObject = tt.TestClass(root)
var = classObject.chooseFile()
print(var)
root.mainloop()
I want to access the path string only with the GUI so that it gives me the string only after I press the button to select the file not right after the program starts.
I am currently programming a GUI with tkinter in Python 3.6 for another Program, which is called through subprocess. I would like to represent the progress of the Program called, with a Progressbar, popping up in another window as soon as I hit the 'Run Program' Button. The value of the progressbar is set by arguments passed from the subprocess script, where I calculate the percentage of progress in a function. What I need:
1. How do I properly use the Threading-Module for spawning the subprocess?
2. How do I import a function (and therefore its arguments) of a script, that runs with command line parameters?
I was looking for a answer in other posts the whole day, but couldn't really connect them to my problem.
I tried to spawn the subprocess by simply calling its function with threading.Thread(target=self.runProgram()).start()
Apparently the GUI-program still waits until the subprocess/Thread is finished and then continues with creating the progressbar, but I expected it to happen at the same time. I then tried to import the percentage value of the subprocess-Program, which didn't work due to missing parameters. Also I don't think that this would really work the way I want it to, because I want the arguments passed during the runtime, when the subprocess is called. It's very hard to properly explain what I am looking for, so here is some code:
GUI-Program:
import tkinter as tk
from tkinter import ttk
from tkinter import *
from tkinter.filedialog import askdirectory,askopenfilename
import os,subprocess
import threading
class eodApplication(tk.Tk):
def __init__(self):
#different entryboxes are created, not necessary for understanding
self.runButton=''
self.progress=''
self.window = tk.Tk()
self.window.geometry("500x350")
self.window.configure(background="white")
self.window.title("End of Day Application")
self.create_widgets()
def create_widgets(self):
#creating entryboxes initiated in __init__-method, containing paths one can browse for and a submit/'Run Program'-Button
self.submit()
def submit(self):
#Button calls function when pressed
self.runButton=ttk.Button(self.window,text='Run Program',command=lambda:self.bar_init())
self.runButton.grid(row=7, columnspan=2)
def bar_init(self):
barWindow = tk.Tk()
barWindow.geometry("250x150")
barWindow.configure(background="white")
barWindow.title("Progress")
self.progress=ttk.Progressbar(barWindow, orient="horizontal", length=200, mode="determinate",value=0)
self.progress.grid(row=0, column=0, sticky=tk.W)
threading.Thread(target=self.runProgram()).start()
from PythonProgrammeDWH import get_percentage
self.progress["value"] = percentage
def runProgram(self):
devnull = open(os.devnull, 'w')
subprocess.call(f"{self.entryboxPyExe.get()} {self.entryboxPyCode.get()} {self.entrybox64.get()} {self.entrybox66.get()} {self.entryboxXsd.get()} {self.entryboxOutput.get()} {self.entryboxXmlExe.get()}",cwd=os.getcwd(),stdout=subprocess.DEVNULL,stderr=subprocess.DEVNULL,shell=True)
eodApplication=eodApplication()
eodApplication.window.mainloop()
PythonProgrammeDWH (subprocess):
def main(sys.argv[1],sys.argv[2],sys.argv[3],sys.argv[4]):
~ a lot of stuff going on ~
sumFiles=len(os.listdir(path))
checkedFiles=0
for file in os.listdir(path):
checkedFiles+=1
get_percentage(sumFiles, checkedFiles)
def get_percentage(sumFiles, checkedFiles):
percentage= round((checkedFiles/sumFiles)*100)
return percentage
#percentage is the argument I want to pass to the other script for updating the progressbar
My function was working perfectly fine few minutes ago. Did not modify the code, just installed PyAudio. I get the error as per subject. It doesn't matter if run it from command line or IDE, same error. Any ideas?
def DataFinder():
#imports and initialize
import pandas as pd
import tkinter as tk
finder = tk.Tk()
finder.withdraw()
__dataFlag = False
#ask user to select a file
__path = tk.filedialog.askopenfilename()
#check the extension to handle reader
#for csv files
if __path.endswith('.csv')==True:
df = pd.read_csv(__path,header=0)
return df
__dataFlag = True
#and for excel files
elif __path.endswith('.xls')==True:
df = pd.read_excel(__path,header=0)
return df
__dataFlag = True
#if a file is not a supported type display message and quit
else:
__dataFlag = False
#check if there is a data to be returned
if __dataFlag==True:
return df
else:
print('The file format is not supported in this version.')
Explicitly import of filedialog can solve the problem.
So, you just need to add this line to your codes:
import tkinter.filedialog
You can find more information at Why tkinter module raises attribute error when run via command line but not when run via IDLE?
the following code didn't work for me:
import tkinter as tk
import tkinter.filedialog
But the following did work:
import tkinter
import tkinter.filedialog
and also this:
import tkinter.filedialog
import tkinter as tk
Hope this helps
Note
As mentioned by Vaidøtas I., you can't import filedialog from tkinter. Because you did not import the original tkinter but an aliased version tk.