我是 python 和 tkinter 的新手,我想使用 tkinter 创建仪表板。我编写了下面的代码来使用 Matplotlib 在 tkinter 中添加图形。由于我有 4 个图表,无法容纳所有图表,因此添加了一个水平滚动条,但不知何故它不起作用。请找到以下代码。
import tkinter as tk
from tkinter import ttk
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import matplotlib.pyplot as plt
import numpy as np
def calculate_gap(sum_of_demand, allocated, capacity):
if sum_of_demand - allocated < 0:
sum_of_not_demanded = abs(sum_of_demand - allocated)
elif capacity - sum_of_demand > 0:
sum_of_not_demanded = capacity - sum_of_demand
else:
sum_of_not_demanded = 0
if capacity - allocated > 0:
spare_capacity = capacity - allocated
else:
spare_capacity = 0
if sum_of_demand - capacity > 0:
skill_gap = sum_of_demand - capacity
else:
skill_gap = 0
return sum_of_not_demanded, spare_capacity, skill_gap
def h_scroll(*args):
print("In scroll")
graph1_canvas.get_tk_widget().xview(*args)
graph2_canvas.get_tk_widget().xview(*args)
graph3_canvas.get_tk_widget().xview(*args)
graph4_canvas.get_tk_widget().xview(*args)
def test_gap():
sum_of_demand = 256
allocated = 73
capacity = 66
sum_of_not_demanded, spare_capacity, skill_gap = calculate_gap(sum_of_demand, allocated, capacity)
width = 0.35
below = np.array([sum_of_demand, allocated, capacity])
above = np.array([sum_of_not_demanded, spare_capacity, skill_gap])
weight_counts = {
"Below": np.array([sum_of_demand, allocated, capacity]),
"Above": np.array([sum_of_not_demanded, spare_capacity, skill_gap])
}
title = ['Demand', 'Allocated', 'Capacity']
bottom = np.zeros(3)
for boolean, weight_count in weight_counts.items():
p = graph4_ax.bar(title, weight_count, width, label=boolean, bottom=bottom)
bottom += weight_count
graph4_canvas.draw()
# canvas1.get_tk_widget().pack(side="left",fill="both",expand=True)
graph4_canvas.get_tk_widget().pack(fill="both", expand=True, side="left")
graph4_canvas.get_tk_widget().config(scrollregion=graph4_canvas.get_tk_widget().bbox("all"))
graph4_canvas.get_tk_widget().config(xscrollcommand=horizontal_scrollbar.set,
scrollregion=graph4_canvas.get_tk_widget().bbox("all"))
# test_canvas.get_tk_widget().config(xscrollcommand=horizontal_scrollbar.set)
# test_canvas.get_tk_widget().bind("<<Key>>", pop_up)
def graph_three():
sum_of_demand = 256
allocated = 73
capacity = 66
sum_of_not_demanded, spare_capacity, skill_gap = calculate_gap(sum_of_demand, allocated, capacity)
if sum_of_demand - capacity > 0:
skill_gap = sum_of_demand - capacity
else:
skill_gap = 0
width = 0.1
weight_counts = {
"Below": np.array([sum_of_demand, allocated, capacity]),
"Above": np.array([sum_of_not_demanded, spare_capacity, skill_gap])
}
title = ['Demand', 'Allocated', 'Capacity']
bottom = np.zeros(3)
for boolean, weight_count in weight_counts.items():
p = graph_ax.bar(title, weight_count, width, label=boolean, bottom=bottom)
bottom += weight_count
graph3_canvas.draw()
# canvas1.get_tk_widget().pack(side="left",fill="both",expand=True)
graph3_canvas.get_tk_widget().pack(fill="both", expand=True, side="left")
graph3_canvas.get_tk_widget().config(scrollregion=graph3_canvas.get_tk_widget().bbox("all"))
graph3_canvas.get_tk_widget().config(xscrollcommand=horizontal_scrollbar.set,
scrollregion=graph3_canvas.get_tk_widget().bbox("all"))
# mobile_canvas.get_tk_widget().config(xscrollcommand=horizontal_scrollbar.set)
def graph_two():
sum_of_demand = 830
allocated = 313
capacity = 339
sum_of_not_demanded, spare_capacity, skill_gap = calculate_gap(sum_of_demand, allocated, capacity)
width = 0.35
weight_counts = {
"Below": np.array([sum_of_demand, allocated, capacity]),
"Above": np.array([sum_of_not_demanded, spare_capacity, skill_gap])
}
title = ['Demand', 'Allocated', 'Capacity']
bottom = np.zeros(3)
for boolean, weight_count in weight_counts.items():
p = graph2_ax.bar(title, width, label=boolean, bottom=bottom)
bottom += weight_count
graph2_canvas.draw()
# canvas1.get_tk_widget().pack(side="left",fill="both",expand=True)
graph2_canvas.get_tk_widget().pack(fill="both", expand=True, side="left")
graph2_canvas.get_tk_widget().config(scrollregion=graph2_canvas.get_tk_widget().bbox("all"))
graph2_canvas.get_tk_widget().config(xscrollcommand=horizontal_scrollbar.set,
scrollregion=graph2_canvas.get_tk_widget().bbox("all"))
# be_canvas.get_tk_widget().config(xscrollcommand=horizontal_scrollbar.set)
def graph_one():
sum_of_demand = 1631
allocated = 778
capacity = 795
sum_of_not_demanded, spare_capacity, skill_gap = calculate_gap(sum_of_demand, allocated, capacity)
width = 0.35
weight_counts = {
"Below": np.array([sum_of_demand, allocated, capacity]),
"Above": np.array([sum_of_not_demanded, spare_capacity, skill_gap])
}
title = ['Demand', 'Allocated', 'Capacity']
bottom = np.zeros(3)
for boolean, weight_count in weight_counts.items():
p = graph1_ax.bar(title, weight_count, width, label=boolean, bottom=bottom)
bottom += weight_count
graph1_canvas.draw()
graph1_canvas.get_tk_widget().config(scrollregion=graph1_canvas.get_tk_widget().bbox("all"))
graph1_canvas.get_tk_widget().config(xscrollcommand=horizontal_scrollbar.set,
scrollregion=graph1_canvas.get_tk_widget().bbox("all"))
# horizontal_scrollbar.config(command=h_scroll())
root = tk.Tk()
# Main Frame
frame = ttk.Frame(root)
frame.pack()
# Data Frame
graph_frame = ttk.Labelframe(frame, text="Skill Gap")
graph_frame.grid(side = tk.RIGHT, expand = True, fill = tk.BOTH)
horizontal_scrollbar = ttk.Scrollbar(graph_frame, orient=tk.HORIZONTAL, command=h_scroll)
horizontal_scrollbar.pack(side=tk.BOTTOM, fill=tk.X)
# Canvas
graph1_fig, graph1_ax = plt.subplots(dpi=100)
graph1_canvas = FigureCanvasTkAgg(graph1_fig, graph_frame)
horizontal_scrollbar.config(command=graph1_canvas.get_tk_widget().xview)
graph1_canvas.get_tk_widget().config(yscrollcommand=horizontal_scrollbar.set)
# Canvas
graph2_fig, graph2_ax = plt.subplots(dpi=100)
graph2_canvas = FigureCanvasTkAgg(graph2_fig, graph_frame)
# Canvas
graph3_fig, graph_ax = plt.subplots(dpi=100)
graph3_canvas = FigureCanvasTkAgg(graph3_fig, graph_frame)
# Canvas
graph4_fig, graph4_ax = plt.subplots(dpi=100)
graph4_canvas = FigureCanvasTkAgg(graph4_fig, graph_frame)
graph_one()
graph_two()
graph_three()
test_gap()
horizontal_scrollbar.config(command=h_scroll)
tk.mainloop()
我期待水平滚动条能够正常工作。并且能够滚动浏览所有图表。
Tkitner
只能滚动Canvas
、Listbox
和Text
,但不能滚动Frame
如果你想滚动所有元素,那么你必须将它们放在一个
tkinter.Frame
中,并将该框架放在 tkinter.Canvas
上,并使用 tkinter.Scrollbar
在画布上滚动该框架。
我从你上一个问题的答案中获取了一个代码
python - 无法使用 matplotlib 显示超过 4-5 个条形图 - 代码日志 我添加了滚动的洞穴
import tkinter as tk
from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg, NavigationToolbar2Tk)
from matplotlib.figure import Figure
import matplotlib.pyplot as plt
# --- functions ---
def resize(event):
dashboard_canvas.configure(scrollregion=dashboard_canvas.bbox('all'))
# --- main ---
x = [1, 2, 3, 4]
y = [1, 2, 3, 4]
AS = [10 / 2 ** 0]
# ---
root = tk.Tk()
root.geometry("1000x1000")
root.title("eggs")
# ---
# canvas
dashboard_canvas = tk.Canvas(root)#, bg='#00c000') # background color only to test its size
dashboard_inner_frame = tk.Frame(dashboard_canvas)
inner_frame_id = dashboard_canvas.create_window((0,0), window=dashboard_inner_frame, anchor='nw')
dashboard_canvas.pack(fill='both', expand=True)
# scrollbar
dasboard_scrollbar_x = tk.Scrollbar(root, orient='horizontal')
dasboard_scrollbar_x.pack(fill='x')
# join widgets
dashboard_canvas.configure(xscrollcommand=dasboard_scrollbar_x.set)
dasboard_scrollbar_x['command'] = dashboard_canvas.xview
# resize scrollregion on canvas when plots will have size (and it will be after starting program and drawing plots)
dashboard_inner_frame.bind('<Configure>', resize)
#---
# put on dashboard_inner_frame
frame_top = tk.Frame(dashboard_inner_frame, width=2000)
frame_top.pack(fill='both', expand=True)
plots = []
for index in range(10):
fig = Figure(dpi=100)
ax = fig.add_subplot(111)
ax.plot(x, y)
fig.suptitle(f"Plot {index+1}")
canvas = FigureCanvasTkAgg(fig, master=frame_top)
canvas.draw()
canvas.get_tk_widget().pack(side="left", fill='both', expand=True)
#canvas.get_tk_widget()['width'] = 1
plots.append({'fig': fig, 'canvas': canvas})
root.mainloop()