Merging Files in Tkinter Search Files Application - python

I am trying to build a simple application using Tkinter wherein I should be able to search files in my local folders and display them. For example, if I am searching a 'test.txt' file, it will return me that file plus all txt files. Now the second part of the problem is, I have to merge all the files that was returned to me in my search into one single file (I know it sounds absurd but please forgive me). I have successfully achieved the first part but not able to implement the second part. Quite new to functions and OOPs concepts. Pasting my code below in the hope for some guidance. Please forgive me for the code quality as I am quite new.
import pandas as pd
from tkinter import *
import os
from docx import Document
doc1 = Document()
def search_file():
file_entry_name = entry.get()
answer.delete(1.0,END)
extension = file_entry_name.split('.')[1]
file_name = file_entry_name.split('.')[0]
file_entry_name = file_entry_name.lower()
for r,d,f in os.walk('/Users/kausthab/Documents/Documents – Kausthab’s MacBook Air/DSBA'):
for file in f:
file.split()
if file.startswith(file_entry_name) or file.endswith(extension):
answer.insert(INSERT,file + '\n')
def merge_file():
# files = os.listdir('/Users/kausthab/Documents/Documents – Kausthab’s MacBook Air/DSBA')
# global answer
# for i in answer:
# if i != '.DS_Store': # i kept getting an error for a hidden file. So excluded it
# doc1.add_heading(i, 2)
# doc2 = Document(i)
# for para in doc2.paragraphs:
# para_in_doc = doc1.add_paragraph(para.text)
# doc1.add_page_break()
# doc1.save('search.docx')
return
root = Tk()
root.title('Docu Search')
topframe = Frame(root)
entry = Entry(topframe)
entry.pack()
button = Button(topframe, text="search",command =search_file)
button.pack()
topframe.pack(side = TOP)
bottomframe = Frame(root)
scroll = Scrollbar(bottomframe)
scroll.pack(side=RIGHT, fill=Y)
answer = Text(bottomframe, width=80, height=50, yscrollcommand = scroll.set,wrap= WORD)
scroll.config(command=answer.yview)
merge_button = Button(bottomframe, text="merge",command =merge_file)
merge_button.pack()
answer.pack()
bottomframe.pack()
root.mainloop()

Related

How do I shop tkPDFViewer from combining PDF's when opening PDFs using buttons?

