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.
Related
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()
I am trying to make a GUI program where at the press of a button, the program picks a random word out of 3 files and displays the selected word in a Label.
What is the simplest way that I could go about doing this?
Thanks!
Here's a simple example that randomly picks a 'word'(anything that is separated) in some files named 'test.txt', 'test2.txt', 'test3.py' that are in the same directory as the below code:
from secrets import choice # for cryptographically secure randomness
import tkinter as tk # for GUI
def random_file():
random_file = choice(("test.txt", "test2.txt", "test3.py"))
return random_file
def random_word(file_name):
with open(file_name) as f:
all_words_in_file = list()
for line in f:
for word in line.split():
all_words_in_file.append(word)
random_word = choice(all_words_in_file)
return random_word
def label_rnd_word():
global lbl
lbl['text'] = random_word(random_file())
if __name__ == '__main__':
root = tk.Tk()
lbl = tk.Label(root)
btn = tk.Button(root, text="Random Word", command=label_rnd_word)
# layout
lbl.pack()
btn.pack()
root.mainloop()
Make a button in tkinter - this is pretty easy... something like:
button= Button(root, text="button name", command=self.do_something)
button.grid(row=1, column=1, columnspan=1)
Import the data from the 3 text files with something like this:
load_file = os.path.join('FOLDER', 'FILENAME')
with open(load_file, 'r') as f:
FILE1= f.read()
f.close()
You could iterate this is you want, but it's hardly worth it for 3 files.
Join the 3 together....
Maybe
combined = string1 + string2 + string3
then simply select a random word
Use the random.choice() function:
import random
print(random.choice(combined))
You still need to do some work- but that's how I would do it. hope this helps!!
I'm trying to create a program in python using tkinter, and this program is supposed to have a list of books created by the user. On the main window (the one with the list), there should be a menubar with the option to add a book to the list. When clicked, this option should open another window, this time with one entrybox, where the user should enter the book's title and an add button, to add the button to the list.
The list is saved in a .txt file.
This is the program I wrote so far:
import sys
from tkinter import *
def newBook():
def add():
BookTitle = v.get()
bookTitle = '\n' + BookTitle
books = open('c:/digitalLibrary/books.txt', 'a')
books.write(bookTitle)
books.close()
addWindow = Tk()
v = StringVar()
addWindow.geometry('250x40+500+100')
addWindow.title('digitalLibrary - Add Book')
newBookEntry = Entry(addWindow,textvariable=v)
newBookEntry.pack()
addButton = Button(addWindow, text='ADD', command=add)
addButton.pack()
def refresh():
books = open('c:/digitalLibrary/books.txt', 'r')
bookList = books.readlines()
books.close()
for i in range (0, len(bookList)):
bookOne = Label(text=bookList[i])
bookOne.grid(row=i, column=0, sticky=W)
def quitProgram():
tfQuit = messagebox.askyesno(title='Close Program', message='Are you sure?')
if tfQuit:
window.destroy()
window = Tk()
menubar = Menu(window)
window.geometry('400x400+200+100')
window.title('digitalLibrary')
booksmenu = Menu(menubar, tearoff=0)
booksmenu.add_command(label='Add Book', command=newBook)
booksmenu.add_command(label='Delete Book')
booksmenu.add_command(label='Close Program', command=quitProgram)
menubar.add_cascade(label='digitalLibrary', menu=booksmenu)
books = open('c:/digitalLibrary/books.txt', 'r')
bookList = books.readlines()
books.close()
for i in range (0, len(bookList)):
bookOne = Label(window, text=bookList[i])
bookOne.grid(row=i, column=0, sticky=W)
refreshButton = Button(window, text='Refresh', command=refresh)
refreshButton.grid(row=0, column=1)
window.config(menu=menubar)
window.mainloop()
It seems logical to me that this should work, but it just doesn't. When I click the ADD button on the Add Book window, all it does is add the line break to the .txt file.
I know that it works if I use the OS library and create a separate python file for the add book window, but I'd rather put it all in one code, if possible.
I've tried many things, and tried searching it in the web, but I got nowhere.
The root cause of your problem is that you are creating more than once instance of Tk. You cannot do this. If you want to create a popup window, create an instance of Toplevel. A proper Tkinter application creates exactly once instance of Tk with exactly one invocation of mainloop.
If your main goal is to simply get input from the user (versus learning how to write your own dialog), you might want to consider using one of the built-in dialogs.
For example:
import tkinter.simpledialog as tkSimpleDialog # python 3.x
...
def newBook():
BookTitle = tkSimpleDialog.askstring("Add Book","What is the name of the book?")
if BookTitle is not None:
bookTitle = '\n' + BookTitle
books = open('/tmp/books.txt', 'a')
books.write(bookTitle)
books.close()
I have this code in python 2.7 using tkinter that creates a Button on a Frame to open a file. There's a Label under it. I'm trying to make it so once the file is opened, the label prints the path, "file1.name" or whatever, on the Label, and if you open a new file it will change that Label again.
Also, I'm betting there's a better way to move data between the functions than I'm using here with global, but that's not worrying me right now.
I have to move the data from the opened files between functions so that I can mix the data and save to a new file. The code is:
from Tkinter import *
import Tkinter
import tkFileDialog
import tkMessageBox
root = Tkinter.Tk()
global rfile1
global rfile2
rfile1 = ""
rfile2 = ""
class Application(Frame):
def __init__(self, master = None):
Frame.__init__(self, master)
self.grid()
self.createWidgets1()
self.createLabels1()
self.createWidgets2()
self.createLabels2()
def createWidgets1(self):
self.oButton = Button(self, text = "open1", command = self.openfile1)
self.oButton.grid()
def createLabels1(self):
self.oLabel = Label(self, text = "whoops")
self.oLabel.grid()
def createWidgets2(self):
self.oButton = Button(self, text = "open2", command= self.openfile2)
self.oButton.grid()
def createLabels2(self):
self.oLabel2 = Label(self, text = "whoops2")
self.oLabel2.grid()
def openfile1(self):
file1 = tkFileDialog.askopenfile(title = "choose a file, *****", parent=root, mode = 'rb')
rfile1 = file1.read()
tkMessageBox.showinfo("oy", rfile1, parent=root)
def openfile2(self):
file2 = tkFileDialog.askopenfile(parent=root, mode='rb')
rfile2 = file2.read()
tkMessageBox.showinfo("hola", rfile2, parent=root)
app = Application()
app.master.title("whiggy whompus")
app.mainloop()
If I understand correctly, you want something like (untested):
def openfile1(self):
file1 = tkFileDialog.askopenfile(title = "choose a file, *****", parent=root, mode = 'rb')
self.oLabel.configure(text=file1.name)
rfile1 = file1.read()
tkMessageBox.showinfo("oy", rfile1, parent=root)
#mgilson has solved your first question. Your second question, about how to pass parameters between functions without using globals :
you might want to look at storing the variables as attributes on your application class :
The syntax self. is an attribute on the current instance (an instance being a particular example of a class - just like your car is a specific example of a class "car").
You can use instance attributes in this example as if they are globals.
from Tkinter import *
import Tkinter
import tkFileDialog
import tkMessageBox
root = Tkinter.Tk()
class Application(Frame):
def __init__(self, master = None):
Frame.__init__(self, master)
self.grid()
self.createWidgets1()
self.createLabels1()
self.createWidgets2()
self.createLabels2()
self.rfile1 = ""
self.rfile2 = ""
def createWidgets1(self):
self.oButton = Button(self, text = "open1", command = self.openfile1)
self.oButton.grid()
def createLabels1(self):
self.oLabel = Label(self, text = "whoops")
self.oLabel.grid()
def createWidgets2(self):
self.oButton = Button(self, text = "open2", command= self.openfile2)
self.oButton.grid()
def createLabels2(self):
self.oLabel2 = Label(self, text = "whoops2")
self.oLabel2.grid()
def openfile1(self):
file1 = tkFileDialog.askopenfile(title = "choose a file, *****", parent=root, mode = 'rb')
self.rfile1 = file1.read()
tkMessageBox.showinfo("oy", self.rfile1, parent=root)
def openfile2(self):
file2 = tkFileDialog.askopenfile(parent=root, mode='rb')
self.rfile2 = file2.read()
tkMessageBox.showinfo("hola", self.rfile2, parent=root)
app = Application()
app.master.title("whiggy whompus")
app.mainloop()
++_+++_+++_+++_+++_+++_+++
** Never mind! ** This question is answered! it just needed this at the bottom instead of that root beezwax...
yup. it was the bottom. it just needed a little code cleaning :).... never mind. thanks anyway!
#omit root
app = App()
app.mainloop()
++_+++_+++_+++_+++_+++_++++
I've tried hard for two hours to get rid of this second window. After I implemented the popup to ask for the folder name, I suddenly had two windows open when the program runs. I just want one, it's really quite aggravating. I want this program to open one window with four buttons, and have a title above them. one of the buttons asks for input, and then it goes away. can someone help me get back to one window? thank you. i apologize for the messy code, it's my first script of this style.
#!/usr/bin/python
#from Tkinter import *
import Tkinter as tk
import os
import tkFileDialog
class App(tk.Tk):
#class App:
#def __init__(self, master):
def __init__(self):
tk.Tk.__init__(self)
frame = tk.Frame(self)
frame.pack()
self.button = tk.Button(frame, text="leave", fg="red", command=frame.quit)
self.button.pack(side=tk.LEFT)
self.fetch = tk.Button(frame,text="Choose Folder for Pictures",fg="salmon",command=self.choose)
self.fetch.pack(side=tk.LEFT)
self.fetch = tk.Button(frame,text="Name folder on site (public)",command=self.on_click)
self.fetch.pack(side=tk.LEFT)
self.hi_there = tk.Button(frame, text="Create code for images", fg="brown", command=self.generate)
self.hi_there.pack(side=tk.LEFT)
#oroville dam is the highest in the country
w = tk.Label(text="MSP Art File Fetcher")
w.pack()
# Toplevel window
top = self.top = tk.Toplevel(self)
myLabel = tk.Label(top, text='Name of image directory:')
myLabel.pack()
self.myEntryBox = tk.Entry(top)
self.myEntryBox.pack()
mySubmitButton = tk.Button(top, text='Done', command=self.submit_name)
mySubmitButton.pack()
top.protocol("WM_DELETE_WINDOW", self.save_top)
top.withdraw()
def save_top(self):
self.top.withdraw()
def choose(self):
self.foldername=tkFileDialog.askdirectory()
print self.foldername
def name(self):
print self.foldername
def generate(self):
print self.foldername
self.path=self.foldername # failing, works
self.dirlist=os.listdir(self.path)
yoz = file('demcode.txt','wt')#totally works
f=open('demcode.txt', 'r+')
f.write(self.foldername)
f.write('\ndo not be a crack addic\n')
f.write('\n')
print self.dirlist
print self.dirlist[0]
self.y=len(self.dirlist)
print self.y
for x in range(0,self.y): #works great
#for x in range(0,4):#self.y: #failing
print 'We\'re on image %d' % (x)
#print in self.dirlist
f.write('\n'.join(self.dirlist[0]))#returns a vertical word!?
f.write('\n')
f.write(self.dirlist[0])
f.write('\n')
f.write('\n')
f.write('\n')
f.write(', '.join(self.dirlist))#CAUTION, will write over existing data
def say_hi(self):
print "don't be a crack addic"
def submit_name(self):
if self.myEntryBox.get() != "":
self.username = self.myEntryBox.get()
self.myEntryBox.delete(0, 'end')
self.top.withdraw()
def on_click(self):
self.top.deiconify()
"""
def show_name(self):
self.mainText.delete('1.0', 'end')
self.mainText.insert('end', 'Welcome ' + self.username + '!')
"""
root = tk.Tk()
app = App()
root.mainloop()
"""
"""
achieve this format of html. python program will loop every file in the directory, placing the name of the file in the set path (asked directory name), and write the approiate code for lightbox
"""
<h1>MSP (Acorns) Gallery</h1>
#http://www.mspart.com/lightbox.html
<div id="page">
<div id="images">
<ul class="gallery">
<li><img src="images/Pastels/alpha_farm.jpg" alt="description"></li>
<li><img src="images/Pastels/_day_island.jpg" alt="description">
</li></ul>
</div>
</div>
In your app class, you have already defined a Tk. So, when you define an app and another Tk, you are creating two windows. Removing one or the other should create only one window.