1. Windows 10
2. Python 3.6
3.
4. В моей программе существует цикл, который с помощью перебора данных таблицы PySimpleGUI находит выбранную кликом мыши строку:
Данный цикл хорошо служит для удаления выбранной строки из таблицы(таблица изначально заполнена с помощью DataFrame библиотеки pandas):
однако при использовании его в функции кнопки изменения данных выдаёт ошибку по этому же самому циклу:
Ошибка:
File "C:\Users\Mu3aHTpoTT\Desktop\main.py", line 117, in <module>
for num in values['-TABLE-']:
KeyError: '-TABLE-'
Если присвоить переменной row_index какой-нибудь индекс собственноручно в коде, то всё работает хорошо: он изменяет данные строки по индексу, однако моя цель - чтобы индекс был присвоен выбором строки по клику мыши, что приводит к использованию того самого цикла, создающего ошибку. Мой полный код:
Используя дебаггер, я пришёл к выводу, что values заполняется введёнными для изменения данными так же, как заполняется при добавлении новой строки. Функция добавления строки:
Однако после заполнения values данными, я уже не могу обратиться к values['-TABLE-'], так как выдаёт ошибку.
Для заполнения таблицы и воспроизведения проблемы прошу использовать таблицу в csv файле, прикреплённым ниже, следующим путём:
При запуске кода выбрать csv файл с помощью кнопки 'File browse'
Нажать кнопку 'Go'
2. Python 3.6
3.
import PySimpleGUI as sg
import numpy as np
import pandas as pd
import datetime
import numpy as np
import pandas as pd
import datetime
Python:
for num in values['-TABLE-']:
row_index = num
Python:
elif event == '-DELETE-':
row_index = 0
for num in values['-TABLE-']:
row_index = num
df = df.drop([row_index],axis=0)
df = df.reset_index(drop=True)
df1 = np.array(df).tolist()
window1['-TABLE-'].update(df1)
Python:
elif event == '1-ADD-':
row_index = 0
for num in values['-TABLE-']:
row_index = num
fs = int(values['1-IN-5'])-int(values['1-IN-6'])*int(values['1-IN-5'])//100
new_line={'Name':values['1-IN-1'],
'DateOfBirth':values['1-IN-2'],
'PhoneNumber':values['1-IN-3'],
'Position':values['1-IN-4'],
'Salary':values['1-IN-5'],
'RetentionPercentage':values['1-IN-6'],
'FinalSalary':fs}
df1 = df.iloc[row_index]
df = df.replace(df1, new_line)
df1 = np.array(df).tolist()
window1['-TABLE-'].update(df1)
window3.close()
File "C:\Users\Mu3aHTpoTT\Desktop\main.py", line 117, in <module>
for num in values['-TABLE-']:
KeyError: '-TABLE-'
Если присвоить переменной row_index какой-нибудь индекс собственноручно в коде, то всё работает хорошо: он изменяет данные строки по индексу, однако моя цель - чтобы индекс был присвоен выбором строки по клику мыши, что приводит к использованию того самого цикла, создающего ошибку. Мой полный код:
Python:
import PySimpleGUI as sg
import numpy as np
import pandas as pd
import datetime
df = [[' ',' ',' ',' ',' ',' ',' ',' ']]
df1 = np.array(df).tolist()
headings = ['Name','Date of birth','Phone number','Position','Salary','Retention percentage','Final Salary','Employment date']
sg.theme('darkgrey8')
def make_win1():
layout = [
[
sg.Button('Add employee',size=(20,1),key='-ADD-',button_color='darkgreen'),
sg.Button('Remove employee',size=(20,1),key='-DELETE-',button_color='darkred'),
sg.Button('Change employee data',size=(25,1),key='-CHANGE-',button_color='darkorange'),
sg.Text(' '),
sg.Input(key='-FILEBROWSE-'),
sg.FileBrowse('File browse',button_color='darkorange',file_types=(("csv Files", "*.csv"),)),
sg.Button('Go', button_color='darkgreen'),
],
[sg.Table(values=df1,
headings=headings,
max_col_width=35,
display_row_numbers=True,
justification='center',
alternating_row_color='grey',
key='-TABLE-',
size=(150,20),
enable_events=True,
row_height=30,
)],
[sg.Button('Save',size=(20,1), button_color='darkgreen',key='-SAVE-')]
]
return sg.Window('Employee accounting', layout,finalize=True)
def make_win2():
l_col = sg.Column(
[
[sg.Text('Name'),sg.Input(key='0-IN-1', enable_events=True)],
[sg.Text('Date of birth'),sg.Input(key='0-IN-2', enable_events=True)],
[sg.Text('Phone number'),sg.Input(key='0-IN-3', enable_events=True)],
[sg.Text('Position'),sg.Input(key='0-IN-4', enable_events=True)],
[sg.Text('Salary'),sg.Input(key='0-IN-5', enable_events=True)],
[sg.Text('Retention percentage'),sg.Input(key='0-IN-6', enable_events=True)],
[sg.Button('OK',key='0-ADD-',button_color='darkgreen')]
],
element_justification="right"
)
layout = [
[l_col]
]
return sg.Window('Add employee', layout, finalize=True)
def make_win3():
l_col = sg.Column(
[
[sg.Text('Name'),sg.Input(key='1-IN-1', enable_events=True)],
[sg.Text('Date of birth'),sg.Input(key='1-IN-2', enable_events=True)],
[sg.Text('Phone number'),sg.Input(key='1-IN-3', enable_events=True)],
[sg.Text('Position'),sg.Input(key='1-IN-4', enable_events=True)],
[sg.Text('Salary'),sg.Input(key='1-IN-5', enable_events=True)],
[sg.Text('Retention percentage'),sg.Input(key='1-IN-6', enable_events=True)],
[sg.Button('OK',key='1-ADD-',button_color='darkgreen')]
],
element_justification="right"
)
layout = [
[l_col]
]
return sg.Window('Change employee data', layout, finalize=True)
window1, window2, window3 = make_win1(), None, None
while True:
#try:
window, event, values = sg.read_all_windows()
if event == sg.WIN_CLOSED or event == 'Exit':
window.close()
if window == window2:
window2 = None
elif window == window3:
window3 = None
elif window == window1:
break
elif event == 'Go':
data = values['-FILEBROWSE-']
df = pd.read_csv(data,delimiter=',')
df1 = np.array(df).tolist()
window1['-TABLE-'].update(df1)
elif event == '-ADD-':
window2 = make_win2()
elif event == '0-ADD-':
now = datetime.datetime.now()
fs = int(values['0-IN-5'])-int(values['0-IN-6'])*int(values['0-IN-5'])//100
new_line={'Name':values['0-IN-1'],
'DateOfBirth':values['0-IN-2'],
'PhoneNumber':values['0-IN-3'],
'Position':values['0-IN-4'],
'Salary':values['0-IN-5'],
'RetentionPercentage':values['0-IN-6'],
'FinalSalary':fs,
'EmploymentDate':now.date()}
df = df.append(new_line, ignore_index=True)
df1 = np.array(df).tolist()
window1['-TABLE-'].update(df1)
window2.close()
elif event == '-DELETE-':
row_index = 0
for num in values['-TABLE-']:
row_index = num
df = df.drop([row_index],axis=0)
df = df.reset_index(drop=True)
df1 = np.array(df).tolist()
window1['-TABLE-'].update(df1)
elif event == '-CHANGE-':
window3 = make_win3()
elif event == '1-ADD-':
row_index = 0
for num in values['-TABLE-']:
row_index = num
fs = int(values['1-IN-5'])-int(values['1-IN-6'])*int(values['1-IN-5'])//100
new_line={'Name':values['1-IN-1'],
'DateOfBirth':values['1-IN-2'],
'PhoneNumber':values['1-IN-3'],
'Position':values['1-IN-4'],
'Salary':values['1-IN-5'],
'RetentionPercentage':values['1-IN-6'],
'FinalSalary':fs}
df1 = df.iloc[row_index]
df = df.replace(df1, new_line)
df1 = np.array(df).tolist()
window1['-TABLE-'].update(df1)
window3.close()
elif event == '-SAVE-':
df.to_csv(data,sep=',',header=True,index=None)
#except Exception:
# print('Error')
window.close()
Python:
elif event == '0-ADD-':
now = datetime.datetime.now()
fs = int(values['0-IN-5'])-int(values['0-IN-6'])*int(values['0-IN-5'])//100
new_line={'Name':values['0-IN-1'],
'DateOfBirth':values['0-IN-2'],
'PhoneNumber':values['0-IN-3'],
'Position':values['0-IN-4'],
'Salary':values['0-IN-5'],
'RetentionPercentage':values['0-IN-6'],
'FinalSalary':fs,
'EmploymentDate':now.date()}
df = df.append(new_line, ignore_index=True)
df1 = np.array(df).tolist()
window1['-TABLE-'].update(df1)
window2.close()
Для заполнения таблицы и воспроизведения проблемы прошу использовать таблицу в csv файле, прикреплённым ниже, следующим путём:
При запуске кода выбрать csv файл с помощью кнопки 'File browse'
Нажать кнопку 'Go'