Borut Flis
Borut Flis

Reputation: 16375

How to reserve space inside scrollable column in PySimplegUI?

So I want to have a column which is scrollable. There will be plenty of elements inside it. Among other things two canvases that will have matplotlib figures printed.

layout = [[sg.Column(layout, vertical_scroll_only=True, scrollable=True,size=(800,400))]]

I understand now that this reserves space for the column of width 800 and height 400. Inside it you can scroll the allocated space of the elements.

[sg.Button("Load CSVs", key="-loadcsv-")],
[sg.Canvas(key='-CANVAS2-' ),sg.InputText(size=(10,1),key="threshold"), sg.Button("Set Threshold", key="-threshold-")],
[sg.InputText(size=(50, 1), key='-MODELNAME-'), sg.FileBrowse("Load Model")]

This is part of what is inside the column. I understand I can reserve space for the canvas, so that it has some space before the figure is even drawn, but I don't want that look. And also the things after the canvas will still be pushed off the visible space.

How can I allocate the space inside the column?

EDIT: I am adding two pictures, the first is the inital layout:

enter image description here

This is what happens when the matplotlib figure is inserted. Some of it just gets wiped out. I know I can pre-allocated the canvas size, but than I don't like the initial layout. enter image description here

Upvotes: 0

Views: 469

Answers (1)

Jason Yang
Jason Yang

Reputation: 13061

To set size of sg.Canvas to fit figure of Matplotlib, you have better specified option figsize and dpi, then you can get the size will be (figsize[0]*dpi, figsize[1]*dpi).

Method sg.pin is to keep the position of sg.Canvas when invisible. window['-CANVAS-'].Widget.pack() is to make it visible for no update method of sg.Canvas.

Method contents_changed called to update scrollbar of sg.column, here window.refresh() required to update GUI before it.

import matplotlib.pyplot as plt
import numpy as np
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import PySimpleGUI as sg
import matplotlib
matplotlib.use('TkAgg')

def draw_figure(canvas, figure):
    figure_canvas_agg = FigureCanvasTkAgg(figure, canvas)
    figure_canvas_agg.draw()
    figure_canvas_agg.get_tk_widget().pack(side='top', fill='both', expand=1)
    return figure_canvas_agg

column = [
    [sg.Button("Load CSVs", key="-loadcsv-")],
    [sg.pin(sg.Canvas(size=(500, 500), visible=False, key='-CANVAS2-')),
     sg.InputText(size=(10,1), key="threshold"),
     sg.Button("Set Threshold", key="-threshold-")],
    [sg.InputText(size=(50, 1), key='-MODELNAME-'),
     sg.FileBrowse("Load Model")],
]
layout = [[sg.Column(column, vertical_scroll_only=True, scrollable=True, size=(800, 400), key='-COLUMN-')]]
window = sg.Window('Demo Application - Embedding Matplotlib In PySimpleGUI', layout, finalize=True, element_justification='center', font='Helvetica 18')
fig_canvas_agg = None

while True:
    event, values = window.read()
    if event == sg.WINDOW_CLOSED:
        break
    elif event == "-threshold-":
        if fig_canvas_agg is None:
            fig = matplotlib.figure.Figure(figsize=(5, 4), dpi=100)
            t = np.arange(0, 3, .01)
            fig.add_subplot(111).plot(t, 2 * np.sin(2 * np.pi * t))
            fig_canvas_agg = draw_figure(window['-CANVAS2-'].TKCanvas, fig)
            window['-CANVAS2-'].Widget.pack()
            window.refresh()
            window['-COLUMN-'].contents_changed()

window.close()

Upvotes: 1

Related Questions