In this code, I'm trying to open PDFs as a separate window using tkinter and tkPDFViewer. The way this is done is a simple UI opens up with 2 buttons for 2 articles that are accessed from my computer in this case (but I just labeled it "filepath" for the file path to avoid revealing personal info). However, while the buttons work and open up a PDF window and a download window below that (as expected), when you close the PDF window (and the download window closes along with it) and then re-click on a button (the same one or a different one), it shows the previous pdf and the current one that appeared when you re-click combined. As you repeat this process, the PDFs just append to each other. However, what should happen is that the corresponding PDF to the article that is described in the button is shown and no other PDFs. How do I fix this? I've already tried to move the PDF initialization outside the event function then re-initialize it, but that results in a "local variable used before being defined" error, so that doesn't work, and I currently do not know of any other way to do this.
pdfArray = [
["skweak: Weak Supervision Made Easy for NLP",
r"filepath",
"Pierre Lison, Jeremy Barnes, and Aliaksandr Hubin",
"skweak, NLP, Natural Language Processing"],
["Information Theoretic-Based Quality Measures for Clustering",
r"filepath",
"Barry Drake, and Tiffany Huang",
"Quality Measures, Clustering, Data"
]
]
#Import tkinter library
import os
from tkinter import *
import tkinter as tk
from tkinter import ttk
from tkPDFViewer import tkPDFViewer as pdfViewer
from functools import partial
import shutil
#Create an instance of tkinter frame or window
mainWin= Tk()
#Set the geometry of tkinter frame
mainWin.geometry("1000x600+20+20")
download_icon = tk.PhotoImage(file=r'filepath')
paw_icon = tk.PhotoImage(file=r'filepath')
def download_pdf(original_file):
#this if-else statment detects if the original file exists.
if os.path.isfile(original_file):
newFileStem = os.path.expanduser('~') + r"\Downloads\ChatBox_download"
num = 0
while os.path.isfile(newFileStem + "(%d).pdf"%num):
num = num + 1;
newFile = newFileStem + "(%d).pdf"%num
f = open(newFile, "x")
shutil.copyfile(original_file, newFile)
completeWin = Toplevel(mainWin)
completeWin.geometry("400x75+660+480")
completeWin.title("Download Complete")
Label(completeWin, text = "Download Complete!", font = ('Gabriola', 14, 'bold')).pack()
Label(completeWin, text = str(newFile), font = ('Gabriola', 10)).pack(pady=2)
else:
notFoundWin = Toplevel(mainWin)
notFoundWin.geometry("200x75+660+480")
notFoundWin.title("File Not Found")
Label(notFoundWin, text = "File Not Found", font = ('Gabriola', 14, 'bold')).pack(pady=20)
#Define a new function to open the window
def open_win(pdf_ID):
pdf_title = pdfArray[pdf_ID][0] #title of pdf
file_location = pdfArray[pdf_ID][1] #location of pdf
authors = pdfArray[pdf_ID][2] #authors
keywords = pdfArray[pdf_ID][3] #keywords
pdfWin = Toplevel(mainWin)
pdfWin.geometry("600x350+640+20")
pdfWin.title(pdf_title)
# Adding pdf location and width and height.
pdfViewer.ShowPdf().pdf_view(pdfWin, pdf_location=file_location, width=70, height=100).pack(ipadx = 10, ipady = 10)
infoWin = Toplevel(pdfWin)
infoWin.geometry("600x200+640+420")
infoWin.title("PDF Information")
Label(infoWin, text = "Information: ", font = ('Gabriola', 15, 'bold')).pack(pady=2)
Label(infoWin, text = "Title: " + pdf_title, font = ('Gabriola', 12)).pack(pady=1)
Label(infoWin, text = "Author(s): " + authors, font = ('Gabriola', 12)).pack(pady=1)
Label(infoWin, text = "Keyword(s): " + keywords, font = ('Gabriola', 12)).pack(pady=1)
tk.Button(infoWin, image=download_icon, borderwidth = 0, command=partial(download_pdf, file_location)).pack(pady=1)
#Create a label
Label(mainWin, text= "Click any button below to open a PDF", font= ('Gabriola', 25, 'bold')).pack(pady=30, padx = 10)
#Create a button to open a New Window
for ID in range(0, len(pdfArray)):
tk.Button(mainWin, image=paw_icon, compound=LEFT, text=" Open \" " + pdfArray[ID][0]+" \"", font= ('Gabriola', 12), command=partial(open_win, ID)).pack(pady=2)
mainWin.mainloop()
I ran into this issue as well when using tkPDFViewer.
To fix I had to go into the tkPDFViewer module and add a line:
self.img_object_li.clear()
immediately after the line:
def add_img():
I'm just a beginner myself so this was my fix to get around the issue.
From what I understand the line:
self.img_object_li.append(timg)
adds images indefinitely, I was trying to destroy the frame and widgets containing the objects from my main program but couldn't get it to work at all. Issue just kept persisting. This is probably not the best way to do it and someone else will ahve a better fix.

Display output of print in python GUI?

Hello I created this function that allows you to count the top X words in the Macbeth play however I want to display the results in a gui of my creation and was wondering if someone could show me how to? I already created the function and tested it but I don't understand python gui and whenever I try to create it, I run into a host of errors.
#Imports
import tkinter as tk
from tkinter import *
from tkinter import filedialog
from collections import Counter
import collections
# Initialize the dictionary
wordcount = {}
#Function
#open Macbeth text file
file = open('Macbeth Entire Play.txt', encoding="utf8")
a= file.read()
n_print = int(input("How many most common words are: "))
print("\nThe {} most common words are as follows\n".format(n_print))
word_counter = collections.Counter(wordcount)
for word, count in word_counter.most_common(n_print):
print(word, ": ", count)
# Close the file
file.close()
#Graphics
fullString = ""
root = tk.Tk()
root.title("Count words")
root.geometry('400x400')
#Background Image Label
bg = PhotoImage(file = "./guibackground.gif")
# Show image using label
label1 = Label( root, image = bg)
label1.place(relx=0.5, rely=0.5, anchor=CENTER)
#Class Window
class Window:
def __init__(self):
self.root = tk.Tk()
self.btn = tk.Button(text='Open File', command=self.open_file)
self.btn.pack()
self.btn = tk.Button(text='Exit', command=root.quit)
self.btn.pack()
self.lbl.pack()
self.root.mainloop()
def open_file(self):
file = open('Macbeth Entire Play.txt', encoding="utf8")
a= file.read()
def word_count(self):
for word in a.lower().split():
word = word.replace(".","")
word = word.replace(",","")
word = word.replace(":","")
word = word.replace("\"","")
word = word.replace("!","")
word = word.replace("“","")
word = word.replace("‘","")
word = word.replace("*","")
if word not in wordcount:
wordcount[word] = 1
else:
wordcount[word] += 1
if __name__ == '__main__':
mainWindow = Window()
# root.mainloop()
I'll present a general example for you to start with in building your GUI. There are a few items I'd like to comment.
It's not a good idea to import tkinter as tk as well as from tkinter import * as this may lead to confuson later in the development. In general it's preferred to import tkinter as tk as you then always can see which module a widget comes from.
I would advise against the mix of flat and OOP programming styles. As above, it may lead to confusion later.
It's a good idea to use descriptive names, even if you just create and forget widgets, because an error message will tell you the name of the offending object. And also just in general it's easier to get a grip of the application with descriptive names. For example the GUI Buttons could instead be called: self.open_btn and self.exit_btn.
When you are working with files you may consider using the with statement as this adds a layer of security; it won't leave files open even if there is an error.
My example uses a program structure which I often use myself, depending on how I intend to use the program. Pros and cons for different structures are discussed in the thread Best way to structure a tkinter application?
Below is an example you can use as a cornerstone for your efforts if you wish.
import tkinter as tk
class Application(tk.Frame):
def __init__(self, master):
super().__init__() # Call __init__() method in parent (tk.Frame)
self.bg_image = tk.PhotoImage(file = "images/pilner.png")
self.background = tk.Label( root, image=self.bg_image)
self.background.place(relx=0.5, rely=0.5, anchor=tk.CENTER)
self.open_btn = tk.Button(text='Open File', command=self.open_file)
self.open_btn.pack(pady=(30,10))
self.exit_btn = tk.Button(text='Exit', command=master.destroy)
self.exit_btn.pack()
def open_file(self):
with open('Macbeth Entire Play.txt', encoding="utf8") as file:
self.file_text = file.read()
# Etc, etc.
if __name__ == '__main__':
root = tk.Tk()
root.title("Count words")
root.geometry('400x400+900+50')
app = Application(root)
app.pack(expand=True, fill='both')
root.mainloop()
Hope this is of help.

