0

First and foremost - a huge shoutout to @Bryan Oakley for helping with a great answer here: [Creating a table look-a-like Tkinter that got me started on solving what I wanted to do in the first place.

Goal: Create a simplistic "character sheet" for my rogue-like game. (super, simplistic text-based game), using Grid Geometry in Tkinter for my UI.

Process: I wanted to learn how to create the the grid like a table and place the stats in each slot (right now I'm just using the place-holder string formatting for ease of reference from Bryan Oakley's earlier answer.)

Problem: I tried to modify lines 8, 29, and 30 to include "columnspan" as an argument. Columnspan is normally an argument that works in a number of widgets to let an item occupy more "slots".

The original code did not have 6 in line 8, columnspan in line 29, and [columnspan] in line 30.

Some things I have tried:

  1. I tried commenting-out the for column in range bit in line 25 to remove the weight=1 component of the table. This didn't make any significant impression (actually the code works in its original condition without this at all.)

  2. I tried changing the order of the columnspan, value section in line 29 as I thought maybe putting columnspan after the value was causing the problem (it did in fact cause a different problem altogether.) Which is why I now have columnspan before the value.

  3. I tried creating a new line within the set method to add columnspan as a configuration to widget.

# begin tkinter sample unit menu
import tkinter as tk

class ExampleApp(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)
        t = SimpleTable(self, 4, 6)
        t.pack(side="top", fill="x")
        t.set(0, 0, 6, "Hello, world")

class SimpleTable(tk.Frame):
    def __init__(self, parent, rows=4, columns=6):
        # use black background so it "peeks through" to
        # form grid lines
        tk.Frame.__init__(self, parent, background="black")
        self._widgets = []
        for row in range(rows):
            current_row = []
            for column in range(columns):
                label = tk.Label(self, text="%s/%s" % (row, column),
                                 borderwidth=0, width=10)
                label.grid(row=row, column=column, sticky="nsew", padx=1, pady=1)
                current_row.append(label)
            self._widgets.append(current_row)

        for column in range(columns):
            self.grid_columnconfigure(column, weight=1)


    def set(self, row, column, columnspan, value):
        widget = self._widgets[row][column][columnspan]
        widget.configure(text=value)

if __name__ == "__main__":
    app = ExampleApp()
    app.mainloop()

Expectation: I expected the output to allow the columnspan argument and thus make the entire first column be a single block that would say "Hello, world" across the top.

Result: I receive the following error:

Traceback (most recent call last):

  File "tkintersampleunitmenu.py", line 35, in <module>
    app = ExampleApp()

  File "tkintersampleunitmenu.py", line 8, in __init__
    t.set(0, 0, 6, "Hello, world")

  File "tkintersampleunitmenu.py", line 31, in set
    widget = self._widgets[row][column][columnspan]
  File "/Users/#/anaconda3/lib/python3.6/tkinter/__init__.py", line 1486, in cget

return self.tk.call(self._w, 'cget', '-' + key)

***TypeError: must be str, not int***

What I grasp (or maybe am failing to grasp) is that python is expecting columnspan to be a string? But why? Why wouldn't it look for an integer like with row/column?

martineau
  • 119,623
  • 25
  • 170
  • 301

1 Answers1

0

When you do widget[x], tkinter treats it like widget.cget(x). You are passing in an integer, and an integer is not a proper argument for cget which expects the name of a widget option (background, borderwidth, etc).

Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
  • Okay - thank you, that does help clarify what the error was attempting to beat into my brain. But, how did you get it to accept the integer arguments in the previous arguments that you wrote? I.e. 0, 0, – C. Michael Oct 13 '19 at 13:58
  • @C.Michael: the first and second numbers ("0, 0,") are the row and column, and I use them as an index into a list of lists. You're doing the same and it works just fine. The difference is that you're using a third integer and you're using it incorrectly. – Bryan Oakley Oct 13 '19 at 14:08
  • Okay thank you. So, apparently I'm working in the wrong place is what I'm gathering from this. Back to tinkering. Thank you so much for the clarification! – C. Michael Oct 13 '19 at 15:14