0

I'm making a database for my cadet corps, because our officers' organisation is a MESS and I want to organise things and I'm making a menu with buttons labeled after each master cadets. To make it aesthetically pleasing, I wanted to split it into three lines, but I keep messing it up.

Here's the ̶s̶p̶a̶g̶h̶e̶t̶t̶i̶ code in question

import PySimpleGUI as sg

SO = ["LastName1","FirstName"]
Mettraux = ["LastName2","FirstName"]
JayForbes =["LastName3","FirstName"]
JacForbes =["LastName4","FirstName"]
Callahan = ["LastName5","FirstName"]
Foster = ["LastName6","FirstName"]
MB = ["LastName7","FirstName"]
Peever = ["LastName8","FirstName"]
Carron = ["LastName9","FirstName"]
Woodward = ["LastName10","FirstName"]
Poire = ["LastName11","FirstName"]
KA = ["LastName12","FirstName"]
Cabanaw = ["LastName13","FirstName"]
Veldman = ["LastName14","FirstName"]

MCadets = [SO,Mettraux,JayForbes,JacForbes,Callahan,Foster,MB,Peever,Carron,Woodward,Poire,KA,Cabanaw,Veldman]
MCadets = sorted(MCadets)

cadetsButtons = []
for i in MCadets:
    cadetsButtonsSection = []
    fullName = i[0],", ",i[1]
    fullName = "".join(fullName)
    cadetsButtonsSection.append(sg.Button(f"{fullName}"))
    cadetsButtons.append(cadetsButtonsSection)
    cadetsButtonsSection = []

mainMenu = [[sg.Text("Hello, who would you like to check?")],
            [cadetsButtons]
            ]

sg.Window("Master Cadets Database - Main Menu",mainMenu).read()

I tried a whole sort of blind tinkering without getting the wished result, which is to have the names as evenly split as possible between three lines.

Here's what it currently looks like: Names stacking on top of eachother

  • What do you mean by "split it into three lines"? Are these related to `SO`, `MB`, and `KA`? What would be the final result you are expecting? Link to a screenshot would also help readers to understand the problem. – dudung Mar 05 '23 at 22:29
  • @dudung What I meant to say was three rows of buttons and an image of the problem has been added for better comprehension – Cassidy Mettraux Mar 05 '23 at 22:47
  • It looks like you have a list of first and last names. Data like this is commonly shown in a table and each row of the table is clickable to view or edit the object represented by that row. – Code-Apprentice Mar 05 '23 at 22:50
  • @Code-Apprentice ~4 buttons, those buttons would show each Master cadets' information (last name, first name, rank, who they are instructing, etc.) – Cassidy Mettraux Mar 05 '23 at 22:52
  • As an aside, I recommend that you learn about classes. You can make a `Cadet` class that represents each cadet and then create a list of cadets. This will allow your program to be able to handle any number of cadets. Compare this to your current code which only works with a fixed set of cadets instead. – Code-Apprentice Mar 05 '23 at 22:52
  • @Code-Apprentice I probably will, OOP seems better than linear programming or function-based programming. – Cassidy Mettraux Mar 05 '23 at 22:55
  • @KevinMettraux They all have their uses. None is "better". Learning about each tool will help you know that it exists so you can use it when it is appropriate. In this particular case, a class is better than a list for storing a first name and last name. Lists are good for storing similar data. So like a list of cadet objects where each item in the list is the same kind of thing. On the other hand "last name" is a different kind of thing than "first name", so it doesn't make sense to store these together in a list. Instead, putting them in a class makes sense because they are characteristics – Code-Apprentice Mar 05 '23 at 22:59
  • ....of a cadet. Also, classes allow you to name these characteristics, so you can do `i.first_name` and `i.last_name` instead of `i[0]` and `i[1]`. This makes your code more understandable. If you come back to this code later, will you know that `i[0]` means "last name"? If it were me, I will forget and think it is first name since it is the first item in the list. – Code-Apprentice Mar 05 '23 at 23:02
  • 1
    As @Code-Apprentice suggested, you could take a look at https://stackoverflow.com/a/51467756/9475509 for `Person` class and modify it to `Cadet` class, and then implement that to a GUI. – dudung Mar 05 '23 at 23:05

1 Answers1

0

Confirm your layout is in list of lists of elements.

Check if next line by index of an element:

import PySimpleGUI as sg


names = [f'Lastname{i+1:0>2d}, Firstname{i+1:0>2d}' for i in range(14)]
total = len(names)
lines = 3
width = (total//lines + 1) if len(names) % lines else (total//lines)    # buttons per row

buttons, line = [], []
limit = total - 1
for i, name in enumerate(names):
    line.append(sg.Button(names[i]))
    if i % width == width-1 or i == limit:
        buttons.append(line)
        line = []

layout = [[sg.Text("Hello, who would you like to check?")]] + buttons
sg.Window("Master Cadets Database - Main Menu", layout).read(close=True)

enter image description here

Jason Yang
  • 11,284
  • 2
  • 9
  • 23