Having problems with tkinter destroy method with labels

First time posting to Stack! I am very new to Python / Tkinter so bear with me.
I am trying to write code that looks for a saved txt file upon startup that describes the path of a chosen XML file, and for it to print a tkinter label based on the chosen directory.
Problem I'm having is this: if you choose the XML file path, it will print the path - which is what I want. But, if you choose another XML file path, the previously printed label doesn't get destroyed, and the new label gets applied on top of the old one. I have looked at other people having similar issues and I'm stuck. I have tried a few different ways of implementing the .destroy() method, and none of them seem to be working. I wouldn't be surprised if there are other errors/redundancies in my code (please focus on the .destroy() issue), but it seems to be working the way I want other than this issue. I do not get any error messages with this code.
Here's what the code looks like right now (I only posted the part that is having the issue, let me know if you need more).
I have been testing this issue by selecting a long file path first, and then a shorter path on the desktop. The path on the desktop will print on top of the previous label instead destroying the previous label, seemingly ignoring the reset() function.
import xml.etree.ElementTree as ET
from tkinter import filedialog
from tkinter import *
import tkinter as tk
root= tk.Tk()
canvas1 = tk.Canvas(root, width = 750, height = 750)
canvas1.pack()
#Destroy previous label
global label_file
def reset():
label_file.destroy()
#Function that saves selected path
def findfile():
reset()
global file_selected
file_selected = filedialog.askopenfilename(filetypes=[("XML Files", "*.xml")])
if file_selected == "":
label_file = tk.Label(root, text= 'Error. Choose location of config.xml:', bg='red' )
canvas1.create_window(370, 165, window=label_file)
else:
label_file = tk.Label(root, text= 'Saved Path: '+ file_selected, bg='yellow' )
canvas1.create_window(370, 165, window=label_file)
savedpath = open("path.txt", "w")
savedpath.write(file_selected)
#Attempts to read save file on startup
try:
with open('path.txt', 'r') as f:
global file_selected
file_selected = f.readline()
label_file = tk.Label(root, text= 'Path: ' + file_selected, bg='#00ff00' )
canvas1.create_window(370, 165, window=label_file)
button1 = tk.Button (root, text='Change Path',command=findfile, bg='orange')
canvas1.create_window(50, 200, window=button1)
#If no save file on startup
except FileNotFoundError:
file_selected = ""
label_file = tk.Label(root, text= 'Choose location of config.xml file: ', bg='red' )
canvas1.create_window(168, 165, window=label_file)
button2 = tk.Button (root, text='Browse',command=findfile, bg='orange')
canvas1.create_window(50, 200, window=button2)
root.mainloop()

Problem creating a simple tkinter GUI that displays names of text files from a folder and their contents when clicked

