【问题标题】:How can I get the scrollbar to move with my cursor如何让滚动条随光标移动
【发布时间】:2019-09-18 11:51:18
【问题描述】:

我想将光标与滚动条绑定,这样当我切换到下一个文本小部件时,窗口将滚动到光标所在的位置。

在我的代码中,我有许多 Text 小部件,并且窗口是可滚动的。我使用 ctrl-tab 移动到下一个 Text 小部件,但是当光标位于不在窗口中的小部件中时,滚动条不会移动。我知道我将滚动条绑定到鼠标滚轮。我怎样才能使滚动条绑定到光标移动。

import tkinter as tk
from tkinter import *
from tkinter import ttk


def on_mousewheel(event):
    canvas.yview_scroll(int(-1 * (event.delta / 120)), "units")

def on_configure(event):
    # update scrollregion after starting 'mainloop'
    # when all widgets are in canvas
    canvas.configure(scrollregion=canvas.bbox('all'))
    canvas.itemconfigure('internal_frame', width=event.width - 10)

# Create new window
new_win = tk.Tk()
new_win.focus_force()

# Create a canvas with a scrollbar
canvas = tk.Canvas(new_win)
canvas.grid(row=0, column=0, sticky=tk.N + tk.S + tk.E + tk.W)

scrollbar = ttk.Scrollbar(new_win, command=canvas.yview)
scrollbar.grid(sticky=(N, S), row=0, column=1)
canvas.config(yscrollcommand=scrollbar.set)

# --- put frame in canvas ---
new_frame = tk.Frame(canvas)
new_frame.grid(row=0, column=0, sticky=tk.N + tk.S + tk.E + tk.W)

canvas.create_window((0, 0), window=new_frame, anchor='nw', tags=('internal_frame',))

# update scrollregion after starting 'mainloop when all widgets are in canvas
canvas.bind('<Configure>', on_configure)
new_win.bind('<MouseWheel>', on_mousewheel)

# Add Widgets
insert_box = []
for i in range(10):
    insert_box.append(tk.Text(new_frame, borderwidth=2, height=4, width=30, wrap=WORD))
    insert_box[i].grid(column=1, row=i, sticky=tk.N + tk.S + tk.E + tk.W)

# configure
new_win.grid_columnconfigure(0, weight=1)
new_win.grid_rowconfigure(0, weight=1)

new_frame.grid_columnconfigure(1, weight=1)
new_frame.grid_rowconfigure(0, weight=1)

canvas.grid_columnconfigure(0, weight=1)
canvas.grid_rowconfigure(0, weight=1)

new_win.mainloop()

【问题讨论】:

  • 您可以检测到活动框架,然后您应该能够进行一些数学运算以查看该框架是否不在视野范围内,然后根据该框架向下滚动。但我不确定是否有现有的简单方法可以用于此。

标签: python-3.x tkinter


【解决方案1】:

如果您想通过 Ctrl+Tab 或光标移动到当前的 Text 小部件,因为您已经有一个 insert_box 列表。只需将yview_moveto 命令绑定到您创建的每个Text 小部件到FocusIn

for i in insert_box:
    i.bind("<FocusIn>",lambda e, i=i:canvas.yview_moveto(insert_box.index(i)/len(insert_box)))

【讨论】:

  • 谢谢,这适用于所有盒子尺寸相同但尺寸不同时它开始有点偏离
  • 这只是为了展示它的一般工作原理。您可以通过一点数学计算出确切的位置; yview_moveto 采用 0-1 之间的浮点数作为参数。
  • 知道了,这就是我想要弄清楚的。谢谢。
猜你喜欢
  • 2018-10-04
  • 2022-11-23
  • 1970-01-01
  • 2011-11-05
  • 2020-03-01
  • 1970-01-01
  • 2022-11-18
  • 2017-08-17
  • 1970-01-01
相关资源
最近更新 更多