python - 如何防止 tkinter 画布的子窗口跨过画布滚动条
问题描述
我正在构建一个带有多个小部件的画布。滚动条工作正常,但他们踩到了看起来不太好的滚动条。是否可以在不踩滚动条的情况下使子窗口包含在画布中?我尝试在画布中添加一个框架并将我的小部件添加到该框架,但它遇到了其他一些问题。
from tkinter import *
from tkinter import ttk
from tkinter import messagebox
class MainUI:
def __init__(self,master):
self.master = master
self.content = ttk.Frame(self.master, padding=(3,3,12,12))
#row 4
self.canvasFrame = ttk.Frame(self.content,borderwidth=5, relief="sunken")
self.canvasFrame.grid(row=0, column=0, columnspan=3, sticky=W+E+N+S, pady=5, padx=15)
self.xscrollbar = Scrollbar(self.canvasFrame, orient=HORIZONTAL)
self.xscrollbar.grid(row=1, column=0, sticky=E+W)
self.yscrollbar = Scrollbar(self.canvasFrame)
self.yscrollbar.grid(row=0, column=1, sticky=N+S)
self.canvas = Canvas(self.canvasFrame, bd=0,
# scrollregion=(0, 0, 1000, 1000),
xscrollcommand=self.xscrollbar.set,
yscrollcommand=self.yscrollbar.set)
self.xscrollbar.config(command=self.canvas.xview)
self.yscrollbar.config(command=self.canvas.yview)
#listbox
self.listFrame = ttk.Frame(self.content,borderwidth=5, relief="sunken")
self.listFrame.grid(row=0, column=3, columnspan=2, sticky=W+E+N+S, pady=5, padx=15)
listYscrollbar = Scrollbar(self.listFrame)
listYscrollbar.grid(row=0, column=1, sticky=N+S)
self.actualCostlistbox = Listbox(self.listFrame)
self.actualCostlistbox.grid(row=0, column=0, sticky=W+E+N+S)
self.actualCostlistbox.config(yscrollcommand=listYscrollbar.set)
listYscrollbar.config(command=self.actualCostlistbox.yview)
self.canvas.grid(row=0, column=0, sticky=N+S+E+W)
self.content.grid(column=0, row=0, sticky=(N, S, E, W))
self.master.grid_rowconfigure(0,weight=1)
self.master.grid_columnconfigure(0,weight=1)
self.content.grid_rowconfigure(0,weight=1)
self.content.grid_columnconfigure(0,weight=1)
self.content.grid_columnconfigure(1,weight=1)
self.content.grid_columnconfigure(2,weight=1)
self.content.grid_columnconfigure(3,weight=1)
self.canvasFrame.grid_rowconfigure(0,weight=1)
self.canvasFrame.grid_columnconfigure(0,weight=1)
self.listFrame.grid_rowconfigure(0,weight=1)
self.listFrame.grid_columnconfigure(0,weight=1)
self.addEmpColumn()
self.canvas.configure(scrollregion = self.canvas.bbox("all"))
#events binding
self.canvas.bind("<Enter>", self.bound_to_mousewheel)
self.canvas.bind("<Leave>", self.unbound_to_mousewheel)
def addEmpColumn(self):
self.empComboBoxList = []
self.empList=['a','b','c']
for i in range(1, 30):
empCombo = ttk.Combobox(self.canvasFrame,
values=self.empList)
self.empComboBoxList.append(empCombo)
self.canvas.create_window(5, i * 25, anchor=NW, window=empCombo)
def mouse_wheel(self, event):
if self.yscrollbar.get() != (0.0, 1.0):
self.canvas.yview_scroll(-1 * int(event.delta / 60), "units")
if self.xscrollbar.get() != (0.0, 1.0):
self.canvas.xview_scroll(-1 * int(event.delta / 60), "units")
def bound_to_mousewheel(self, event):
self.canvas.bind_all("<MouseWheel>", self.mouse_wheel)
def unbound_to_mousewheel(self, event):
self.canvas.unbind_all("<MouseWheel>")
def on_closing():
root.destroy()
root = Tk()
mainui = MainUI(root)
root.title("Test")
root.protocol("WM_DELETE_WINDOW", on_closing)
root.mainloop()
解决方案
我相信问题出在:
def addEmpColumn(self):
self.empComboBoxList = []
self.empList=['a','b','c']
for i in range(1, 30):
empCombo = ttk.Combobox(self.canvasFrame,
values=self.empList)
self.empComboBoxList.append(empCombo)
self.canvas.create_window(5, i * 25, anchor=NW, window=empCombo)
在行中:
empCombo = ttk.Combobox(self.canvasFrame, values=self.empList)
它将 放置Combobox
在画布的框架中,而不是画布中。
empCombo = ttk.Combobox(self.canvas, values=self.empList)
推荐阅读
- clojure - 比较两个字符串并返回匹配的单词数
- python - 如何在 IIS 上使用 CGI 部署 Python 应用程序?
- c# - How to pass parameters from C # to assembler through registers?
- python - 我在 Flask 代码中找不到 404,我不知道为什么
- java - 无法在 adListener 中使用 sharedPreference
- python - 有没有一种有效的方法可以在 gitlab 上找到失败的管道?
- python - Jenkins Credentials 绑定和 Python Builder 遇到问题
- python - 如何获取丢失的 Udp 缓冲区大小超出的数据包
- video-capture - 使用 Microsoft Media Foundation 和 Desktop Duplication API 创建视频
- python - 当我尝试使用函数参数作为列表索引时,出现错误“列表索引必须是整数或切片,而不是元组”