Reputation: 975
I have a pandas database with slides and text named "df_slides". I would like to make a tkinter GUI to click through the slides and display the text, like that:
This is what I have implemented so far:
import tkinter
from PIL import Image, ImageTk
import base64
import pandas as pd
i = 0
def load_next_img():
global pil_image, tk_image, i, text
i = i+1
base64string = df_slides["Slide_Image"][i]
imgdata = base64.b64decode(base64string)
pil_image = Image.open(io.BytesIO(imgdata))
tk_image = ImageTk.PhotoImage(pil_image)
label['image'] = tk_image
text = df_slides["Text"][i]
def load_previous_img():
global pil_image, tk_image, i, text
i = i-1
base64string = df_slides["Slide_Image"][i]
imgdata = base64.b64decode(base64string)
pil_image = Image.open(io.BytesIO(imgdata))
tk_image = ImageTk.PhotoImage(pil_image)
label['image'] = tk_image
text = df_slides["Text"][i]
root = tkinter.Tk()
label = tkinter.Label(root)
label.pack(side = "bottom", fill = "both", expand = "yes")
load_next_img()
nextbutton = tkinter.Button(text="next", command=load_next_img)
nextbutton.pack()
backbutton = tkinter.Button(text="back", command=load_previous_img)
backbutton.pack()
T = tkinter.Text(root, height=10, width=30)
T.pack()
T.insert(tkinter.END, text)
root.mainloop()
This is the current result:
As you can see the text does not use the full width and more importantly it does not update together with the slide when I press "next" and "back". The slide updates but the text stays the same all the time.
Upvotes: 0
Views: 504
Reputation: 3465
T.insert(tkinter.END, text)
must appear in the functions load_next_img
and load_previous_img
. For me the easiest way is to define a class 'Slides' to get the namespace right. Note to update the label use self.label.configure(image=tk_image)
Below an example where I have commented out the dataframe but should give a hint on how to resolve. Note to clear the text I have also added a line self.T.delete('1.0', tkinter.END)
import tkinter
from PIL import Image, ImageTk
import base64
import pandas as pd
class Slides:
def __init__(self):
self.text_array = ['hello there', 'good bye']
self.pic_array = ['test_1.jpg', 'test_2.jpg']
self.root = tkinter.Tk()
nextbutton = tkinter.Button(text="next", command=self.load_next_img)
nextbutton.pack()
backbutton = tkinter.Button(text="back", command=self.load_previous_img)
backbutton.pack()
self.slide_image = tkinter.Label(self.root)
self.slide_image.pack(side="bottom", fill="both", expand="yes")
self.text_box = tkinter.Text(self.root, height=10, width=30)
self.text_box.pack()
self.i = -1
self.load_next_img()
self.root.mainloop()
def load_next_img(self):
self.i += 1
# base64string = df_slides["Slide_Image"][i]
# imgdata = base64.b64decode(base64string)
pil_image = Image.open(self.pic_array[self.i % 2])
pil_image = pil_image.resize((200, 200), Image.ANTIALIAS) # just for my convenience
tk_image = ImageTk.PhotoImage(image=pil_image)
self.slide_image.configure(image=tk_image)
self.slide_image.image = tk_image
text = self.text_array[self.i % 2]
self.text_box.delete('1.0', tkinter.END)
self.text_box.insert(tkinter.END, text)
def load_previous_img(self):
self.i -= 1
# base64string = df_slides["Slide_Image"][i]
# imgdata = base64.b64decode(base64string)
pil_image = Image.open(self.pic_array[self.i % 2])
pil_image = pil_image.resize((200, 200), Image.ANTIALIAS) # just for my convenience
tk_image = ImageTk.PhotoImage(image=pil_image)
self.slide_image.configure(image=tk_image)
self.slide_image.image = tk_image
text = self.text_array[self.i % 2]
self.text_box.delete('1.0', tkinter.END)
self.text_box.insert(tkinter.END, text)
def main():
slides = Slides()
if __name__ == '__main__':
main()
To get the positioning right for the buttons, label and text I would advice to use grid
, rather than pack
.
PS. I took the liberty to change the variables label
to slide_image
and T
to text_box
Upvotes: 1