henry
henry

Reputation: 975

Click through images and text with a tkinter GUI in Python

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:

enter image description here

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:

enter image description here

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

Answers (1)

Bruno Vermeulen
Bruno Vermeulen

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

Related Questions