1

Go to very bottom for question, detail is at top.

Currently I have a custom made GUI that looks like this:

GUI

This is created using absolute positioning on the 2 buttons, the sell button and the sapling button. The text positioning is created like this:

for i in range(len(self.panel.texts)):
     screen.blit(self.panel.texts[i].text, (self.panel.pos[0] + self.panel.offset, self.panel.offset+i*self.panel.offset))

The panel class is what contains the buttons and text within a 'panel' of the GUI.

class Panel:
    def __init__(self, surface, pos, texts, buttons):
        self.surface = surface
        self.pos = pos
        self.texts = texts
        self.buttons = buttons
        self.offset = 20

For reference the Text class:

class Text:
    def __init__(self, text, pos=(0, 0), font=font_medium, color=BLACK, anchor='top-left'):
        self.string = text
        self.text = font.render(text, False, color)
        if anchor == 'center':
            self.pos = minus_tuple(pos, (self.text.get_width()/2, self.text.get_height()/2))
        else:
            self.pos = pos

and the Button class:

class Button:
    def __init__(self, surface, pos, text='', anchor='top-left'):
        self.surface = surface
        if anchor == 'center':
            self.pos = minus_tuple(pos, (self.surface.get_width()/2, self.surface.get_height()/2))
        else:
            self.pos = pos
        self.text = Text(text, add_tuple(self.pos, (self.surface.get_width()/2, self.surface.get_height()/2)), anchor='center')

I'm trying to make it so I can have a list of both text and buttons that when looped over will be assigned a position (x, y) that will not conflict with an existing button. I want to make sure they're spaced out, one on each line is fine to begin with a little like what is in the picture.

I'm having trouble as I can't find a way to loop through a list of objects while changing an element (the pos) of the object. I do know about list comprehensions and the fact that you can't assign a new value to an element within a list while looping over it but I still can't find a way.

I can't use the method I used to display the text on the buttons as the position of the button is important, that is what determines whether they are clicked or not. I also think it'd just be better coding to assign real positions to every object anyway.

You may find a better solution to my problem but as far as I know the next step I don't know how to do is getting:

Panel([Text(blah, pos=(0,0), Text(blah, pos=(0,0)], [Button(blah, pos=(0,0)])

to:

Panel([Text(blah, pos=(0,20), Text(blah, pos=(0,40)], [Button(blah, pos=(0,60)])
Bob
  • 21
  • 3
  • `I do know about list comprehensions and the fact that you can't assign a new value to an element within a list while looping over it but I still can't find a way.` What makes you think that? – Mick_ Apr 04 '18 at 02:38
  • `self.panel.texts[i].pos = [i*20 for i in range(len(self.panel.texts))]` This was the best I could come up with but obviously it doesn't work as it'd be assigning a whole list to 1 position. What I'd like is for each iteration of the loop to be assigned to a different object in a list. I'd do the following but it doesn't work as I can't assign new variables to an existing list during a loop: `for i in range(len(self.panel.texts)): self.panel.texts[i].pos = i*20 ` – Bob Apr 04 '18 at 03:35
  • Sure you can assign new variables to a list you're iterating over. You cannot however make changes to the actual list (like removing or adding elements), as this can cause the loop to access wrong elements. In other words, as long as the list doesn't change length during the iteration, there shouldn't be any problem. – Ted Klein Bergman Apr 04 '18 at 09:23

0 Answers0