0

I am pretty new to Python as well as coding in general.

I've got 42 Labels (Strings) stored in a list. My aim is to: for each of the 42 labels, create a Tkinter Label displaying the String and a Dropdown List (Tkinter Optionmenu).

Two problems occur:

  • I get an index error for the list of variables (for the optionmenus), here is the output of my Console:

    varDd[i] = StringVar(root) IndexError: list assignment index out of range

  • The Canvas is Scrollable as I intended, but the content doesn't scroll with it

My complete Code: https://codepaste.net/6jkuza

The essential part:

def createDdList():    
    del labelsDd[:]
    del listsDd[:]
        if len(labels) > 1:
            varDd = [len(labels)]
            for i,label in enumerate(labels):
#               Erstelle Labels mit den Markerlabels im scrollbaren Canvas
                labelsDd.append(Label(contentCanvas,text=label))
                labelsDd[i].pack()
#               Erstelle die Dropdown Listen im scrollbaren Canvas
                varDd[i] = StringVar(root)
                listsDd.append(OptionMenu(canvas,varDd[i],*labels))  
                listsDd[i].place(x=70,y=10+(30*i))

contentCanvas = Frame(canvas,bg='#FFFFFF')
canvas.create_window((0,375),window=contentCanvas)
Björn
  • 1,610
  • 2
  • 17
  • 37
  • 1
    um... when would `if 'listDd' in locals()` ever possibly be True and why on earth are you checking for membership of `locals()`? – Tadhg McDonald-Jensen Dec 19 '16 at 22:32
  • @Tadhg McDonald-Jensen: if u run the Map button a second time. However if its bad I will remove it – Björn Dec 19 '16 at 22:36
  • if you don't know what your own code is doing what kind of help are you expecting? I know the first thing I'd tell you is "know what a line of code means/does before writing other code that relies on it" so any code that is in a conditional, I'd expect you to know what the conditional means. – Tadhg McDonald-Jensen Dec 19 '16 at 22:39
  • @TadhgMcDonald-Jensen I removed the line of code, sincerely. PS: still doesn't fix the other 2 issues – Björn Dec 19 '16 at 22:42
  • Ok the index error is happening because `varDd = [len(labels)]` _doesn't_ [initialize an empty lists with a certain length](http://stackoverflow.com/questions/10712002/create-an-empty-list-in-python-with-certain-size) and I think the second issue is happening because you need to call `canvas.create_window` to put the stuff in it instead of `.place`-ing the widgets inside it, I'm actually surprised that worked at all... Will need to investigate that further... – Tadhg McDonald-Jensen Dec 19 '16 at 22:53
  • @TadhgMcDonald-Jensen Thanks ;)! Will work into it – Björn Dec 19 '16 at 23:04
  • you are not stupid - you are new, it happens to everybody ;) I will ask that you edit your question putting that code in it, really hard to read from a comment. – Tadhg McDonald-Jensen Dec 19 '16 at 23:21
  • @TadhgMcDonald-Jensen I appreciate that, I found a solution, it was about the anchor -> I setted the offset to 350 for y now it starts with Marker label 0 So now the first issue is complete solved, box is scrollable. Thanks a lot for the hint with the create_window in the canvas – Björn Dec 19 '16 at 23:25

1 Answers1

0

The first issue arrises from this like:

varDd = [len(labels)]

While this syntax is used in other languages to mean "a list with this many elements in python it is just a list with one number:

>>> labels = range(4)
>>> v = [len(labels)]
>>> v
[4]

Instead you probably want something along the lines of this:

>>> varDb = [None]*len(labels)
>>> varDb
[None, None, None, None]

Then you can index it the same way as your other lists


The other issue is that using .place() inside a canvas places it on the screen but not on the canvas space itself, to do that you need to call canvas.create_window so this line:

listsDd[i].place(x=70,y=10+(30*i))

would translate to this:

canvas.create_window(70, 10+(30*i), window = listsDd[i])
Tadhg McDonald-Jensen
  • 20,699
  • 5
  • 35
  • 59
  • Thanks a lot! Regarding the canvas, does anything speak against my solution? Create a new frame out of the loop and fill this with the labels and OptionsMenus inside the loop? This solved all my issues! – Björn Dec 20 '16 at 10:40
  • nothing against it at all, in fact it makes me happy when people can figure out their own solutions :) – Tadhg McDonald-Jensen Dec 20 '16 at 11:09
  • Actually another question appeared regarding this code. I am using varDd[i] = StringVar(root), and I am not quite sure why I am giving it the Mainframe as an argument. This is related to my new Problem / Question which appeared, how do I access the varDd[i] content from another function? I am trying to avoid the usage of global variables – Björn Dec 20 '16 at 15:36
  • ok nvm, I solved with a wrapper class around the function which has the attribute varDd, so I can read it out later ;) – Björn Dec 20 '16 at 16:22
  • Don't actively avoid using global variables because people tell you "they are bad." When you learn about `class`es and the reusability of instance variables then you will understand why they are frequently preferred over globals but **always make code using the methods that make sense to you** (at least that's my motto) – Tadhg McDonald-Jensen Dec 20 '16 at 21:03