0

I am trying to show data from a MongoDB database in a windows forms table created using the PySimpleGui library. The following code has been adapted from the pySimpleGUI demo program demo_test_element.py.

The data passed to the code which successfully displays the data in the table looks like this:
[["Dog", "Pack"],["Cattle","Herd"]]

In the second example, the data is retrieved into a cursor and then put into a list. On displaying the table, I get a TypeError: can only concatenate list (not "dict") to list. When I print the type of my list, it is described as a <class 'list'>, not a dictionary. The format of the data in the list is different to that in the example program. It looks like this:
[{'_id': ObjectId('5f511b8a5d174ea26fbe2c64'), 'name': 'Dog', 'collective': 'Pack'}, {'_id': ObjectId('5f511b8a5d174ea26fbe2c65'), 'name': 'Cattle', 'collective': 'Herd'}]

So, I thought that I would try and change the list to format it in the same way as the version which is successful. I can achieve:
["['Dog','Pack']", "['Cattle','Herd']"] If the double quotes weren't there, then it would follow the successful pattern. On trying to display the data in the table, the error is TypeError: can only concatenate list (not "str") to list

I'm new to Python etc. and I may be going about this the wrong way. I prefer pySimpleGUI to Tkinter because I find it more straightforward, but I'll be happy to accept advice to use a different GUI library. I'm used to working with RDBMS (mainly Oracle) and I chose MongoDB as a challenge, again, I'm not completely attached to it.

I've tried to make the code as succinct as possible for this question.

from pymongo import MongoClient
import PySimpleGUI as sg

# Display the data in a table
def windowStuff(data):
    headings = ["Animal","Collective"]
    layout = [[sg.Table(values=data[0:][:], headings=headings, max_col_width=25, display_row_numbers=True, num_rows=4, alternating_row_color='red',
                        key='-TABLE-', row_height=35)]]
    window = sg.Window('The Animals', layout,)
    while True:
        event, values = window.read()
        if event == sg.WIN_CLOSED:
            break
    window.close()

sg.theme('Black')

data = [["Dog", "Pack"],["Cattle","Herd"]] 
try:
    windowStuff(data)
    # This works
except Exception:
    pass

# Insert and return data into Mongo Database
client = MongoClient('mongodb://localhost:27017/')
db = client.testdb
db.colCreatures.drop()
docCreatures = [ {'name': 'Dog', 'collective': 'Pack'}, {'name': 'Cattle', 'collective': 'Herd'}]
db.colCreatures.insert_many(docCreatures)
curCreatures = db.colCreatures.find()

#Call the function to display the table with data, using a LIST
listCreatures = list(curCreatures)
try:
    windowStuff(listCreatures)
except Exception:
    # Error is File "..... \PySimpleGUI.py", line 11646, in PackFormIntoFrame
    # value = [i + element.StartingRowNumber] + value
    # TypeError: can only concatenate list (not "dict") to list
    pass
    
#Call the function to display the table after the list has been manipulated
data =[]
for creature in listCreatures:
    strCreature = ('[{0} {1}'.format(creature['name'] +',', creature['collective'] + ']'))
    strCreature = strCreature.replace('[', '[' + "'")
    strCreature = strCreature.replace(']' , "'" + ']')
    strCreature = strCreature.replace(', ', "'" + ',' + "'")
    data.append(strCreature)
try:
    windowStuff(data)
except Exception:
    # Error is File "....\PySimpleGUI.py", line 11646, in PackFormIntoFrame
    # value = [i + element.StartingRowNumber] + value
    # TypeError: can only concatenate list (not "str") to list
    pass

1 Answers1

1

Your idea to iterate over the creatures and build a new list was right. Just don't build that strange string.

data = []
for creature in listCreatures:
    data.append([creature["name"], creature["collective"]])
Wups
  • 2,489
  • 1
  • 6
  • 17
  • This worked perfectly. As a new user, my votes aren't shown, so this is the only way I can say the question has been fully answered. – Julie Stenning Sep 03 '20 at 19:48