0
votes

The example displays three frames with identcal contents. I need to loop through an arbitrary number of different data sets: (img_file, name and color)

{

import tkinter as tk
from tkinter import *
from tkinter import ttk
from PIL import Image, ImageTk


class TestFrame(tk.Frame):
    def __init__(self):
        super().__init__()
 
        image = Image.open(img_file)
        stamp = ImageTk.PhotoImage(image)
        
        labelImage = ttk.Label(self, image=stamp)
        labelImage.grid(row=0, column=0, rowspan=3)
        labelImage.image = stamp
        ttk.Label(self, text=name).grid(row=3, column=0)
        ttk.Label(self, text=color).grid(row=1, column=2)
        ttk.Label(self, text='Value: ').grid(row=0, column=1)
        ttk.Label(self, text='Color: ').grid(row=1, column=1)
        ttk.Label(self, text='Size: ').grid(row=2, column=1)        


class TestMainApplication(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("Test Application")

        self.testFrame1 = TestFrame()
        self.testFrame2 = TestFrame()
        self.testFrame3 = TestFrame()
        self.testFrame1.grid(row=0, column=0, rowspan=3, columnspan=3, sticky='nsew')
        self.testFrame2.grid(row=3, column=0, rowspan=3, columnspan=3, sticky='nsew')
        self.testFrame3.grid(row=0, column=3, rowspan=2, columnspan=3, sticky='nsew')


img_file = 'myfile.jpg'
name = 'Flying Post Horn'
color = 'Orange Brown'


if __name__ == "__main__":
    TestMainApplication().mainloop()

}

The frame gridding "self.testFrame1.grid(row=0, column=0, rowspan=3, columnspan=3, sticky='nsew')" should be controlled by variables, e.g. row=r and column=c The difficulty is in my view on how to pass necessary information between classes.

1
What is it that you want to happen? What have you tried? - figbeam
Let the data img_file, name and color be lists of given length. I've tried to put the lists inside TestMainApplication, but this reults in "NameError: name 'img_file' is not defined" - Kjell
Let the data img_file, name and color be lists of given length. I've tried to put the lists inside TestMainApplication, but this results in "NameError: name 'img_file' is not defined" I want to loop through the lists and position the frames with its label widgets in ordered rows and colum. The content of the labes must be updated accordingly. Since the frames in the exampel allways contains three labels, I thougth it would be a good idea to define a class for this. I can easily make this work by putting everything in a single class (Appwindow()) where the lists are defined outside the class. - Kjell

1 Answers

0
votes

Ok, I'm not sure I understood this correctly but here's a way to think; you always need a reference to an instance to be able to communicate with it. So when I create an instance of TestFrame() I'll have to pass a reference to its creator: self. Now both master and server know each oters names they can pass and get data as they like.

To be able to ask the master instance for image I'll have to make the image list an instance variable. I made lists for names and colors as well.

See example below:

import tkinter as tk
from tkinter import *
from tkinter import ttk
from PIL import Image, ImageTk


class TestFrame(tk.Frame):
    def __init__(self, master, img_no, name_no, color_no):
        super().__init__()
 
        # Create image from item in master image_list
        image = Image.open(master.image_list[img_no])
        stamp = ImageTk.PhotoImage(image)
        labelImage = ttk.Label(self, image=stamp)
        labelImage.grid(row=0, column=0, rowspan=3)
        labelImage.image = stamp
        
        ttk.Label(self, text=master.name_list[name_no]).grid(row=3, column=0)
        ttk.Label(self, text=master.color_list[color_no]).grid(row=1, column=2)
        ttk.Label(self, text='Value: ').grid(row=0, column=1)
        ttk.Label(self, text='Color: ').grid(row=1, column=1)
        ttk.Label(self, text='Size: ').grid(row=2, column=1)        


class TestMainApplication(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("Test Application")
        
        # Create the lists as instance variables
        self.image_list = ['jones.png', 'idle.png', 'cleese.png']
        self.name_list = ['Jones', 'Idle', 'Cleese']
        self.color_list = ['tomato', 'wheat', 'orange']

        # Pass parameters to TestFrame at creation, including instance reference
        self.testFrame1 = TestFrame(self, 0, 0, 0)
        self.testFrame2 = TestFrame(self, 1, 1, 1)
        self.testFrame3 = TestFrame(self, 2, 2, 2)
        self.testFrame1.grid(row=0, column=0, rowspan=3, columnspan=3, sticky='nsew')
        self.testFrame2.grid(row=3, column=0, rowspan=3, columnspan=3, sticky='nsew')
        self.testFrame3.grid(row=0, column=3, rowspan=2, columnspan=3, sticky='nsew')


if __name__ == "__main__":
    TestMainApplication().mainloop()

Is this what you are after?