Simple tkinter gui for already existing code - python

I have some already written code (btw I'm still a noob at python and programming in general) and i want to make a tkinter window that has a text box that is gonna show everything printed in the console and a button that is gonna run the main() function.
my existing code:
import pafy
import os
from pydub import AudioSegment
def downloadSound(videourl):
url = str(videourl)
video = pafy.new(url)
bestaudio = video.getbestaudio()
print(video.title, video.author, video.length)
bestaudio.download()
def linklister(linklist):
f = open('links.txt','r')
for line in f:
linklist.append(line.strip())
f.close()
def converter():
dirlist = os.listdir()
songlist = []
for i in dirlist:
if ".webm" in i:
songlist.append(i)
for i in songlist:
sound = AudioSegment.from_file(i)
imp3 = i.replace(".webm", ".mp3")
sound.export(imp3, format="mp3", bitrate="192k")
print (i, "DONE")
def main():
ytlinks = []
linklister(ytlinks)
for i in ytlinks:
downloadSound(i)
print ("downlad complete, proceeding to conversion")
converter()
try:
main()
except Exception as e:
print (e)
print ("OPPS")
else:
pass

I have not tested this but from personal experience this tkinter code works, I am unable to check if it works within yours. If this code doesn't work, test it by adding a print where I placed the comment.
import sys
import tkinter as tk
import pafy
import os
from pydub import AudioSegment
def downloadSound(videourl):
url = str(videourl)
video = pafy.new(url)
bestaudio = video.getbestaudio()
print(video.title, video.author, video.length)
bestaudio.download()
def linklister(linklist):
f = open('links.txt','r')
for line in f:
linklist.append(line.strip())
f.close()
def converter():
dirlist = os.listdir()
songlist = []
for i in dirlist:
if ".webm" in i:
songlist.append(i)
for i in songlist:
sound = AudioSegment.from_file(i)
imp3 = i.replace(".webm", ".mp3")
sound.export(imp3, format="mp3", bitrate="192k")
print (i, "DONE")
def main():
ytlinks = []
linklister(ytlinks)
for i in ytlinks:
downloadSound(i)
print ("downlad complete, proceeding to conversion")
class TextOut(tk.Text):
def write(self, s):
self.insert(tk.CURRENT, s)
def flush(self):
pass
if __name__ == '__main__':
root = tk.Tk()
text = TextOut(root)
sys.stdout = text
text.pack(expand=True, fill=tk.BOTH)
main()#here
root.mainloop()

Related

How to run Tkinter in the background and update it each time a function executes?

I'm writing a script and I'd like to use Tkinter GUI (or any other module which could do this) to show how many times in total this script has been run, store the number in file and update GUI dynamically from this file. But each time I call label.mainloop() nothing past this line gets executed, it just freezes there.
import tkinter
import time
def tracker():
f = open('howmanytimes.txt', 'r')
thenumber = f.read()
f.close()
tracker = 'Script has run this many times: ' + (str(thenumber))
label = tkinter.Label(text=tracker, font=(
'Times', '20'), fg='red', bg='black')
label.master.overrideredirect(True)
label.master.geometry("+0+0")
label.pack()
label.master.wm_attributes("-topmost", True)
label.mainloop()
tracker() # <- Nothing past this line gets executed
time.sleep(2)
i = 0
while i < 20:
print('Script has been run')
time.sleep(3)
f = open('howmanytimes.txt', 'w+')
thenumber = f.read()
g = int(thenumber) + 1
f.write(str(g))
f.close()
tracker()
i+=1
Here's a way to implement what you want. I put all the tkinter related code into a class to better encapsulate what it does and allow it to be put into a separate thread. It uses the universal widget method after() to periodically "poll" the file for changes without interfering with tkinter's mainloop() — which is a very common way to do that sort of thing.
I also had to change your file handling quite a bit to get it working and handle all the possible cases of it not existing yet or being empty — as well as deleting it at the end so its existence can't affect a subsequent run of the same program.
import os
from threading import Lock, Thread
import tkinter as tk
import time
class Tracker:
def __init__(self):
self.root = tk.Tk()
self.root.overrideredirect(True)
self.root.geometry("+0+0")
self.root.wm_attributes("-topmost", True)
# Create empty label widget to be updated.
self.label = tk.Label(self.root, font=('Times', '20'), fg='red', bg='black')
self.label.pack()
self.update() # Start polling file.
self.root.mainloop()
def update(self):
try:
with open(FILE_PATH, 'r') as f:
thenumber = next(f)
except (FileNotFoundError, StopIteration):
thenumber = '0'
self.label.config(text=f'Script has run this many times: {thenumber}')
with running_lock:
if running:
self.label.after(1000, self.update)
else:
self.root.quit() # Stop mainloop.
FILE_PATH = 'howmanytimes.txt'
running_lock = Lock()
running = True
bkg_thread = Thread(target=Tracker)
bkg_thread.start()
for i in range(5):
try: # Create or update file.
with open(FILE_PATH, 'r+') as f:
thenumber = f.read()
try:
g = int(thenumber) + 1
except ValueError: # Empty file.
g = 1
f.seek(0) # Rewind.
f.write(str(g))
except FileNotFoundError:
with open(FILE_PATH, 'w') as f:
g = 1
f.write(str(g))
print('Script has been run')
time.sleep(3)
with running_lock:
running = False # Tell background thread to stop.
try:
os.remove(FILE_PATH) # Clean-up.
except Exception:
pass

Mini Search engine Python(File finder and keyword finder)

I'm working on a search engine but I'm facing problems,I want like words from notepad to show on my 'search results', but it's not showing anything, and if you could help me doing like how many times the keyword that I'm searching for got repeated I would appreciate it this is the code:
from tkinter import *
import os
from tkinter.filedialog import askdirectory
from tkinter import messagebox
import subprocess
def content_analyser(pat):
with open(pat,'r') as f:
try:
for line in f:
if search in line:
d.update()
d.insert(END, pat)
break
except:
pass
def smali_finder(pat):
try:
for file in os.listdir(pat):
spat=pat+'/'+file
if os.path.isdir(spat):
smali_finder(spat)
else:
if file.endswith(".smali"):
content_analyser(spat)
except Exception as e:
print ("Error:::",pat,e)
def fing(path):
global search
if search_word.get()=='':
var=messagebox.showwarning(message="Please a search word")
else:
search=search_word.get()
smali_finder(path)
def save_list():
with open("saved_result","w") as sfile:
sfile.write('\n'.join(d.get(0,END)))
var=messagebox.showwarning(message="File names are saved as {}".format("saved_result.txt"))
def chose_folder():
global path
foldername = askdirectory()
path=foldername
folder_name.delete(0,END)
folder_name.update()
folder_name.insert(END, path)
if __name__=="__main__":
parent=Tk()
parent.title('File Finder')
Label(parent,text="Folder name: ").grid(row=0,column=0,sticky='e')
folder_name=Entry(parent,width=20)
folder_name.grid(row=0,column=1,padx=2,pady=2,sticky='we',columnspan=9)
Label(parent,text="Search word: ").grid(row=1,column=0,sticky='e')
search_word=Entry(parent,width=20)
search_word.grid(row=1,column=1,padx=2,pady=2,sticky='we',columnspan=9)
Label(parent,text="Search Results: ").grid(row=3,column=0,sticky='e')
d=Listbox(parent,width=125,height=20)
d.grid(row=4,column=3,padx=2,pady=2,sticky='we',columnspan=9)
Button(parent,text="Folder",command=lambda:chose_folder()).grid(row=0,column=10,sticky='e'+'w',padx=2,pady=2,)
start=Button(parent,text="Start",command=lambda:fing(path)).grid(row=1,column=10,sticky='e'+'w',padx=2,pady=2,)
save=Button(parent,text="Save",command=lambda:save_list())
save.grid(row=2,column=10,sticky='e'+'w',padx=2,pady=2)
Button(parent,text="Exit",command=parent.destroy).grid(row=3,column=10,sticky='e'+'w',padx=2,pady=2)
parent.mainloop()

Using tqdm progress bar in a if statement

Actually I have this code :
#!/usr/bin/env python3
import sys
import requests
import random
from multiprocessing.dummy import Pool
from pathlib import Path
requests.urllib3.disable_warnings()
print ('Give name of txt file on _listeNDD directory (without.txt)'),
file = str(input())
if Path('_listeNDD/'+file+'.txt').is_file():
print ('--------------------------------------------------------')
print ("Found")
print ('--------------------------------------------------------')
print ('Choose name for the output list (without .txt)'),
nomRez = str(input())
filename = '_listeNDD/'+file+'.txt'
domains = [i.strip() for i in open(filename , mode='r').readlines()]
else:
print ('--------------------------------------------------------')
exit('No txt found with this name')
def check(domain):
try:
r = requests.get('https://'+domain+'/test', timeout=5, allow_redirects = False)
if "[core]" in r.text:
with open('_rez/'+nomRez+'.txt', "a+") as f:
print('https://'+domain+'/test', file=f)
except:pass
mp = Pool(100)
mp.map(check, domains)
mp.close()
mp.join()
exit('finished')
Screen of the root file
With this code, it open text file on directory "_listeNDD" and I write new text file on directory "_rez".
Obviously it's super fast for ten elements but when it gets a bigger I would like a progress bar to know if I have time to make a coffee or not.
I had personally tried using the github tqdm but unfortunately it shows a progress bar for every job it does, while I only want one for everything...
Any idea?
Thank you
EDIT : Using this post, I did not succeed with
if __name__ == '__main__':
p = Pool(100)
r = p.map(check, tqdm.tqdm(range(0, 30)))
p.close()
p.join()
I don't have a high enough python level to master this so I may have badly integrated this into my code.
I also saw:
if __name__ == '__main__':
r = process_map(check, range(0, 30), max_workers=2)

Using .split with tkinter

Quite a beginner here. I have a command line script that works fine for what I do and I'm looking to move it into a GUI.
os.chdir(ImageDirST)
for f in sorted(os.listdir(ImageDirST)):
f_name,f_ext = (os.path.splitext(f))
f_sku = (f_name.split(' ')[0])
f_num = (f_name[-2:])
n_name = ('{}_{}{}'.format(f_sku,f_num,f_ext))
print(f, "-->", n_name)
I would like this to display in the same fashion within a message window in tkinter.
With some help from here, I managed to print the filenames in the directory when a button is pushed with:
filenames = sorted(os.listdir(ImageDirBT))
text = "\n".join(filenames)
print_filename_test.set(text)
I have tried to use my split code to setup a list of what the new filenames would look like, prior to setting the variable, with the following, where print_filenames() is the function triggered by the press of a button.
def print_filenames():
filenames = sorted(os.listdir(ImageDirBT))
for filenames in sorted(os.listdir(ImageDirBT)):
f_name,f_ext = (os.path.splitext(filenames))
f_sku = (f_name.split('_')[0])
f_num = (f_name[-2:])
n_name = ('{}_{}{}'.format(f_sku,f_num,f_ext))
newlist = "\n".join(n_name)
print_filename_test.set(newlist)
I don't get any errors with this code for print_filenames(), however what is displayed in the message panel is the last filename in the list, vertically, one character wide:
eg:
F
I
L
E
_
1
1
.
e
x
t
I would like to display the output as:
oldfilename_01.ext --> newfilename_csvdata_01.ext
oldfilename_02.ext --> newfilename_csvdata_02.ext
oldfilename_03.ext --> newfilename_csvdata_03.ext
oldfilename_04.ext --> newfilename_csvdata_04.ext
The command line program I have written uses numbers to chose menu options for what needs to be done, confirming before any renaming is done, hence printing the file name comparisons. My struggle is manipulating the strings in the list to be able to do the same thing.
Using messagebox:
import os
import tkinter as tk
from tkinter import messagebox
ImageDirST = r"your_path"
os.chdir(ImageDirST)
root = tk.Tk()
names = []
for f in sorted(os.listdir(ImageDirST)):
f_name,f_ext = (os.path.splitext(f))
f_sku = (f_name.split(' ')[0])
f_num = (f_name[-2:])
n_name = ('{}_{}{}'.format(f_sku,f_num,f_ext))
names.append(f"{f} --> {n_name}\n")
messagebox.showinfo(title="Something", message="".join(names))
root.mainloop()
Or using Text widget with scrollbar:
import os
import tkinter as tk
from tkinter.scrolledtext import ScrolledText
ImageDirST = r"your_path"
os.chdir(ImageDirST)
root = tk.Tk()
txt = ScrolledText(root, font="Arial 8")
txt.pack()
for f in sorted(os.listdir(ImageDirST)):
f_name,f_ext = (os.path.splitext(f))
f_sku = (f_name.split(' ')[0])
f_num = (f_name[-2:])
n_name = ('{}_{}{}'.format(f_sku,f_num,f_ext))
txt.insert("end",f"{f} --> {n_name}\n")
root.mainloop()

Running a script for many files of the same extension and writing the results to a text file

I'm trying to write a script to extract data from a number of files in a directory with the extension ".tp6" and then write all of that data to a single text file.
It's able to get data from each file correctly and print them to the terminal, but I haven't been able to 'pass' each data point to another function that writes it to a text file.
Any ideas? Thank you!
import glob
import os
import Tkinter
import tkFileDialog
root = Tkinter.Tk()
root.withdraw()
dir_path = tkFileDialog.askdirectory()
os.chdir(dir_path)
def main():
for file_path in glob.glob('*.tp6'):
uncovext(file_path)
def main2():
for file_path in glob.glob('*.tp6'):
totext(uncovext)
#find and print data from each .tp6 file - this part works correctly
def uncovext(file_path):
for line in open(file_path):
if line.startswith(' UNCONVOLVED INTEGRATED RADIANCE'):
text = line[36:47]
number = float(text) * 10000
print('%.3f' % number)
def totext(uncovext):
with open("output.txt", "a") as f:
f.write(uncovext)
f.close()
if __name__ == '__main__':
main()
main2()
I think it was a matter of naming: if you change your input parameter of totext function to p_uncovext for example, it should work. You need also to call the function to text on your loop.
import glob
import os
import Tkinter
import tkFileDialog
root = Tkinter.Tk()
root.withdraw()
dir_path = tkFileDialog.askdirectory()
os.chdir(dir_path)
def main():
for file_path in glob.glob('*.tp6'):
uncovext(file_path)
#find and print data from each .tp6 file - this part works correctly
def uncovext(file_path):
for line in open(file_path):
if line.startswith(' UNCONVOLVED INTEGRATED RADIANCE'):
text = line[36:47]
number = float(text) * 10000
totext('%.3f' % number)
def totext(p_uncovext):
with open("output.txt", "a") as f:
f.write(p_uncovext)
f.close()
if __name__ == '__main__':
main()
You have a couple of problems. First uncovext doesn't save the data it parses from the input file. After printing to the screen, it is just thrown away. You could collect it into a list and return that for further processing. Then, you call the writer in a second function and you don't have any way for main to let main2 know what the data is.
An easy fix is a single function that calls uncovext and uses its result to call totext.
import glob
import os
import Tkinter
import tkFileDialog
root = Tkinter.Tk()
root.withdraw()
dir_path = tkFileDialog.askdirectory()
os.chdir(dir_path)
def main():
for file_path in glob.glob('*.tp6'):
totext(uncovext(file_path))
#find and print data from each .tp6 file - this part works correctly
def uncovext(file_path):
output = []
for line in open(file_path):
if line.startswith(' UNCONVOLVED INTEGRATED RADIANCE'):
text = line[36:47]
number = float(text) * 10000
output.append('%.3f\n' % number)
return output
def totext(uncovext):
with open("output.txt", "a") as f:
f.writelines(uncovext)
if __name__ == '__main__':
main()
You could also rewrite your parser as a generator and write code that I find more self-explanatory (that's just me though...)
def main():
with open('output.txt', 'a') as f:
for file_path in glob.glob('*.tp6'):
f.writelines(uncovext(file_path))
#find and print data from each .tp6 file - this part works correctly
def uncovext(file_path):
for line in open(file_path):
if line.startswith(' UNCONVOLVED INTEGRATED RADIANCE'):
text = line[36:47]
number = float(text) * 10000
yield '%.3f\n' % number

Categories