I would like for tab 2 to show a table of all existing reservations.
I have tried making the dataframe a string and then a list.
import pandas as pd
from pandas import DataFrame
#create dataframe to simulate databse with names and dates
data = {'Name': ['Joe Smith', 'Jason Leary','Bill Murray'],
'Start Date': ['2019/10/01', '2019/11/01','2019/12/01'],
'End Date': ['2019/10/15', '2019/11/15','2019/12/15']
}
df = pd.DataFrame (data, columns = ['Name','Start Date','End Date'])
Data_Table = df.to_string()
# Stuff inside window
tab1_layout = [
[sg.Text('The Scheduler')],
[sg.Combo(name, size=(30,4), enable_events=True)],
[sg.Combo(reason, size=(30,4), enable_events=True)],
[sg.T('Start Date')],
[sg.In('', size=(10,1), key='input1')],
[sg.CalendarButton('Choose Start Date', target='input1', key='date1',format='%Y/%m/%d')],
[sg.T('End Date')],
[sg.In('', size=(10,1), key='input2')],
[sg.CalendarButton('Choose End Date', target='input2', key='date2', format='%Y/%m/%d')],
[sg.Button('Submit')]]
# create a table to show names and dates with an export to CSV button
tab2_layout = [[sg.Table(values=Data_Table, max_col_width=25, background_color='lightblue',
auto_size_columns=True, justification='right', alternating_row_color='blue', key='_table_')],
[sg.Button('Update')]]
tab3_layout = [[sg.T('This is inside tab 3')],
[sg.In(key='_in3_')]]
# create the window
layout = [[sg.TabGroup([[sg.Tab('Scheduler', tab1_layout, key='_mykey_'),
sg.Tab('Schedule', tab2_layout),
sg.Tab('Admin', tab3_layout)]],
key='_group2_', title_color='darkgrey',
selected_title_color='black', tab_location='topleft')]]
window = sg.Window('My window with tabs', default_element_size=(30,1)).Layout(layout)
# event loop to process events and get the values of inputs
while True:
event, values = window.Read()
print(event, values)
if event in (None, 'Exit'):
break
if event == 'Update':
window.FindElement('_table_').Update( row_colors=((8,'white', 'red'), (9,'black')))
window.Close()
I would like for a table to show on tab 2 with existing reservations. Ultimately this will come from a db but for now I have created a pd.DataFrame.
The error is
TclError: Invalid column index
But I have tried strings and lists.
In sg.table you need to include:
headings = header_list
header_list = [str(x) for x in range(len(data[0]))]
tab2_layout = [[sg.Table(values=Data_Table, max_col_width=25,
background_color='lightblue',
auto_size_columns=True,
justification='right',alternating_row_color='blue',
key='_table_', headings = header_list)]
[sg.Button('Update')]]
For more Details See:
https://repl.it/#PySimpleGUI/Table-Element
Related
I am creating an app in which i want display data in tabular format i created a GUI windows that displays the data properly but whenever i recall the same function or any other GUI function my GUI window Gets Resized/Rescaled to a smaller size
def tableGUIP(file):
data = []
header_list = []
df = pd.read_csv(file, sep=',', engine='python', header=None)
data = df.values.tolist() # read everything else into a list of rows
header_list = df.iloc[0].tolist()
data = df[1:].values.tolist()
layout = [
[sg.Table(values=data,
headings=header_list,
display_row_numbers=False,
auto_size_columns=True,
row_height=20,
num_rows=min(20, len(data)))],
[sg.Text('Column', size =(15, 1))],
[sg.Button("Rank"),sg.Button("Live"),sg.Button("2020"),sg.Button("Area"),sg.Button("Density"),sg.Button("Growth"),sg.Button("World %"),sg.Exit()]
]
window = sg.Window('Table', layout, grab_anywhere=False,use_default_focus=True,keep_on_top=True,finalize=True)
event, values = window.read()
while True:
if event in (None, 'Exit'):
sortcol('Exit')
break
# in ('Rank','2022 (Live)', '2020 Population', 'Area', 'Density', 'Growth Rate', 'World %'):
if event == "Rank":
sortcol('Rank')
break
elif event=="Live":
sortcol('2022 (Live)')
break
elif event=="2020":
sortcol('2020 Population')
break
elif event=="Area":
sortcol('Area')
break
elif event=="Density":
sortcol('Density')
break
elif event=="Growth":
sortcol('Growth Rate')
break
elif event=="World %":
sortcol('World %')
break
window.close()
This is the GUI windows after the first occurrence occurs
This is the GUI windows When the first occurrence occurs
please advise my project to the attched picture(error&problem)
1.combo source==>one of column in dataframe: need to fix, please help me
2.last record No(ExNo) in excel ==>should to reflect on the input screen as ExNo
3.int(['Total'])-int(['VAT']) ==>error
import PySimpleGUI as sg
from datetime import datetime
import pandas as pd
# Add some color to the window
sg.theme('DarkTeal9')
coa_file = 'D:\92Python\Acdb\coa.xlsx'
coa_data = pd.read_excel(coa_file, sheet_name="coa", skiprows = 1, index_col=False)
coa_df = pd.DataFrame(coa_data) #.reset_index(drop=True, inplace=True)
coa_df1 =coa_df.iloc[:,[0,1]] <--error
ExNo = 1
#print(coa_df1)
EXCEL_FILE = 'D:\92Python\Acdb\Data_Entry.xlsx'
df = pd.read_excel(EXCEL_FILE)
layout = [
[sg.Text('Please fill out the following fields:')],
[sg.Text('Expense No', size=(15,1), justification= 'left', key='ExNo')], <--error
[sg.Text('Date', size=(15,1)), sg.InputText(key='Date'), sg.CalendarButton("Date", close_when_date_chosen=True, target="Date", location=(0,0), no_titlebar=False)],
[sg.Text('COA', size=(15,1)), sg.InputCombo(coa_df1, key='COA',size=(50,1))],
[sg.Text('Supplier', size=(15,1)), sg.InputText(key='Supplier')],
[sg.Text('Total', size=(15,1)), sg.InputText(key='Total')],
[sg.Text('VAT', size=(15,1)), sg.InputText(key='VAT')],
#[sg.Text('Amount', size=(15,1), justification= 'left', key='Amount')],
[sg.Text('Paid', size=(15,1)),
sg.Checkbox('Cash', key='Cash'),
sg.Checkbox('CreditCard', key='CreditCard'),
sg.Checkbox('Bank', key='Bank'),
sg.Checkbox('Owners', key='Owners')],
[sg.Text('Description', size=(15,1)), sg.InputText(key='Desc')],
[sg.Text('No. of Children', size=(15,1)), sg.Spin([i for i in range(0,16)],
initial_value=0, key='Children')],
[sg.Submit(), sg.Button('Clear'), sg.Exit()]
]
window = sg.Window('Simple data entry form', layout, no_titlebar=False, location=(10,10), size=(800,600), keep_on_top=True)
#window['Date'].bind("<Return>", "_Enter")
def clear_input():
for key in values:
window[key]('')
return None
while True:
event, values = window.read()
if event == sg.WIN_CLOSED or event == 'Exit':
break
if event == 'Clear':
clear_input()
if event == 'Submit':
#amount = float(int(['Total'])-int(['VAT']))
#window['Amount'].Update(amount)
new_record = pd.DataFrame(values, index=[0])
df = pd.concat([df, new_record], ignore_index=True)
df.to_excel(EXCEL_FILE, index=False)
sg.popup('Data saved!')
clear_input()
window.close()
I have created a small form with ipywidgets. The sample code can be run in Jupyter or Google colab.
Each time the form is filled and the button is clicked a row gets added to a dataframe. Subsequently the dataframe gets displayed.
My problem is that the output displays the new updated dataframe on top of the old one. What I want is that the new display output overwrites the old one. See image description here.
import ipywidgets as widgets
from ipywidgets import HBox, Label
from ipywidgets import Layout, Button, Box, FloatText, Textarea, Dropdown, Label, IntSlider
import time
import pandas as pd
#Create DF
df = df = pd.DataFrame(columns = ['Dropdown_column', 'Float_column'])
df
# Layout
form_item_layout = Layout(
display='flex',
flex_flow='row',
justify_content='space-between',
)
button_item_layout = Layout(
display='flex',
flex_flow='row',
justify_content='center',
padding = '5%'
)
# Dropdown item
drop_down_input = 'Dropdown_input_1'
drop_down = widgets.Dropdown(options=[('Dropdown_input_1', 'Dropdown_input_1'), ('Dropdown_input_2','Dropdown_input_2'), ('Dropdown_input_3', 'Dropdown_input_3')])
def dropdown_handler(change):
global drop_down_input
print('\r','Dropdown: ' + str(change.new),end='')
drop_down_input = change.new
drop_down.observe(dropdown_handler, names='value')
# FloatText item
float_input = 0
FloatText = widgets.FloatText()
def IntText_handler(change):
global float_input
print('\r','Float text:' + str(change.new),end='')
float_input = change.new
FloatText.observe(IntText_handler, names='value')
# Button
button = widgets.Button(description='Add row to dataframe')
out = widgets.Output()
def on_button_clicked(b):
global df
button.description = 'Row added'
time.sleep(1)
with out:
new_row = {'Dropdown_column': drop_down_input, 'Float_column': float_input}
df = df.append(new_row, ignore_index=True)
button.description = 'Add row to dataframe'
display(df)
button.on_click(on_button_clicked)
# Form items
form_items = [
Box([Label(value='Dropdown'),
drop_down], layout=form_item_layout),
Box([Label(value='FloatText'),
FloatText], layout=form_item_layout),
Box([Label(value=''), button],
layout=button_item_layout),
]
form = Box(form_items, layout=Layout(
display='flex',
flex_flow='column',
border='solid 1px',
align_items='stretch',
width='30%',
padding = '1%'
))
display(form)
display(out)
I have tried using the print() function in combination with '/r' and changing #button part of my code.
Change:
display(df)
to
print('\r',str(df), end='')
or
print(str(df), end='\r')
But this does not work either.
Does somebody have any idea what to do?
\r works only for single line of normal text but df is not displayed as normal text (and it is not single line) but as HTML code.
You have to use out.clear_output() to remove previous content.
with out:
new_row = {'Dropdown_column': drop_down_input, 'Float_column': float_input}
df = df.append(new_row, ignore_index=True)
button.description = 'Add row to dataframe'
out.clear_output() # <---
display(df)
You can see more about out.clear_output() in documentation:
Output widgets: leveraging Jupyter’s display system
i want to delete dataframe unnamed in red arrow , and the i want to add some text when i click submit i have index from 1 not in 0 like this
Data_entry.xlsx
can you give me solution about this problem ?
in above my code in python 3
import PySimpleGUI as sg
import pandas as pd
# importing openpyxl module
import openpyxl
# Give the location of the file
path = "C:\\Users\\Admin\\Desktop\\WEB\\PYTHON_PYSIMPLEGUI\\Data_Entry.xlsx"
sg.theme('DarkGreen7')
EXCEL_FILE = 'Data_Entry.xlsx'
df = pd.read_excel(EXCEL_FILE)
my_img = sg.Image(r'C:\Users\master\Desktop\WEB\PYTHON_PYSIMPLEGUI\logo.png')
"""
# Template Taskbar
menu_def = [['File', ['Open', 'Save', 'Exit',]],
['Edit', ['Paste', ['Special', 'Normal',], 'Undo'],],
['Help', 'About...'],]
"""
menu_def = [['File', ['Exit']],['Help', 'About...'],]
layout = [
[sg.Menu(menu_def)],
[sg.Column([[my_img]], justification='center')],
[sg.Text('Simacan ( SIstem Monitoring And Controling Absen Nilai')],
[sg.Text('Nama', size=(15,1)), sg.InputText(key='Nama')],
[sg.Text('Kehadiran', size=(15,1)), sg.Combo(['Hadir', 'Sakit', 'Tidak Masuk'], key='Keterangan')],
[sg.Submit(), sg.Exit()]
]
window =sg.Window('Aplikasi Simacan versi 1.2', layout,size=(800, 600), font='Courier 12')
while True:
event, values = window.read()
if event == sg.WIN_CLOSED or event == 'Exit':
break
if event == 'Submit':
df = df.append(values, ignore_index=True)
df.to_excel(EXCEL_FILE, index=True)
sg.popup('Data saved !')
print(event, values)
window.close()
There's are some issues here.
Create a blank excel file to store your data.
Open excel file as a dataframe, option index_col set the index column or you may get Unnamed: 0 column as index in your dataframe.
df = pd.read_excel(EXCEL_FILE, index_col=[0])
There's one extra item 0 in dictionary values, it is the key of sg.Menu, should remove it before you append the values to your dataframe by
del values[0]
You can re-index your dataframe by
df.index = np.arange(1, len(df)+1)
You can save dataframe to your excel file only before end of you script, of course, write each new record to your excel file is still fine.
Sorry for the potentially confusing phrasing of my question. Essentially, I am trying to make it so that every time I press the 'Add Data' command button there is only one DataFrame displayed. The one that should be displayed is the DF that is modified when the button is pressed. Currently, though, it will append the output with the recently modified DF, on top of the older versions that were created from earlier clicks of the button.
I'm using this code as part of a larger program for performing Monte Carlo simulations and back testing. My goal for these widgets is to input all the option positions I take on certain assets. That way, I can have a consolidated DF of my positions to speed up my analysis in later sections of this program and be available for other programs. The 'Add Data' button will input the values of the other widgets into a dictionary and concat that dictionary with the existing portfolio DF (which is saved in a CSV file).
I believe my problem is caused by me not properly utilizing the ipywidget Output() function, but have not been able to find a workable solution to my problem.
Also, I am writing in a Jupyter Notebook.
import pandas as pd
import datetime
from datetime import *
import ipywidgets as widgets
from ipywidgets import *
############################################## The following section is usually in a seperate cell so I can
df = { # refresh my portfolio every day, but still add to the DF throughout the day
'Datetime' : [],
'Expire' : [],
'Type' : [],
'Quantity' : [],
'Strike' : [],
'Spot' : []
}
df = pd.DataFrame(df)
df.to_csv("portfolio.csv", index=False)
##############################################
Type = widgets.Dropdown(
options = ['Call', 'Put'],
value = 'Call',
description= 'Select Binary Type',
disabled=False,
layout={'width': 'max-content'},
style={'description_width': 'max-content'}
)
Quantity = widgets.BoundedIntText(value=1,
min=1,
max=10,
step=1,
description='Quantity:',
disabled=False,
layout={'width': 'max-content'},
style={'description_width': 'max-content'}
)
Strike = widgets.BoundedIntText(
min=1500,
max=3500,
step=1,
description='Strike:',
disabled=False,
layout={'width': 'max-content'},
style={'description_width': 'max-content'}
)
Spot = widgets.BoundedIntText(
min=1500,
max=3500,
step=1,
description='Spot:',
disabled=False,
layout={'width': 'max-content'},
style={'description_width': 'max-content'}
)
Add = widgets.Button(description="Add Data")
out = Output()
def add_on_click(b):
dt = datetime.now()
option = Type.value
quant = Quantity.value
strike = Strike.value
spot = Spot.value
df = pd.read_csv("portfolio.csv")
now = datetime.now()
add = {
'Datetime' : dt,
'Expire' : datetime(now.year, now.month, now.day, 14, 15,0,1),
'Type' : option,
'Quantity': quant,
'Strike' : strike,
'Spot': spot
}
add = pd.DataFrame(add, index=[0])
df = pd.concat([df, add],sort=True) #ignore_index=True)
df.to_csv("portfolio.csv", index=False)
display(df, out)
Add.on_click(add_on_click)
items = [Type, Quantity, Strike, Spot, Add]
box_layout = Layout(display='flex',
flex_flow='row',
align_items='stretch',
width='100%')
box_auto = Box(children=items, layout=box_layout)
display_widgets = VBox([box_auto])
display_widgets
Change your last lines of add_on_click to:
out.clear_output()
with out:
display(df)
You can try
def add_on_click(b):
with out:
clear_output()
display(df)
#rest of the code goes here