这里是业余程序员。我使用 tkinter GUI 和 matplotlib 用 Python 编写了一个程序来计算并绘制根据用户输入的数字生成的 Collatz 猜想序列:
import tkinter as tk
from tkinter import ttk
import ttkbootstrap as ttk
from matplotlib.figure import Figure
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg,
NavigationToolbar2Tk)
seq =[]
def calc():
global num
num = int(entry.get())
while num > 2:
if num % 2 == 0:
num = num / 2
else:
num = 3 * num + 1
seq.append(int(num))
def plot_sequence():
global ax
global canvas
fig = Figure(facecolor='lightblue', edgecolor = "blue")
ax = fig.add_subplot(111)
ax.clear()
ax.plot(seq, marker='o', linestyle='-')
ax.set_xlabel('Iteration')
ax.set_ylabel('Value')
ax.set_title('Collatz Sequence')
canvas = FigureCanvasTkAgg(fig)
canvas.draw()
canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1)
ax.plot(seq)
def clear_graph():
ax.clear()
canvas.draw()
entry.delete(0, 'end')
seq.clear()
# def seq_display():
# print(seq)
# print(f"The length of the sequence generated is: {len(seq)}")
######################################################
# Create main window
root = tk.Tk()
root.title("Collatz Sequence")
root.geometry("500x500")
style = ttk.Style("litera")
# Title
title_label = ttk.Label(root,
text = "Collatz Sequence Generator",
font = "Calibri 24",
foreground = "#4a7e9e")
title_label.pack(pady =10)
# Input
entry_frame = ttk.Frame(root)
entry_frame.pack()
entry_label = ttk.Label(entry_frame, text = "Enter a Number:",
font = "Calibri 16")
entry_label.pack(side = "left", padx = 30, pady = 30)
entry = ttk.Entry(entry_frame, width = 5)
entry.delete(0, 'end')
entry.focus_set()
entry.pack(side = "left", pady = 30)
entry_button = ttk.Button(entry_frame,text = "SUBMIT", command=lambda: [calc(), plot_sequence()])
entry_button.pack(side = "left", padx = 60, pady = 30)
clear_button = ttk.Button(root,text = "CLEAR", command=clear_graph)
clear_button.pack(side = "bottom", pady = 50)
root.mainloop()
一切正常,除了当我清除输入字段、序列列表和绘图并输入新数字时,绘图不会再次生成。我必须关闭该程序并再次打开它才能工作。我知道序列会再次计算并附加到新清空的序列列表 (seq[]) 中,但当我再次运行程序时,绘图仍为空。
昨天我真的花了一整天的时间试图找出我做错了什么。我在完美运行的示例上对“defclear_graph():”函数进行了建模,但在我的代码中,它根本不起作用。它清除了,但就像我说的,它不会根据新的数字输入绘制新的序列
如果有人可以帮助我,我将不胜感激。
安德烈
当我仅创建
Figure
和 Canvas
一次时,代码对我有用。
import tkinter as tk
from tkinter import ttk
#import ttkbootstrap as ttk
import matplotlib.pyplot as plt
from matplotlib.figure import Figure
from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg, NavigationToolbar2Tk)
# --- functions ---
def calc():
global num
#seq.clear()
num = int(entry.get())
while num > 2:
if num % 2 == 0:
num = num / 2
else:
num = 3 * num + 1
seq.append(int(num))
def plot_sequence():
global ax
global canvas
ax.clear()
ax.plot(seq, marker="o", linestyle="-")
ax.plot(seq)
canvas.draw()
def create_graph():
calc()
plot_sequence()
def clear_graph():
ax.clear()
canvas.draw()
entry.delete(0, "end")
seq.clear()
# def seq_display():
# print(seq)
# print(f"The length of the sequence generated is: {len(seq)}")
# --- main ---
seq = []
# Create main window
root = tk.Tk()
root.title("Collatz Sequence")
root.geometry("500x500")
#style = ttk.Style("litera")
# Title
title_label = ttk.Label(root,
text="Collatz Sequence Generator",
font="Calibri 24",
foreground="#4a7e9e")
title_label.pack(pady=10)
# Input
entry_frame = ttk.Frame(root)
entry_frame.pack()
entry_label = ttk.Label(entry_frame, text= "Enter a Number:", font="Calibri 16")
entry_label.pack(side="left", padx=30, pady=30)
entry = ttk.Entry(entry_frame, width=5)
#entry.delete(0, "end") # no need it at start
entry.focus_set()
entry.pack(side="left", pady=30)
entry_button = ttk.Button(entry_frame, text="SUBMIT", command=create_graph)
entry_button.pack(side="left", padx=60, pady=30)
clear_button = ttk.Button(root, text="CLEAR", command=clear_graph)
clear_button.pack(side="bottom", pady=50)
# Figure and Canvas
fig = Figure(facecolor="lightblue", edgecolor="blue")
ax = fig.add_subplot(111)
ax.set_xlabel("Iteration")
ax.set_ylabel("Value")
ax.set_title("Collatz Sequence")
canvas = FigureCanvasTkAgg(fig)
canvas.draw()
canvas.get_tk_widget().pack(side="top", fill="both", expand=1)
root.mainloop()