I’ve been trying to make a program, with 3 layouts depending on the window’s width (using Tkinter).
The issue is in the medium layout. Whenever I place my mouse onto the left canvas and use the MouseWheel, the right canvas scrolls, when the left canvas is supposed to. When my mouse is placed on the right canvas and I use the mouse wheel, the right canvas scrolls. I can’t find any solution to this.
import tkinter as tk
from tkinter import ttk
import random as rand
class App(tk.Tk):
def init(self, Geometry, Icon, MinimumSizesDictionary):
super().init()
self.title("Practise")
self.geometry(f"{Geometry[0]}x{Geometry[1]}")
self.minsize(Geometry[0], Geometry[1])
self.iconbitmap(Icon)
# variables
self.MinimumSizesDictionary = MinimumSizesDictionary
# widgets
self.LayoutNSizeChecker = LayoutNSizeChecker(self, self.MinimumSizesDictionary)
# run
self.mainloop()
class LayoutNSizeChecker(ttk.Frame):
def init(self, Parent, MinimumSizesDictionary):
super ().init(Parent)
self.pack(expand = True, fill = "both")
self.MinimumSizesDictionary = MinimumSizesDictionary
self.MinimumSize = self.CurrentMinimumSize = None
self.Layout = None
# binding an event to the main frame
self.bind("<Configure>", lambda event : self.Update())
# binding an event to the window
Parent.bind("<Configure>", lambda event : self.CheckScreenSize(event, Parent))
def CheckScreenSize(self, event, Window):
if event.widget == Window:
for Key, Value in self.MinimumSizesDictionary.items():
self.Delta = event.width - Key
if self.Delta >= 0: self.MinimumSize = Key
if self.CurrentMinimumSize != self.MinimumSize:
self.CurrentMinimumSize = self.MinimumSize
if self.CurrentMinimumSize == 300:
for Widget in self.winfo_children():
Widget.destroy()
self.Destroyed = True
print("small layout")
self.Layout = "Small"
# variables
self.NumberOfButtons = 20
self.SpaceEachRowTakes = 100
self.TotalHeight = self.NumberOfButtons * self.SpaceEachRowTakes
# canvas
self.Canvas = tk.Canvas(self, scrollregion = (0, 0, self.winfo_width(), self.TotalHeight))
self.Canvas.pack(expand = True, fill = "both")
# canvas frame
self.CanvasFrame = ttk.Frame(self)
# scroll bar
self.ScrollBar = ttk.Scrollbar(self, orient = "vertical", command = self.Canvas.yview)
self.ScrollBar.place(relx = 1, rely = 0, relheight = 1, anchor = "ne")
self.Canvas.config(yscrollcommand = self.ScrollBar.set)
# scroll using the mousewheel
self.Canvas.bind_all("<MouseWheel>", lambda event : self.Scroll(event))
for i in range(1, 21):
self.FramePortion = ttk.Frame(self.CanvasFrame)
# variables
self.TextData = ["hello!", "goodbye!", "cya", "innit", "lol", "xd", "alr", "bro", "dude", "wsg"]
# making the grid
self.FramePortion.rowconfigure(0, weight = 1, uniform = "z")
self.FramePortion.columnconfigure((0, 1, 2), weight = 1, uniform = "z")
# the widgets
self.Button1 = ttk.Button(self.FramePortion, text = i)
self.Button2 = ttk.Button(self.FramePortion, text = rand.choice(self.TextData))
self.Button3 = ttk.Button(self.FramePortion, text = rand.choice(self.TextData))
# placing the widgets onto the grid we created earlier
self.Button1.grid(row = 0, column = 0, sticky = "nesw", padx = 5, pady = 5)
self.Button2.grid(row = 0, column = 1, sticky = "nesw", padx = 5, pady = 5)
self.Button3.grid(row = 0, column = 2, sticky = "nesw", padx = 5, pady = 5)
self.FramePortion.pack(expand = True, fill = "both")
self.Destroyed = False
elif self.CurrentMinimumSize == 600:
print("medium layout")
self.Layout = "Medium"
for Widget in self.winfo_children():
Widget.destroy()
self.Destroyed = True
# grid for main frame
self.rowconfigure(0, weight = 1, uniform = "z")
self.columnconfigure((0, 2), weight = 6, uniform = "z")
self.columnconfigure((1, 3), weight = 1, uniform = "z")
# left side layout
self.LeftFrame = ttk.Frame(self)
self.LeftFrame.grid(row = 0, column = 0, sticky = "nesw")
self.LeftCanvas = tk.Canvas(self.LeftFrame, scrollregion = (0, 0, self.LeftFrame.winfo_width(), self.TotalHeight / 2))
self.LeftCanvas.pack(side = "left", pady = 10, expand = True, fill = "both")
self.LeftCanvasFrame = ttk.Frame(self.LeftCanvas)
# scroll bar
self.LeftScrollBar = ttk.Scrollbar(self, orient = "vertical", command = self.LeftCanvas.yview)
self.LeftScrollBar.grid(row = 0, column = 1, sticky = "ns")
self.LeftCanvas.config(yscrollcommand = self.LeftScrollBar.set)
# scroll using the mouse wheel
self.LeftCanvas.bind_all("<MouseWheel>", lambda event : self.LeftScroll(event))
for i in range(1, 11):
self.LeftFramePortion = ttk.Frame(self.LeftCanvasFrame)
self.Button4 = ttk.Button(self.LeftFramePortion, text = i)
self.Button5 = ttk.Button(self.LeftFramePortion, text = rand.choice(self.TextData))
self.Button6 = ttk.Button(self.LeftFramePortion, text = rand.choice(self.TextData))
self.Button4.pack(expand = True, fill = "both", padx = 2.5, pady = 2.5)
self.Button5.pack(expand = True, fill = "both", padx = 2.5, pady = 2.5)
self.Button6.pack(expand = True, fill = "both", padx = 2.5, pady = 2.5)
self.LeftFramePortion.pack(expand = True, fill = "both")
# right side layout
self.RightFrame = ttk.Frame(self)
self.RightFrame.grid(row = 0, column = 2, sticky = "nesw")
self.RightCanvas = tk.Canvas(self.RightFrame, scrollregion=(0, 0, self.RightFrame.winfo_width(), self.TotalHeight / 2))
self.RightCanvas.pack(side = "left", pady = 10, expand = True, fill = "both")
self.RightCanvasFrame = ttk.Frame(self.RightCanvas)
# scroll bar
self.RightScrollBar = ttk.Scrollbar(self, orient = "vertical", command = self.RightCanvas.yview)
self.RightScrollBar.grid(row = 0, column = 3, sticky = "ns")
self.RightCanvas.config(yscrollcommand = self.RightScrollBar.set)
# scroll using the mouse wheel
self.RightCanvas.bind_all("<MouseWheel>", lambda event : self.RightScroll(event))
for i in range(11, 21):
self.RightFramePortion = ttk.Frame(self.RightCanvasFrame)
self.Button7 = ttk.Button(self.RightFramePortion, text = i)
self.Button8 = ttk.Button(self.RightFramePortion, text = rand.choice(self.TextData))
self.Button9 = ttk.Button(self.RightFramePortion, text = rand.choice(self.TextData))
self.Button7.pack(expand = True, fill = "both", padx = 2.5, pady = 2.5)
self.Button8.pack(expand = True, fill = "both", padx = 2.5, pady = 2.5)
self.Button9.pack(expand = True, fill = "both", padx = 2.5, pady = 2.5)
self.RightFramePortion.pack(expand = True, fill = "both")
self.Destroyed = False
elif self.CurrentMinimumSize == 1000:
print("large layout")
self.Layout = "Large"
for Widget in self.winfo_children():
Widget.destroy()
self.Destroyed = True
def Update(self):
if not self.Destroyed and self.Layout == "Small":
self.Canvas.create_window(
(0, 0),
anchor = "nw",
window = self.CanvasFrame,
width = self.winfo_width(),
height = self.TotalHeight
)
elif not self.Destroyed and self.Layout == "Medium":
self.LeftCanvas.create_window(
(0, 0),
anchor = "nw",
window = self.LeftCanvasFrame,
width = self.LeftFrame.winfo_width(),
height = self.TotalHeight / 2
)
self.RightCanvas.create_window(
(0, 0),
anchor = "nw",
window = self.RightCanvasFrame,
width = self.RightFrame.winfo_width(),
height = self.TotalHeight / 2
)
def Scroll(self, event):
if not self.Destroyed and self.Layout == "Small":
self.Canvas.yview_scroll(-int(event.delta / 60), "units")
def LeftScroll(self, event): # left scroll bar function for medium layout
self.LeftCanvas.yview_scroll(-int(event.delta / 60), "units")
def RightScroll(self, event): # right scroll bar function for medium layout
self.RightCanvas.yview_scroll(-int(event.delta / 60), "units")
App = App([300, 300], “icon.ico”, {300 : “Small”, 600 : “Medium”, 1000 : “Large”})
as always in the medium layout, whenever i use the mouse wheel, it scrolls the right canvas no matter what.
New contributor
clicky clicky is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.