Tretron
Tretron

Reputation: 11

Auto generate frame with checkbox per item in PysimpleGUI on python

My issue: i am trying to auto generate code from a json array with the products of an order. I want to create a layout where each product line, has an frame with an own checkbox and info and the frames are sorted as a list.

this is my desired layout:

Wireframe of layout

However my current layout is:

Current Pysimplegui layout

I tried to play around with putting brackets on diffrent places to get the frames to line up correctly. I also tried around to search for a few diffrent tutorials and questions on stack overflow to see if something comes close to what I want to achieve. however I fear that I am fundementally miss understanding something about PySimpleGui.

The code I use to generate the layout is as follows:

def __create_checkbox_array(self, input_string):
    formated_array = []
    i = 0
    if len(input_string) != 0:
        for item in input_string:
            formated_array.append(  sg.Frame(f'Item Line : {i}', [[ sg.Checkbox(item, default = True, key= f"-item:{i}-") ]] )   )
            i += 1
    else:
        formated_array.append(sg.Text('No items found', key="-item:0-"))
    print(formated_array)
    return formated_array
def __item_selection_layout(self, item_list):
    layout_over_view =  [
        [
            sg.Text("Order Nummer"),
    
            sg.In(size=(20, 1), enable_events=True, key="-order-"),
    
            sg.Button("Zoeken", key="-search-"),
            
            
    
        ] ,  self.__create_checkbox_array(item_list)
        
        
        ]
    image_viewer_column = [

        [sg.Text("Choose an image from list on left:")],
    
        [sg.Text(size=(40, 1), key="-TOUT-")],
    
        [sg.Image(key="-IMAGE-")],
    
    ]
    layout = [

        [
    
            sg.Column(layout_over_view),
    
            sg.VSeperator(),
    
            sg.Column(image_viewer_column),
            
            sg.VSeperator(),
            
           
            

        ]
    
    ]
    return sg.Window("Image Viewer", layout)

both functions are private within a class that is used to manage the GUI.where __create_checkbox_array takes in an json file that constists of all the product lines within a order.

Upvotes: 1

Views: 662

Answers (2)

Jason Yang
Jason Yang

Reputation: 13061

Here's the way I create only the scrollable table with items.

import PySimpleGUI as sg

def Text(text, size, justification, expand_x=None, key=None):
    return sg.Text(text, size=size, pad=(1, 1), expand_x=expand_x,
        justification=justification, key=key)

def line_frame(index, number, description, amount):
    font1 = ("Courier New", 16)
    frame_layout = [
        [Text("Product #", 10, 'c'), Text(number, 12, 'l', key='t'),
         Text("Amount",     7, 'c'), Text(amount, 10, 'r'),],
        [Text(description, (39, 3), 'l', expand_x=True)],
    ]
    layout = [
        [sg.Checkbox('Print', font=font1, enable_events=True, key=f'Print {index}'),
         sg.Frame('', frame_layout, pad=((0, 5), (0, 5)), relief=sg.RELIEF_FLAT, background_color='#4b5a69'),],
    ]
    return sg.Frame(f'Line {index:0>4d}', layout, pad=((0, 5), 0))

data = [
    ('REQ0011118', 'USB', 1),
    ('REQ0011932', 'Tire Disposal '*5, 2),
    ('REQ0011476', 'Labor', 4.5),
    ('4500236642', 'None', 'None' ),
    ('4500221028', 'Toner', 1),
    ('4500253427', 'None', 'None'),
    ('REQ0013911', 'HP 35A BLACK TONER '*4, 30),
    ('12-64006.01', 'Radiation Oncology '*3, 1),
    ('REQ0014515', 'Black Toner Cartridge for CLJ 4700 '*5, 16),
    ('4500200308', '1" ss 90* elbow , threaded', 4),
]

font = ("Courier New", 11)
sg.theme("DarkBlue3")
sg.set_options(font=font, )

column_layout = [
    [line_frame(i+1, number, description, amount)]
        for i, (number, description, amount) in enumerate(data)
]
layout = [
    [sg.Column(column_layout, scrollable=True, vertical_scroll_only=True)],
]
window = sg.Window("test", layout, margins=(0, 0), finalize=True)

while True:
    event, values = window.read()
    if event in (sg.WINDOW_CLOSED, 'Exit'):
        break
    print(event, values)
window.close()

enter image description here

Upvotes: 1

Tretron
Tretron

Reputation: 11

I figured it out with the help of someone not from this site.

The problem was missunderstanding how PySimpleGUI frames work. I changed the code to the following:

def __create_checkbox_array(self, input_string):
    formated_array = [[sg.Frame('Order Number',  [[
         
                 sg.In(size=(20, 1), enable_events=True, key="-order-"),
         
                 sg.Button("Zoeken", key="-search-"),
         
             ]]
        )]]
    i = 0
    if len(input_string) != 0:
        for item in input_string:
            formated_array.append([sg.Frame(f'Item:{i}',[[sg.Checkbox(item, default = True, key= f"-item:{i}-")]])])
            i += 1
    else:
        formated_array.append([sg.Frame('',[[sg.Text('No items found', key="-item:0-")]])])
    print(formated_array)
    return formated_array

This causes each frame to be correctly loaded in. Mixing non frames and frames causes the poor results as the first object that contained the 'header' was not a frame.

then the whole string can be put put into the function to create the layout:

layout_over_view = self.__create_checkbox_array(item_list)

Upvotes: 0

Related Questions