I've finished the movie search script. Still a little ruff around the edges but, works. I had trouble placing text in the textbox so I went with using a frame in the textbox. That way I could kinda order the layout a little. I welcome any input. Remember it will take a few seconds to get the results as it does a few queries. My understanding of the imdb database may search through several pages to get the information.
# Do the imports from imdb import Cinemagoer import tkinter as tk from tkinter import ttk from urllib.request import urlopen from PIL import ImageTk, Image import io class Data: ''' The Data class retrieves all information from user input Searches person and movies returns all relevant information ''' def __init__(self): self.action = Cinemagoer() def search_person(self, name): person = self.action.search_person(name.strip())[0] return person.get('name'), person.personID def get_person(self, id): person = self.action.get_person(id) jobs = [job for job in person.get('filmography').keys()] movies = [movie for movie in person['filmography'][jobs[0]]] return person.get('name'), movies def search_movies(self, title): return self.action.search_movie(title) def get_movie(self, movie_id): if movie_id: movie = self.action.get_movie(movie_id) return movie class Window: ''' Window class is for visual and has fields and buttons for the Controller class to use ''' def __init__(self, parent): parent.columnconfigure(0, weight=1) parent.rowconfigure(0, weight=1) parent.minsize(800,600) parent['padx'] = 5 parent['pady'] = 3 parent['bg'] = '#c0c0c0' parent.title('Movie Search') container = tk.Frame(parent, bg='#333333') container.grid(column=0, row=0, sticky='news') container.grid_columnconfigure(0, weight=3) container.grid_rowconfigure(3, weight=3) header = tk.Label(container, text='Movie Search', fg='#ffffff', bg='#333333') header['font'] = 'tk.HEADER 28 bold' header.grid(column=0, row=0, sticky='new', padx=2, pady=2) self.msg = tk.Label(container, text='Messages: ', bg='#555555', fg='#FFFFFF', anchor='w', padx=10) self.msg['font'] = 'tk.MENU 13 normal' self.msg.grid(column=0, row=1, sticky='new', padx=2, pady=2) row1 = tk.Frame(container, bg='#555555') row1.grid(column=0, row=2, sticky='new', padx=2, pady=2) for i in range(5): weight = 4 if i == 3 else 3 row1.grid_columnconfigure(i, weight=weight, uniform='cols') row2 = tk.Frame(container, bg='#555555') row2.grid(column=0, row=3, sticky='news', padx=2, pady=2) row2.grid_columnconfigure(0, weight=3, uniform='tree') row2.grid_columnconfigure(2, weight=3, uniform='tree') row2.grid_rowconfigure(0, weight=3) row3 = tk.Frame(container, bg='#555555') row3.grid(column=0, row=4, sticky='new', padx=2, pady=2) row3.grid_columnconfigure(0, weight=3) label = tk.Label(row1, text='Search by:', bg='#555555', fg='#ffffff') label['font'] = 'None 12 normal' label.grid(column=0, row=0, sticky='new', padx=2, pady=4) self.options = ['Actors/Actresses', 'Movie Title'] self.picked = tk.StringVar() self.picked.set(self.options[0]) self.searchby = tk.OptionMenu(row1, self.picked, *self.options) self.searchby['font'] = 'None 10 normal' self.searchby.grid(column=1, row=0, sticky='new', padx=2, pady=4) self.searchby.config(border=0) label = tk.Label(row1, text='Search For:', bg='#555555', fg='#ffffff') label['font'] = 'None 12 normal' label.grid(column=2, row=0, sticky='new', padx=2, pady=4) self.entry = tk.Entry(row1) self.entry['font'] = 'None 12 normal' self.entry.grid(column=3, row=0, sticky='new', padx=2, pady=4) self.button = tk.Button(row1, text='Search') self.button.grid(column=4, row=0, sticky='new', padx=2) columns = ('Title', 'Released', 'Movie ID') self.left_tree = ttk.Treeview(row2, columns=columns, show='headings', selectmode='browse') for column in columns: if column == columns[0]: self.left_tree.column(column, minwidth=0, width=300, stretch='yes') else: self.left_tree.column(column, minwidth=0, width=100) self.left_tree.heading(column, text=column.title()) self.left_tree.grid(column=0, row=0, sticky='news', padx=2) left_scroll = tk.Scrollbar(row2, orient='vertical', command=self.left_tree.yview) self.left_tree.config(yscrollcommand=left_scroll.set) left_scroll.grid(column=1, row=0, sticky='ns', padx=2) self.textbox = tk.Text(row2) self.textbox.grid(column=2, row=0, sticky='news', padx=2) self.textbox.grid_columnconfigure(0, weight=3) textbox_scroll = tk.Scrollbar(row2, orient='vertical', command=self.textbox.yview) self.textbox.config(yscrollcommand=textbox_scroll.set) textbox_scroll.grid(column=3, row=0, sticky='ns', padx=2) sig = tk.Label(row3, text='my-python.org', bg='#333333', fg='#ffffff') sig['font'] = 'None 10 normal' sig.grid(column=0, row=0, sticky='new') class Controller: ''' Controller class handles all communications between the Data and Window class ''' def __init__(self, data, window): self.data = data self.window = window self.images = [] # Button Commands self.window.button['command'] = self.search #Dropdown command self.window.picked.trace('w', self.clear) # Bind treeview self.window.left_tree.bind('<<TreeviewSelect>>', self.details) def search(self): ''' Search method will lookup either actor or movie depending on the selection in the Window class. At the momment the search only works for finding actors and actresses ''' # Clear the views self.window.left_tree.delete(*self.window.left_tree.get_children()) self.window.textbox.delete('1.0', 'end') try: self.frame.destroy() except AttributeError: pass # Get the param for either person search or movie search picked = self.window.picked.get() # Get the name of the search. person or movie name = self.window.entry.get().strip() # Set alternation colors for the treeview self.window.left_tree.tag_configure('oddrow', background='#ccceee') self.window.left_tree.tag_configure('evenrow', background='white') # Clear the entry field self.window.entry.delete(0, 'end') # # Person was selected for search if picked == 'Actors/Actresses': self.window.msg['text'] = f'Messages: Search results for {name.title()}' # Call the Data class search_person method person = self.data.search_person(name.strip()) # Get relevant data using the person[1] which is set to the person id data = self.data.get_person(person[1]) # Create empty list to hold the data wanted movie_list = [] # Loop through the data getting relevant information # Also checking that there is a year for the movie release # This helps in not getting any movies not yet released for movie in data[1]: if movie.get('year'): movie_list.append((movie.get('title'), movie.get('year'), movie.movieID)) elif movie.get('year') == None: year = self.data.get_movie(movie.movieID).get('year') if year: movie_list.append((movie.get('title'), year, movie.movieID)) else: pass else: movies = self.data.search_movies(name.strip()) movie_list = [] for movie in movies: if movie.get('year'): movie_list.append((movie.get('title'), movie.get('year'), movie.movieID)) elif movie.get('year') == None: year = self.data.get_movie(movie.movieID).get('year') if year: movie_list.append((movie.get('title'), year, movie.movieID)) else: pass movie_list.sort(key=lambda year: year[1]) # Loop through the movie_list and insert into the treeview with alternating colors for index, movie in enumerate(movie_list): if index % 2 == 0: self.window.left_tree.insert('', index, values=(movie[0], movie[1], movie[2]), tags=('oddrow',)) else: self.window.left_tree.insert('', index, values=(movie[0], movie[1], movie[2]), tags=('evenrow',)) def details(self, id): item = self.window.left_tree.focus() try: id = self.window.left_tree.item(item)['values'][2] except IndexError: pass try: self.frame.destroy() except AttributeError: pass try: details = self.data.get_movie(id) title = details.get('title') cast = details.get('cast') year = details.get('year') plot = details.get('plot outline') cover = details.get('cover') rating = details.get('rating') air_date = details.get('original air date') cast_list = [c.get('name') for c in cast] cast = ', '.join(cast_list) img_url = urlopen(cover).read() img = Image.open(io.BytesIO(img_url)) image = ImageTk.PhotoImage(img) self.frame = tk.Frame(self.window.textbox,bg='white') self.frame.grid(column=0, row=0, sticky='news') self.frame.grid_columnconfigure(0, weight=3) label = tk.Label(self.frame, text=f'Title', anchor='w',bg='white') label['font'] = 'tk.HEADER 10 bold' label.grid(column=0,row=0,sticky='new',pady=8) label = tk.Label(self.frame, text=f'{title}', anchor='w',bg='white') label.grid(column=1,row=0,sticky='new',pady=8) label = tk.Label(self.frame, text=f'Year:', anchor='w',bg='white') label['font'] = 'tk.HEADER 10 bold' label.grid(column=0, row=1, sticky='new',pady=8) label = tk.Label(self.frame, text=f'{year}', anchor='w',bg='white') label.grid(column=1, row=1, sticky='new',pady=8) label = tk.Label(self.frame, text=f'Air Date:', anchor='w',bg='white') label['font'] = 'tk.HEADER 10 bold' label.grid(column=0, row=2, sticky='new',pady=8) label = tk.Label(self.frame, text=f'{air_date}', anchor='w',bg='white') label.grid(column=1, row=2, sticky='new',pady=8) label = tk.Label(self.frame, text=f'Cover Image:', image=image, compound='bottom',anchor='w',bg='white') label['font'] = 'tk.HEADER 10 bold' label.grid(column=0, row=3, columnspan=2, sticky='new',pady=8) label = tk.Label(self.frame, text=f'Rating:', anchor='w',bg='white') label['font'] = 'tk.HEADER 10 bold' label.grid(column=0, row=4, sticky='new',pady=8) label = tk.Label(self.frame, text=f'{rating}', anchor='w',bg='white') label.grid(column=1, row=4, sticky='new',pady=8) label = tk.Label(self.frame, text=f'Plot:', anchor='w', wraplength=800, justify='left',bg='white') label['font'] = 'tk.HEADER 10 bold' label.grid(column=0, row=5, sticky='new',pady=8) label = tk.Label(self.frame, text=f'{plot}', anchor='w', wraplength=800, justify='left',bg='white') label.grid(column=1, row=5, sticky='new',pady=8) label = tk.Label(self.frame, text=f'Cast:', anchor='w', wraplength=800, justify='left',bg='white') label['font'] = 'tk.HEADER 10 bold' label.grid(column=0, row=6, sticky='new',pady=8) label = tk.Label(self.frame, text=f'{cast}', anchor='w', wraplength=800, justify='left',bg='white') label.grid(column=1, row=6, sticky='new',pady=8) self.window.textbox.delete('1.0', tk.END) self.window.textbox.insert('end', self.frame) self.images.append(image) except TypeError: pass def clear(self, write, index, mode): # Clear the treevies self.window.left_tree.delete(*self.window.left_tree.get_children()) self.window.textbox.delete('1.0', 'end') self.window.msg['text'] = 'Messages: ' try: self.frame.destroy() except AttributeError: pass if __name__ == '__main__': root = tk.Tk() img = urlopen('https://my-python.org/images/code-forum/light/light_on.png') data = img.read() image = tk.PhotoImage(data=data) root.wm_iconphoto(True, image) controller = Controller(Data(), Window(root)) root.mainloop()
I welcome all feedback.
The only dumb question, is one that doesn't get asked.
My Github
How to post code using bbtags
Download my project scripts
The only dumb question, is one that doesn't get asked.
My Github
How to post code using bbtags
Download my project scripts