3

Using Python 3.6/tkinter on MacOS, I created a frame within a canvas and bound a scrollbar to it. This all works fine. The problem is when I try to snag MouseWheel events when the cursor is in the scrollable frame. I set up a binding:

main_window.bind("<MouseWheel>",on_mousewheel)

and created a short dummy event handler:

def on_mousewheel(event):
    print(event.delta)

Every time I use the scroll wheel, Python responds with:

Traceback (most recent call last):
  File "/Users/Gary/IPPS/opendb.py", line 160, in <module>
    main_window.mainloop()
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/tkinter/__init__.py", line 1277, in mainloop
    self.tk.mainloop(n)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte

Here is the code:

from tkinter import *

def on_main_window_resize(event):
    canvas.configure(scrollregion=canvas.bbox('all'))

def on_mousewheel(event):
    print(event.delta)

main_window = Tk()
main_window.bind("<MouseWheel>",on_mousewheel)
canvas = Canvas(main_window, width=500, height=500)
canvas.pack(side=LEFT, fill=BOTH, expand=YES)
cust_scroll = Scrollbar(main_window, orient=VERTICAL, command=canvas.yview)
cust_scroll.pack(side=RIGHT, fill=Y, expand=NO)
cust_list = Frame(canvas)
canvas['yscrollcommand'] = cust_scroll.set
canvas.bind('<Configure>', on_main_window_resize)
canvas.create_window((0,0), window=cust_list, anchor=NW)
main_window.grid_columnconfigure(0, weight=1)
main_window.grid_rowconfigure(0, weight=1)

memberbuttons = list();
for member in range(1,20):
    memberbutton = Button(cust_list, text="BUTTON", justify=LEFT, pady=2)
    memberbutton.pack(side=TOP, fill=X)
main_window.mainloop()

Any ideas?

Gary R.
  • 175
  • 10
  • 2
    Please provide [a Minimal, _Complete_, and Verifiable example](https://stackoverflow.com/help/mcve). In its current state, the code you've provided is incomplete to reproduce that error. – Nae Jan 03 '18 at 21:42
  • 1
    I've added the code, @Nae. Sorry about that. – Gary R. Jan 03 '18 at 22:02
  • 1
    I can't reproduce the same error still. Only that mousewheel does nothing w/o any errors. – Nae Jan 03 '18 at 22:13
  • What do you get with `print(repr(event.delta))` or `print(type(event.delta))`? – Novel Jan 03 '18 at 22:13
  • The first "tick" of the mouse wheel works fine, displaying 1 or -1 depending on the direction of movement (I didn't notice this before, as I was just spinning the wheel). The second movement of the mouse wheel causes the Unicode error as shown, no matter what the "print()" contains. I tried it with just `print("on_mousewheel")` (not referencing event.delta at all), and it fails with the Unicode error immediately. – Gary R. Jan 03 '18 at 22:24
  • @GaryR. this is extremely strange. I can't reproduce this either, so I'm just shooting in the dark here: Try binding to the canvas instead of the root window: `canvas.bind("",on_mousewheel)` – Novel Jan 03 '18 at 22:28
  • @Novel, binding it to the canvas doesn't help, even when not referencing event.delta. Is this a Mac problem, perhaps? I'm using the tkinter library that automatically installed with Python 3.6, so it wouldn't be a version mismatch. – Gary R. Jan 03 '18 at 22:45
  • Another shot in the dark: Add `return "break"` to the on_mousewheel function. – Novel Jan 03 '18 at 22:54
  • 2
    Adding `return "break"` doesn't change anything. Strangely, though, if I add the `return "break"` and remove the `print(event.delta)`, then I get the Unicode error the first time I attempt to scroll down, but not until the second time I attempt to scroll up. This is confusing the heck out of me. – Gary R. Jan 03 '18 at 23:05
  • Can you provide the actual error message from this very code snippet that you've provided? – Nae Jan 03 '18 at 23:37
  • The code works as shown on Python 3.6 with Windows 10 as well and returns an integer value (-120 or 120 in my case). What does `print(ascii(event.delta))` display? – Mark Tolonen Jan 04 '18 at 01:40
  • Thank you all for the help and suggestions, but I've given up on tkinter and switched to wxPython, which seems to be working *much* more smoothly for me. – Gary R. Jan 04 '18 at 18:41
  • 2
    I got the same error by accident and I can also reproduce the error with the code provided. Python 3.6.5 on a macOS 10.13.4. Seems like a bug in the tkinter library. – felixbade Jun 04 '18 at 12:13
  • Thank you, felixblade! I'm glad to hear it was reproducible for someone else. – Gary R. Jun 30 '18 at 01:59
  • It's so strange. I have the same problem here and don't know how to solve.. – Benedetto Abbenanti Oct 21 '18 at 23:37

1 Answers1

0

I found some references online useful to grasp the problem, it seems to happen on an older version of ActiveTcl (8.5.x).

Inertial scrolling in Mac OS X with Tkinter and Python

nltk/nltk on Github - OS X: downloader GUI crashes in Python 3 when mouse wheel is used for scrolling

The solution is to upgrade your version of ActiveTlc to >=8.6 and you can do this in two ways:

  • manually
  • installing the latest version of Python 3.7.1 via the binary package on Python Release 3.7.1