francesco gorini francesco gorini - 3 months ago 14
Python Question

Python Tkinter visually display seating arrangements

I am doing a school project, the purpose of the program is to sell tickets, the only problem i have is "Available and unavailable seats should be coloured/displayed differently and change when seat(s) are sold or returned.", i have a total of 250 seats, how to display them all on the screen? should i use a table or grid? or a canvas? i don't want you to code for me this is my assessment i just need an idea on how to tackle this problem efficiently.

I have tried to manually use buttons to display the seats, not efficient for 250 of them.

Button(master, text="seat").grid(row=0,column=0) * 250 != efficient


i also tried to create the buttons dynamically with a For loop

self.seats = []
row_count = 0
for i in range(250):
if(i > 5):
row_count += 1 #5 column table style
if(i < seats_taken):
self.seats.append(Button(master, bg='#ff0000')) #So taken seats are red bg
self.seats[i].grid(column=i+1 , row= row_count)
else:
self.seats.append(Button(master, bg='#ffffff')) #Available seats are white bg
self.seats[i].grid(column=i+1 , row= row_count)


How would you takle this problem?

Answer

I just approached this problem with a different scenario. You want some way to track the variables of each seat so you can come back and change the color. One way is to create a name for the tkinter widget, i.e. seat1 Where 1 would change for the seat number. You probably want the layout similar to the layout of the event so you want some rows. May I suggest also putting a frame in a canvas with a specific height and width. This way you can scroll through a frame without changing the size of the window.

Here's an example:

import tkinter as tk
from tkinter import ttk


class MainApp(ttk.Frame):

    def __init__(self, parent):
        ttk.Frame.__init__(self, parent)
        self.parent = parent
        self.mainframe = ttk.Frame(self.parent)
        self.canvas = tk.Canvas(self.mainframe)
        self.frame = ttk.Frame(self.canvas)
        self.gen_layout()
        self.column_row_config()

    def column_row_config(self):
        self.parent.rowconfigure(0, weight=1)
        self.parent.columnconfigure(0, weight=1)

    def gen_layout(self):
        self.mainframe.grid(row=0, column=0, sticky='nsew')
        self.canvas.grid(row=0, column=0, sticky='nsew')
        self.frame.grid(row=0, column=0, sticky='nsew')
        self.make_seats()
        self.access_seat_numb(1)

    def make_seats(self):
        # create 250 buttons on 10 rows
        seat_counter = 1
        for x in range(10):
            for y in range(1, 26):
                # print('creating seat %d' % seat_counter)
                b = ttk.Button(
                    self.frame, text='Seat%d' % seat_counter,
                    name='seat%d' % seat_counter
                )
                # doesn't matter that the columns won't line up
                b.grid(row=x, column=y)
                seat_counter += 1

    def access_seat_numb(self, numb):
        # print(self.frame.children)
        for k, v in self.frame.children.items():
            if k == 'seat%d' % numb:
                # run some code on a seat numb
                print(v._name)

if __name__ == '__main__':
    root = tk.Tk()
    MainApp(root)
    root.mainloop()

Now access_seat_numb is a method that you can call and change that button.