I'm unable to use PySimpleGUI.Table because of my inability to create list of lists, please see my code:
def is_compiled(file):
full_path = main_path + 'models_data/'+ file[:-3]
return isdir(full_path) #Returns bool True of False
models_src = [f for f in listdir(model_src_path) if isfile(join(model_src_path, f))]
is_compiled_list = [str(is_compiled(f)) for f in models_src]
table_list = [models_src,is_compiled_list]
print(table_list)
printing my lists shows:
[['CNN_v1.py', 'test.py'], ['False', 'True']]
and type is <class 'list'>
But when I try to put this list into sg.Table:
table_headings = ['name','iscompiled?']
layout = [[sg.Table(table_list,headings=table_headings]]
window = sg.Window("Demo", layout, margins=(500, 300))
while True:
event, values = window.read()
I'm getting this error message:
list indices must be integers or slices, not Text
I know this is probably a very simple solution but I was trying to find it for hours and I couldn't. Thanks for help!
EDIT:Typo
This exception maybe caused by the code you not show here.
For example, in following code, [sg.Table(table_list, headings=table_headings)] come with [sg.Text('Hellow World')] at next line.
import PySimpleGUI as sg
table_list = [['CNN_v1.py', 'test.py'], ['False', 'True']]
table_headings = ['name','iscompiled?']
layout = [
[sg.Table(table_list, headings=table_headings)]
[sg.Text('Hellow World')]
]
sg.Window('Title', layout).read(close=True)
It is something like following code, sg.Text('Hellow World') will be thought as the index of list1, that's why you got exception TypeError: list indices must be integers or slices, not Text
list1 = [sg.Table(table_list, headings=table_headings)]
layout = [
list1[sg.Text('Hellow World')]
]
It should be with a comma between any two items in a list, like
import PySimpleGUI as sg
table_list = [['CNN_v1.py', 'test.py'], ['False', 'True']]
table_headings = ['name','iscompiled?']
layout = [
[sg.Table(table_list, headings=table_headings)], # A comma missed between any two items
[sg.Text('Hellow World')]
]
sg.Window('Title', layout).read(close=True)
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 months ago.
Improve this question
I am trying to write a script which writes path data to an excel file. The function is working, I just want to create an simple GUI using PySimpleGUI where the user can give a path. The path variable is used in the function. Now I have the error:
str_path = int(values['-INF1-'])
TypeError: tuple indices must be integers or slices, not str
This is my code:
import PySimpleGUI as sg
import ctypes
import platform
import os
import pandas as pd
from pathlib import Path
from docxtpl import DocxTemplate
def make_dpi_aware():
if int(platform.release()) >= 8:
ctypes.windll.shcore.SetProcessDpiAwareness(True)
make_dpi_aware()
sg.LOOK_AND_FEEL_TABLE['MyCreatedTheme'] = {'BACKGROUND': '#DCD7C9',
'TEXT': '#000000',
'INPUT': '#E9DAC1',
'TEXT_INPUT': '#000000',
'SCROLL': '#99CC99',
'BUTTON': ('#000000', '#54BAB9'),
'PROGRESS': ('#D1826B', '#CC8019'),
'BORDER': 1, 'SLIDER_DEPTH': 0,
'PROGRESS_DEPTH': 0, }
sg.theme('MyCreatedTheme')
layout = [
[sg.T('Voer een pad in: '), sg.Input(key='-INF1-')],
[sg.FolderBrowse('Opslaan in', key="-IN-")],
[sg.Button("Open excel bestand"), sg.Exit()]
]
window = sg.Window('Pad naar excel generator', layout, element_justification="right", modal=True, font='Any 12')
values = window.read()
str_path = int(values['-INF1-'])
path = Path(str_path)
def list_files(path):
files = []
for r, d, f in os.walk(path):
for file in f:
files.append(os.path.join(r, file))
df = pd.DataFrame(files, columns = ['path'])
df['filename'] = df['path'].str.split('\\').str[-1]
df['path'] = df['path'].str.replace(r'\\[^\\]*$', '')
df.to_excel('files.xlsx', index = False)
return df
list_files(path)
while True:
event = window.read()
if event == sg.WIN_CLOSED or event == "Exit":
break
if event == "Open excel bestand":
list_files(values['-INF1-'])
output_path = Path(values["-IN-"]) / f"filestopath.docx"
doc = DocxTemplate(output_path)
doc.save(output_path)
os.startfile(output_path)
window.close()
Can someone explain to me what is going wrong? Any help would be appreciated!
This is how PySimpleGUI docs tell us to read event and values from Window:
event, values = window.read()
Instead you do (in different places):
values = window.read()
...
event = window.read()
In your code values/event is assigned a tuple of (<EVENT>, <VALUES>), which you try to process as if it were PySimpleGUI object.
If you need only one part of the tuple, do this instead:
_, values = window.read()
...
event, _ = window.read()
I want to make a widget window, but the Bottom and Text part aren't working properly and it keps getting sintax errors at the same part:
import PySimpleGUI as sg
layout = [
[sg.Text("Hello from PySimpleGUI")],
[sg.Button("Close")]
window = sg.Window("Demo, layout")
]
while true:
event, values = window.read()
if event == "Close" or event == sg.WIN_CLOSED:
break
window.close()
it says I forgot a comma, but the references I checked for this code didn't use one, and I tried changing the elements or just putting the comma, but it didn't work either.
ERROR message:
line 5
[sg.Buttom("OK")]
^^^^^^^^^^^^^^^^^
SyntaxError: invalid syntax. Perhaps you forgot a comma?
This:
layout = [
[sg.Text("Hello from PySimpleGUI")],
[sg.Button("Close")]
window = sg.Window("Demo, layout")
]
isn't a valid list, because you can't include an assignment like that, and there should be a comma after the second element. Also, the call to sg.Window() doesn't look right, because presumably you meant to pass layout as the second argument to define the layout of a window named "Demo".
Try doing this:
layout = [
[sg.Text("Hello from PySimpleGUI")],
[sg.Button("Close")]
]
window = sg.Window("Demo", layout)
If you need to access an object in a list, you either need to create it before hand, like this:
window = sg.Window("Demo")
layout = [
[sg.Text("Hello from PySimpleGUI")],
[sg.Button("Close")],
[window]
]
Or do something ugly that relies on knowing the internal structure, like this:
layout = [
[sg.Text("Hello from PySimpleGUI")],
[sg.Button("Close")],
[sg.Window("Demo")]
]
window = layout[2][0]
I have the following development that I am working on with the Tkinter, ElementTree and Pandas modules in Python:
from tkinter import *
import xml.etree.ElementTree as ET
import pandas as pd
file_xml = ET.parse('example1.xml')
rootXML = file_xml.getroot()
root = Tk()
root.title("Graphical Analysis of Signals of a XML")
root.geometry("1024x820")
root.pack_propagate(False)
root.config(bd=15)
# Functions to open xml file
def open_file():
try:
global temxml, xml_Name
xml_Name = str(easygui.fileopenbox(title='Select xml file', default='*.xml'))
if str(os.path.abspath(xml_Name)) != os.path.join(os.path.abspath(os.getcwd()), os.path.basename(xml_Name)):
menssage.set("Opened xml file: ", xml_Name)
child_4_separate(os.path.basename(str(tempxml)))
else:
child_4_separate(os.path.basename(str(xml_Name)))
except FileNotFoundError:
print('XML file was not loaded.')
# Function to display buttons and choose the Child_4 to be plotted
def child_4_separate(xml_Name):
print("File: ", xml_Name)
file_xml = ET.parse(xml_Name)
data_xml = [
{
"Name": signal.attrib["Name"],
"Id": signal.attrib["Id"],
} for signal in file_xml.findall(".//Child_4")
]
# print(data_xml)
for i in data_xml:
print(i)
id_tc = i.get('Id')
dict_tc = str(i.values()).replace('dict_values([\'', '')
name_tc = dict_tc.replace('\'])', '')
Button(root, text=f"TC> {name_tc}", command=transfor_data_atri_child_4(xml_Name, id_tc)).pack()
# Function to transform xml file to DataFrame
def transfor_data_atri_child_4(rootXML, id_tc):
print("File: ", rootXML)
print("id_tc: ", id_tc)
What I'm trying to do is that every time I click a button, the child_4_separate (xml_Name) function it goes to the transform_data_atri_child_4 (rootXML, id_tc) function with a single id number and does not fetch me everything like it does in the last print that I show below, this is to be able to manipulate them separately.
I share the XML file in this link example1.xml because of how long it is.
I don't know if I need another for inside or what I need, because when trying another for inside the already existing for in the child_4_separate (xml_Name) function it is repeating it many times and it is not what I want, but simply that redirect to the following function with the two parameters that I am indicating, but separately; help me please! Beforehand, thank you very much!
Just for possible searches or related problems later, I share the solution:
Take the value command = lambda x = xml_Name, y = id_tc: transform_data_atri_child_4 (x, y) in the button attributes and it worked, my function is like this:
# Function to display buttons and choose the Child_4 to be plotted
def child_4_separate(xml_Name):
# print("File: ", xml_Name)
file_xml = ET.parse(xml_Name)
data_xml = [
{
"Name": signal.attrib["Name"],
"Id": signal.attrib["Id"],
} for signal in file_xml.findall(".//Child_4")
]
# print(data_xml)
for i in data_xml:
id_tc = i.get('Id')
dict_tc = str(i.values()).replace('dict_values([\'', '')
name_tc = dict_tc.replace('\'])', '')
Button(root, text=f"TC> {name_tc}", command=lambda x=xml_Name, y=id_tc: transfor_data_atri_child_4(x, y)).pack()
I appreciate the solution to #Sujay. Happy codification everyone!!
I'm trying to generate multiple ComboBoxes with values from a "config.ini" file, the config.ini file data is:
priority1 = Normal:farty-blobble-fx.wav:2
priority8 = Reclamacao:buzzy-blop.wav:3
priority3 = Critico:farty-blobble-fx.wav:5
priority2 = Urgente:echo-blip-thing.wav:4
and the goal is turning the sound files names to the select values in the comboboxes.
My code to generate the comboboxes is:
content_data = []
for name, value in parser.items(section_name):
if name=="name":
self.note.add(self.tab2, text = value)
else:
data_prior = value.split(":")
self.PRIOR_LABEL = Label(self.tab2, text=data_prior[0])
self.PRIOR_LABEL.grid(row=data_prior[2],column=0,pady=(10, 2),padx=(40,0))
self.PRIOR_SOUNDS = None
self.PRIOR_SOUNDS = None
self.box_value = StringVar()
self.PRIOR_SOUNDS = Combobox(self.tab2, textvariable=self.box_value,state='readonly',width=35)
self.PRIOR_SOUNDS['values'] = getSoundsName()
self.PRIOR_SOUNDS.current(int(getSoundsName().index(data_prior[1])))
self.PRIOR_SOUNDS.grid(row=data_prior[2],column=1,pady=(10, 2),padx=(30,0))
self.PLAY = Button(self.tab2)
self.PLAY["width"] = 5
self.PLAY["text"] = "Play"
self.PLAY["command"] = lambda:playSound(self.PRIOR_SOUNDS.get())
self.PLAY.grid(row=data_prior[2], column=3,pady=(10,2),padx=(5,0))
And i was unable to show the current values of the "config.ini" file in the comboboxes.
Thank you in advance.
The problem is that you're creating more than one combobox, yet you keep overwriting the variables in each iteration of the loop. At the end of the loop, self.PRIOR_SOUNDS will always point to the last combobox that you created. The same is true for self.box_value, self.PLAY, etc.
The simplest solution is to use an array or dictionary to store all of your variables. A dictionary lets you reference each widget or variable by name; using a list lets you reference them by their ordinal position.
A solution using a dictionary would look something like this:
self.combo_var = {}
self.combo = {}
for name, value in parser.items(section_name):
...
self.combo_var[name] = StringVar()
self.combo[name] = Combobox(..., textvariable = self.combo_var[name])
...
In my source code for a project I am running I have a process that produces a list of strings. I am trying to put this list into a Tkinter listbox for easy sorting, but when I do the list is all inserted into one line and I can't find a way to separate the individual words into a different line on the listbox. Any ideas I am open to anything. Below I have attach an example of what I am trying to do:
from Tkinter import *
app = Tk()
app.geomtery("500x700")
app.title("ListBox")
names = ["Greg", "Earl", "Harry", "Bob"]
box = Listbox(app)
# Right here is where I am stuck
box.insert(END, names)
box.pack()
app.mainloop()
very esay in python, no ?:
just add the item and not the list
# Right here is where I am stuck
for i in names:
box.insert(END, i)
and
app.geometry("500x700")
This is how you could do it:
from Tkinter import *
app = Tk()
app.geometry("500x700")
app.title("ListBox")
names = ["Greg", "Earl", "Harry", "Bob"]
box = Listbox(app)
# Right here is where I am stuck
for name in names:
box.insert(END, name)
box.pack()
app.mainloop()