Codename_DJ
Codename_DJ

Reputation: 563

pysimplegui table multiline text handling

I am filling a pySimpleGui table from a log file. Most logs are single line but some multiline text are present.Table in layout is defined like this [sg.Table(key="mainTable",values=data, headings=header_list, display_row_numbers=False,col_widths=size_list,auto_size_columns=False, num_rows=40)] Currently multiline texts are overlapping over the next line text. Is there any way to show multiline text in a single cell or text-cropping is the only way?

Upvotes: 2

Views: 4645

Answers (2)

Jason Yang
Jason Yang

Reputation: 13061

There's no option to wrap text in sg.Tree or ttk.Treeview.

As I know, the only way is to insert '\n' into your text, then it will wrap to next line.

To show all lines in a row, you have to set option row_height large enough to fit all lines. Here, another problem will be generated for row_height.

  • You won't see next line if row height is too small to shown all wrap lines.
  • If you set row_height large enough, you will still see same space occupied if only one line.
  • Text will be aligned vertical center

It seems there's no way to set row height for different rows.

example here,

import textwrap
from random import randint, choice
import PySimpleGUI as sg

def wrap(string, lenght=15):
    return '\n'.join(textwrap.wrap(string, lenght))

sg.theme('DarkBlue')
sg.set_options(font=('Courier New', 12))

column_width = 15
word = "1234567890"*5

data = [[wrap(word[:randint(1, 50)], column_width) for col in range(4)] for row in range(30)]
header_list = [f'Column {i}' for i in range(4)]
size_list = [column_width+2]*4

layout = [
    [sg.Table(
        key="-TREE-",
        values=data,
        headings=header_list,
        display_row_numbers=False,
        col_widths=size_list,
        auto_size_columns=False,
        num_rows=10,
        row_height=80, 
        alternating_row_color='green',
        )],
]

window = sg.Window('Tree Element Test', layout, finalize=True)
tree = window['-TREE-'].Widget

while True:
    event, values = window.read()
    if event in (sg.WIN_CLOSED, 'Cancel'):
        break

window.close()

Another way is more difficult to implement, using other elements to simulate a tree or a table, like example from Nagaraj Tantri

Upvotes: 1

Nagaraj Tantri
Nagaraj Tantri

Reputation: 5232

If you look into their QT Table or Web Table accepting auto_size_columns and ignoring it for Table specifically like in QT not using it for Table but for Tree and Web its commented!

After checking their allowed options and seeing if we could apply setWordWrap directly on QTTable or similar on anything on Widget, it's hard to even find it.

But on other hand, they do have many examples to custom build a tabular format: Demo_Table_Simulation.py

Here is what I tried to generate a custom table:

#!/usr/bin/env python
import PySimpleGUI as sg
import csv
import math

# Show CSV data in Table
sg.theme('Dark Red')

def table_example():
    filename = sg.popup_get_file('addresses.csv', no_window=True, file_types=(("CSV Files","*.csv"),))
    # --- populate table with file contents --- #
    if filename == '':
        return
    data = []
    header_list = []
    button = sg.popup_yes_no('Does this file have column names already?')
    if filename is not None:
        with open(filename, "r") as infile:
            reader = csv.reader(infile)
            if button == 'Yes':
                header_list = next(reader)
            try:
                data = list(reader)  # read everything else into a list of rows
                if button == 'No':
                    header_list = ['column' + str(x) for x in range(len(data[0]))]
            except:
                sg.popup_error('Error reading file')
                return
    sg.set_options(element_padding=(0, 0))

    values = []
    for row in data:
        # Calculate the size of sg.Text based on the length of the text greater than some size
        values.append([sg.Text(i, size=(15, math.ceil(1 if len(i) <= 15 else len(i)/15))) for i in row])

        # Add a horizontal separator with length and calculate the width
        length=15*len(values[0])
        values.append([sg.Text('_'*length)])


    input_rows = [[sg.Input(size=(15,1), pad=(0,0)) for col in range(4)] for row in range(10)]

    layout = values

    window = sg.Window('Table', layout, grab_anywhere=False)
    event, values = window.read()

    window.close()

table_example()

The output looks something like this:

enter image description here

Upvotes: 2

Related Questions