Search code examples
pythonpython-3.xtkintertkinter-button

Why is my boolean variable not updating when changed within functions in my tkinter custom scrollbar widget?


I am trying to make a custom scrollbar widget for tkinter in Python3. I'm using classes and functions to organise my code. I have a boolean variable that needs to be accessed by the rest of the program to determine whether the scrollbar is active so that it can be updated visually to move with the user's mouse. Changing this variable is done within two functions however when I observe the variable outside the function it has nto updated which has made me believe that I'm doing something wrong with how I am handling self, or just how global and local variables work inside functions and classes. I tried a number of things however I could not get it to work.

Here are the two functions that change the variable:

def scrollOn(self):
    self.scrolling = True
def scrollOff(self):
    self.scrolling = False

Both of these functions are triggered by tkinter bind events from a tkinter.Button:

scrollBar = tk.Button(window, bg = "#000000")
scrollBar.place(x = 390, y = 30, width = 20, height = 40)
scrollBar.bind("<Button-1>", lambda s = self : scrollOn(s))
scrollBar.bind("<ButtonRelease-1>", lambda s = self : scrollOff(s))

This is all of the code:

import tkinter as tk

class scrollbar:

    scrolling = False   

    def __init__(self, window):

        scrollFrame = tk.Frame(window, bg = "#666666")
        scrollFrame.place(x = 10, y = 10, width = 400, height = 400)

        scrollBounds = tk.Frame(window, bg = "#444444")
        scrollBounds.place(x = 390, y = 30, width = 20, height = 360)

        upButton = tk.Button(window, text = "")
        upButton.place(x = 390, y = 10, width = 20, height = 20)

        downButton = tk.Button(window, text = "")
        downButton.place(x = 390, y = 390, width = 20, height = 20)

        def scrollOn(self):
            self.scrolling = True
        def scrollOff(self):
            self.scrolling = False
            
        scrollBar = tk.Button(window, bg = "#000000")
        scrollBar.place(x = 390, y = 30, width = 20, height = 40)
        scrollBar.bind("<Button-1>", lambda s = self : scrollOn(s))
        scrollBar.bind("<ButtonRelease-1>", lambda s = self : scrollOff(s))

        def updateScrollbar(self):
            if self.scrolling == True:
                print("SCROLLING")
            window.after(1, lambda s = self : updateScrollbar(s))
            
        window.after(1, lambda s = self : updateScrollbar(s))

I tried a few different configurations that came to mind when trying to solve this problem however I couldn't solve it. Observing the variable inside the two functions returns the correct result. Any help and guidance would be much appreciated, constructive criticism on how I've wrote my code is appreciated too


Solution

  • self scrollOn and in scrollOff is not scrollbar, it's a ButtonPress event. Remove the parameter or change it to something else

    def scrollOn():
        self.scrolling = True
    
    def scrollOff():
        self.scrolling = False
    
    scrollBar = tk.Button(window, bg="#000000")
    scrollBar.place(x=390, y=30, width=20, height=40)
    scrollBar.bind("<Button-1>", lambda s=self: scrollOn())
    scrollBar.bind("<ButtonRelease-1>", lambda s=self: scrollOff())