I have been trying to develop a GUI for my python based voice assistant. The following is a snippet of the code that I am having problem with.What I want to do is display the name of text files from a folder and display their contents in the same window when the user clicks on one of the file names.
from tkinter import *
import os
menu_color = "#2c2b34"
frame_color = "#28262e"
font_color = "#06dff5"
ss_f_button = []
note_f_button = []
note_text = None
def note_window(): #To operate Note Window
global note_f_button
path = os.path.join(sys.path[0], "Notes/")
note_files = [f for f in os.listdir(path)]
note_f_button = []
if len(note_files)>0:
y=60
for i in range(len(note_files)):
note_f_button.append(Button(root, bg=frame_color, fg=font_color, activebackground=frame_color, activeforeground=font_color, bd ="0", text=note_files[i], font=("Helvetica Neue Bold", "10"), cursor="hand2", command=lambda: open_note(note_files[i])))
note_f_button[i].place(x=55, y=y)
y+=40
root.update()
def open_note(f_name): #To operate Note Window
global note_text
if note_text != None:
note_text.place_forget()
note_text = None
path = os.path.join(sys.path[0], "Notes/")
with open(f"{path}{f_name}", "r") as file:
note_text = file.read()
note_text = Label(root, text=note_text, bg=frame_color, fg=font_color, font=("Helvetica Neue Bold", "11"))
note_text.place(x=340, y=60)
root.update()
root = Tk()
root.title("TEST")
root.geometry("706x462")
note_window()
root.update()
root.mainloop()
Here is the output:
You would understand it best if you run it yourself!! If you try this code, be sure to change the font style as Helvetica may not be installed in your system!!
The problem I am facing is that both the files show the same text when clicked, or more specifically, both of them show the same text from the test.txt file.Can anyone please provide a way to do what I am trying to achieve and also point out where I am doing it wrong.I am using Python 3.8.3.

Using Tkinter to create a GUI that creates a folder and unwrap a ZIP file

Hello fellow programmers,
Im trying to make a GUI with Tkinter. This is the first time that Ive used Tkinter, and Ive run into some issues. The script and GUI should do the following:
Ask user (via entry and 'ok' button) to enter the name of the working folder. Result -> Create the newly made folder on the desktop of the system.
Select an OWL file (which is a zip-file) via TkFileDialog.
Result -> unwrap the selected zip-file in the folder that has been created in step 1.
The script Ive written so-far using online tutorials:
import Tkinter
import Tkconstants
import tkFileDialog
import zipfile
from Tkinter import *
import os
class TkFileDialogExample(Tkinter.Frame):
def __init__(self, root):
Tkinter.Frame.__init__(self, root)
root.configure(background='lightgrey')
root.wm_title("Audit tool: Thickness of pavement")
root.geometry('{}x{}'.format(500, 500))
Label_1 = Message(root, text="Step 1. Please fill in the name of the output folder and click on 'create'. The output folder will be created in the desktop folder:", width=380,)
Label_1.grid(row=1, columnspan=5)
Entry1 = Entry(root)
Entry1.grid(row=2, sticky=E)
folder_location = '~/Desktop/' + Entry1.get()
def createname():
return os.mkdir(os.path.expanduser(folder_location))
button_1 = Button(root, text="Create", command=createname)
button_1.grid(row=2, column =1, sticky=W)
Label_3 = Message(root, text="Step 2. Please select the OWL file:", width=300,)
Label_3.grid(row=5, sticky=W)
button_2 = Button(self, text='Click here to select the OWL file', command=self.askopenfilename)
button_2.grid(row=4,column=1, sticky=W)
self.file_opt = options = {}
options['defaultextension'] = '.owl'
options['filetypes'] = [('all files', '.*'), ('owl files', '.owl')]
options['initialdir'] = 'C:\\'
options['initialfile'] = 'Title_of_OWL-file.ccr'
options['parent'] = root
options['title'] = 'This is a title'
self.dir_opt = options = {}
options['initialdir'] = 'C:\\'
options['mustexist'] = False
options['parent'] = root
def askopenfile(self):
return tkFileDialog.askopenfile(mode='r', **self.file_opt)
def askopenfilename(self):
filename = tkFileDialog.askopenfilename(**self.file_opt)
zip_ref = zipfile.ZipFile(filename, 'r')
if filename:
return zip_ref.extractall(folder_location)
if __name__=='__main__':
root = Tkinter.Tk()
TkFileDialogExample(root).grid()
root.mainloop()
The problem probably lies within the third use of 'folder_location'. Since I am relatively new to the Python language, I cannot seem to find a solution to this problem.
Thank you for your help and time!
Yours truly,
Ruben van der Heijden
The issue is that you have defined the variable folder_location only in the local scope of your TkFileDialogExample.__init__ method. As a result, it is not accessible to any of the other methods of your class. If you do want it to be accessible, then you'll want to set it as an attribute of your class using the self keyword.
def __init__(self, root):
# Stuff
self.folder_location = os.path.join('~', 'Desktop', Entry1.get())
Then you can access it from your TkFileDialogExample.askopenfilename method:
def askopenfilename(self):
filename = tkFileDialog.askopenfilename(**self.file_opt)
zip_ref = zipfile.ZipFile(filename, 'r')
if filename:
return zip_ref.extractall(self.folder_location)
Side Note: In general, it is best to use os.path.join to construct file paths from strings.

Categories

Resources