问题描述
我是 Python 新手,在向画布添加鼠标滚动操作时遇到问题.我有一个垂直滚动条.当我手动滚动滚动条时,滚动条工作正常,或者将鼠标悬停在它上面并滚动鼠标滚轮.我的问题是,我希望能够在我的画布上滚动鼠标滚轮,甚至只是我的框架,只要我的鼠标悬停在它上面,就可以滚动其中的内容.我花了几个小时在stackoverflow上查看与此相关的所有类似问题,但我的修改似乎都不起作用.我目前遇到一个我无法纠正的奇怪错误.由于我的修改,错误仅在我开始滚动时出现,但不会导致崩溃.错误是:-
I am new to python and I have an issue adding mouse scrolling action to my canvas.I have a vertical scrollbar.The scrollbar works fine when I manually scroll it, or mouse over it and roll my mousewheel. My issue is that I would like to be able roll my mousewheel on my canvas or even just my frame and have the contents inside it scroll as long as my mouse is hovering over it.I have spent hours looking at all the similar questions related to this here on stackoverflow, and none of my modifications seem to work. I am currently getting a weird error that I cannot rectify. Due to my modifications, the error ONLY shows up when I start scrolling, however it does not cause a crash.The error is:-
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\twaku\Anaconda3\lib\tkinter\__init__.py", line 1699, in __call__
return self.func(*args)
File "C:/Users/twaku/PycharmProjects/DCSui/FileToSubmit.py", line 152, in _on_mousewheel
self.canvas.yview_scroll(int(-1 * (event.delta / 120), "units"))
TypeError: 'str' object cannot be interpreted as an integer
现在,如果我删除int"类型转换,则会出现此错误:-
Now if I remove the "int" typecast I get this error:-
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\twaku\Anaconda3\lib\tkinter\__init__.py", line 1699, in __call__
return self.func(*args)
File "C:/Users/twaku/PycharmProjects/DCSui/FileToSubmit.py", line 156, in _on_mousewheel
self.canvas.yview_scroll(-1 * (event.delta / 120), "units")
File "C:\Users\twaku\Anaconda3\lib\tkinter\__init__.py", line 1745, in yview_scroll
self.tk.call(self._w, 'yview', 'scroll', number, what)
_tkinter.TclError: expected integer but got "1.0"
所以现在我被困在两个错误之间.
So now I am stuck going back and forth between the two errors.
这是我的代码:-
from tkinter import *
import tkinter as tk
import time
import xlrd
root = Tk()
root.state('zoomed') # full screen -windowed
# ------------------INTRODUCTION BLOCK--------------
f1 = Frame(root, width=900, height=700, relief=SUNKEN)
f1.grid_rowconfigure(1, weight=1)
f1.grid_columnconfigure(2, weight=1)
f1.pack(fill=BOTH, expand=1, side=BOTTOM)
root.title("Diagram Scroll Test")
Tops = Frame(root, width=1600, height=50, relief=SUNKEN)
Tops.pack(side=TOP)
# ------------------TIME--------------
localtime = time.asctime(time.localtime(time.time()))
# -----------------INFO TOP------------
lblinfo = Label(Tops, font=('aria', 30, 'bold'), text="My Diagram Scroll Test",
fg="steel blue", bd=10, anchor='w')
lblinfo.grid(row=0, column=0)
lblinfo = Label(Tops, font=('aria', 20,), text=localtime, fg="steel blue", anchor=W)
lblinfo.grid(row=1, column=0)
lblinfo = Label(Tops, font=('aria', 15, 'bold'), text="Please help", fg="steel blue", bd=10,
anchor='w')
lblinfo.grid(row=2, column=0)
# ------------------CANVAS DEFINITION-------------
class CanvasDemo(Frame):
def __init__(self,root):
Frame.__init__(self,root)
self.canvas = tk.Canvas(root, borderwidth=0)
self.canvas.bind_all("<MouseWheel>", self._on_mousewheel)
self.frame = tk.Frame(self.canvas)
self.vsb = tk.Scrollbar(root, orient="vertical", command=self.canvas.yview)
self.canvas.configure(yscrollcommand=self.vsb.set)
root.state('zoomed')
self.vsb.pack(side="right", fill="y")
self.canvas.config(width=root.winfo_screenwidth(), height=root.winfo_screenheight())
# self.canvas.pack(side="left", fill="both", expand="1")
self.canvas.pack(fill="both", expand="1")
self.canvas.create_window((4, 4), window=self.frame, anchor="nw",
tags="self.frame")
self.frame.bind("<Configure>", self.onFrameConfigure)
self.populate()
# ------------------CODE TO CREATE BLOCK DIAGRAMS-------------
def populate(self):
i = 0
turnCount = 0 # Keeps track of how many boxes is used to trigger a turn
# Create Small starter box
lineVarx1 = 70
lineVary1 = 50
lineVarx2 = 120
lineVary2 = 50
varx1 = 120
vary1 = 25
varx2 = 220
vary2 = 75
varblk = 1
varline = 1
self.canvas.create_rectangle(20, 40, 70, 60, fill="green", tags="start")
while i < 200: # Provides 104 blocks
# ------------------IF STATEMENT TO CONTROL WHEN DIAGRAM TURNS-------------
if turnCount == 12: # At Turn Point, initiating turn sequence
lineVarx2 = lineVarx2 - 25
self.canvas.create_line(lineVarx1, lineVary1, lineVarx2, lineVary2, arrow="last", tags="to_r1")
# Downward line
lineVarx1 = lineVarx2
lineVary1 = lineVary2
lineVary2 = lineVary2 + 50
self.canvas.create_line(lineVarx1, lineVary1, lineVarx2, lineVary2, arrow="last", tags="to_r1")
# long line to left
lineVarx1 = lineVarx2
lineVary1 = lineVary2
lineVarx2 = lineVarx2 - 1825
self.canvas.create_line(lineVarx1, lineVary1, lineVarx2, lineVary2, arrow="last", tags="to_r1")
# Downward line
lineVarx1 = lineVarx2
lineVary1 = lineVary2
lineVary2 = lineVary2 + 50
self.canvas.create_line(lineVarx1, lineVary1, lineVarx2, lineVary2, arrow="last", tags="to_r1")
lineVary1 = lineVary2
lineVarx2 = lineVarx2 + 50
varx1 = lineVarx2
vary1 = lineVary2 - 25
varx2 = lineVarx2 + 100
vary2 = lineVary2 + 25
turnCount = 0
self.canvas.create_line(lineVarx1, lineVary1, lineVarx2, lineVary2, arrow="last", tags="to_r1")
self.canvas.create_rectangle(varx1, vary1, varx2, vary2, fill="bisque", tags="r1")
self.canvas.create_text(varx1 + 20, vary1, fill="darkblue", anchor=NW,
text="Hi")
self.canvas.create_text(varx1 + 20, vary1 + 10, fill="darkblue", anchor=NW,
text="bye")
self.canvas.create_text(varx1 + 20, vary1 + 20, fill="darkblue", anchor=NW,
text="fly")
lineVarx1 = lineVarx1 + 150
lineVarx2 = lineVarx2 + 150
varx1 = varx1 + 150
varx2 = varx2 + 150
i += 1
turnCount += 1
# "End" Block
lineVarx1 = varx2 - 150
lineVarx2 = lineVarx1 + 50
varx1 = lineVarx2
vary1 = lineVary1 - 10
varx2 = varx1 + 50
vary2 = lineVary1 + 10
self.canvas.create_line(lineVarx1, lineVary1, lineVarx2, lineVary2, arrow="last", tags="to_r1")
self.canvas.create_rectangle(varx1, vary1, varx2, vary2, fill="red", tags="r1")
def _on_mousewheel(self, event):
self.canvas.yview_scroll(-1 * (event.delta / 120), "units")
def onFrameConfigure(self, event):
'''Reset the scroll region to encompass the inner frame'''
self.canvas.configure(scrollregion=self.canvas.bbox("all"))
def qexit():
root.destroy()
btnexit = Button(f1, padx=16, pady=7, bd=10, fg="black", font=('ariel', 12, 'bold'), width=8, text="EXIT",
bg="powder blue", command=qexit)
btnexit.grid(row=15, column=2)
canvas = CanvasDemo(root)
canvas.pack()
mainloop()
推荐答案
除法结果是浮点数.尝试使用整数除法:
When you divide the result is a float. Try with integer division instead:
def _on_mousewheel(self, event):
self.canvas.yview_scroll(-1 * (event.delta // 120), "units")
here:--^
现在,您可能想要检查鼠标指针悬停在哪个小部件上方,因为当鼠标指针悬停在滚动条上时会调用 _on_mousewheel()
函数,使其滚动速度提高两倍.
Now, you may want to check which widget the mouse pointer is hovering above because the _on_mousewheel()
function is invoked when the mouse pointer hovers on the scrollbar, making it scroll twice as fast.
这篇关于用于在画布上滚动的 Tkinter 鼠标滚轮动作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!