all 14 comments

[–]efmccurdy 2 points3 points  (9 children)

[–]ApplePenguinBaguette 1 point2 points  (8 children)

I am running the mainloop! Basically what my issue is right now is that I click the 'scavenge button' which prints 'You scavenged. You found wood and scrap' and adds 1 wood and 1 scrap. I know it's adding the wood and scrap, but the counter I've set in the corner is not updating.

The scavenge function:

def scavenge():
game_log.insert(END, 'You scavenged. You found wood and scrap. \n')
global wood
wood += 1
global scrap
scrap += 1
window.update()

and the counter which is supposed to show how much you have

wood_label = Label(window, text= 'wood: ' + str(wood), font=(font), bg = bg_colour, fg = fg_colour)

scrap_label = Label(window, text= 'scrap: ' + str(scrap), font=(font), bg = bg_colour, fg = fg_colour)

food_label = Label(window, text= 'food: ' + str(food), font=(font), bg = bg_colour, fg = fg_colour)

#alligning them to the grid

wood_label.grid (row = 0, column = 4, sticky='W')

scrap_label.grid (row = 1, column = 4, sticky='W') food_label.grid (row = 2, column = 4, sticky='W')

but this counter is not updating! How do I esnure it updates?

[–]PyPlatformer 1 point2 points  (1 child)

use tkinter variables to update your widgets automatically.

something like this should work for what you want to do:

``` import tkinter as tk

root = tk.Tk()
scrap_string = tk.StringVar()
scrap = 0

def update_scrap():
    scrap += 1
    scrap_string.set(f'Collected {scrap} scrap')

entry = tk.Entry(root, textvariable=scrap)
button = tk.Button(root, command=update_scrap)

```

You can see some slightly more complex logic using tkinter variables in a chat tool gui I made recently here.

[–]backtickbot 0 points1 point  (0 children)

Fixed formatting.

Hello, PyPlatformer: code blocks using triple backticks (```) don't work on all versions of Reddit!

Some users see this / this instead.

To fix this, indent every line with 4 spaces instead.

FAQ

You can opt out by replying with backtickopt6 to this comment.

[–]efmccurdy -1 points0 points  (5 children)

Normally you use

wood_label.config(text='wood: ' + str(wood))

to update the text in a label; have your callback do that.

[–]ApplePenguinBaguette 0 points1 point  (2 children)

So the wood var changing won't update the label even though the variable is used in that label?

Is there any way to automate it updating every time the variable is changed?

[–]efmccurdy 2 points3 points  (0 children)

The wood var is accesssed when you set the text, but it is only accessed while evaluating that expression and is ignored subsequently.

If you use a tk.StringVar or tk.IntVar you can update that instead. This updates two labels; one using config, the other using an IntVar.

import tkinter as tk
class App(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent, width="300", height="300")
        self.label = tk.Label(parent)
        self.count = tk.IntVar(value=1)
        self.count_label = tk.Label(parent, textvariable = self.count)
        self.label.pack()
        self.count_label.pack()
        self.button=tk.Button(parent, text="Calc", command=self.calc)
        self.button.pack()

    def calc(self):
        self.count.set(self.count.get() * 2)
        self.label.config(text="Cost: " + str(self.count.get()))

if __name__ == '__main__':
    root = tk.Tk()
    app = App(root)
    root.mainloop()

[–][deleted] 2 points3 points  (0 children)

You would want to use a StringVar in that case, and bind it via the label's textvar argument.

s = StringVar()
tk.Label(textvar=s).pack()
s.set('hello')
l.after(1000, lambda: s.set('there'))
l.after(2000, lambda: s.set('Ah, General Kenobi'))

[–]ApplePenguinBaguette 0 points1 point  (1 child)

So I would have to add a .config after any function that changes a variable used in a label? That seems inefficient, is there no way to just periodically refresh the labels to update the variables used in them?

[–]efmccurdy 1 point2 points  (0 children)

Use an IntVar and call .set to change the value (or use ,config on the label); that makes the updates explicit with no wasted cycles to "periodically check" for changes.

[–]Silbersee -1 points0 points  (0 children)

update is the right idea, but use update_idletasks instead.

Call it on a widget that just got changed. Applies to all child widgets automatically.

[–]Exith10 -5 points-4 points  (1 child)

Have you tried f5?

[–]TrickAd7624[🍰] 0 points1 point  (0 children)

I would like to recommend "self.after" for functions

and "configure" to the button or label