我正在 tkinter 中撰寫代碼以獲得網格圖。要運行代碼,您可以輸入5fornx和ny輸入框,然后打開一個包含25數字的文本檔案,例如:1 3 5 6 1 0 3 5 6 4 2 4 7 3 0 9 8 3 1 3 5 7 8 8 1,然后按Plot,生成網格圖。通過移動滑塊并Plot再次按下,軸范圍會發生變化。
但是,有一個問題,我已經輸入max_val=5了滑塊。我想從輸入欄位中獲取此值,例如:max_val=data.nx.get()。但是當程式運行時,我的輸入欄位最初是zero,它會引發錯誤。在輸入框中輸入值后,有沒有辦法通過滑塊小部件的執行?
import tkinter as tk
from tkinter import *
from tkinter import filedialog
import numpy as np
import matplotlib
matplotlib.use('TkAgg')
from matplotlib.figure import Figure
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib import cm
from matplotlib.colors import ListedColormap
from RangeSlider.RangeSlider import RangeSliderH, RangeSliderV
global nums
class Data:
def __init__(self):
self.nx = tk.IntVar()
self.ny = tk.IntVar()
class SampleApp(tk.Tk):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
container = tk.Frame(self)
container.pack()
self.data = Data()
self.frames = {}
for F in (PageOne, PageTwo):
frame = F(container, self.data)
self.frames[F] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.frames[PageOne].button3_P1.config(command=self.go_to_page_two)
self.show_frame(PageOne)
def go_to_page_two(self):
self.show_frame(PageTwo)
def show_frame(self, c):
frame = self.frames[c]
frame.tkraise()
class PageOne(tk.Frame):
def __init__(self, parent, data):
super().__init__(parent)
self.data = data
frame_1 = tk.LabelFrame(self, text="Inputs", labelanchor='n', height=400, width=280)
frame_1.grid(row=0, column=0, padx=5, sticky='n')
label_1 = tk.Label(frame_1, text="nx:")
label_1.grid(row=0, column=0)
self.entry_1 = tk.Entry(frame_1, textvariable=data.nx, width=7)
self.entry_1.grid(row=0, column=1)
label_2 = tk.Label(frame_1, text="ny:")
label_2.grid(row=1, column=0)
self.entry_2 = tk.Entry(frame_1, textvariable=data.ny, width=7)
self.entry_2.grid(row=1, column=1, padx= 10, pady=10)
global nums
def opentext():
global nums
my_file = filedialog.askopenfilenames(initialdir="/pycharm", title="Select your file")
for T in my_file:
import re
with open(T, 'r') as infile1:
lines = infile1.readlines()
B = [x for x in lines if not x.startswith('--')]
C = " ".join(B)
nums = []
for n in re.findall(r'\d ', C):
split_by_ast = n.split("*")
if len(split_by_ast) == 1:
nums = [float(split_by_ast[0])]
else:
nums = [float(split_by_ast[1])] * int(split_by_ast[0])
self.button1 = tk.Button(frame_1, text="Open file", command=opentext, width=10)
self.button1.grid(row=2, column=0, pady=10, columnspan=2)
frame_2 = tk.LabelFrame(self, text="Convas", labelanchor='n', height=550, width=800)
frame_2.grid(row=0, column=1, padx=5)
frame_2.grid_propagate(0)
def plot_init():
global H, V
x, y = np.mgrid[slice(0, 6, 1), slice(0, 6, 1)]
z = np.reshape(nums, (5, 5), order='F')
figure = Figure(figsize=(7.3, 4.8))
ax = figure.add_subplot(111)
col_type = cm.get_cmap('rainbow', 256)
newcolors = col_type(np.linspace(0, 1, 1000))
white = np.array([1, 1, 1, 1])
newcolors[:1, :] = white
newcmp = ListedColormap(newcolors)
c = ax.pcolormesh(x, y, z, cmap=newcmp, edgecolor='lightgrey', linewidth=0.003)
ax.figure.colorbar(c)
ax.set_title('Title', fontweight="bold")
ax.set_xlabel("X", fontsize=14)
ax.set_ylabel("Y", fontsize=14)
canvas = FigureCanvasTkAgg(figure, frame_2)
canvas.get_tk_widget().place(x=80, y=0)
figure.patch.set_facecolor('#f0f0f0')
ax.set_xlim(rs1.getValues())
ax.set_ylim(rs2.getValues())
rs1.place(x=150, y=470)
rs2.place(x=0, y=50)
hVar1 = IntVar() # left handle variable
hVar2 = IntVar() # right handle variable
rs1 = RangeSliderH(frame_2, [hVar1, hVar2], Width=500, Height=55, padX=17, min_val=0, max_val=5, font_size=12,
show_value=True, digit_precision='.0f', bgColor='#f0f0f0', line_s_color='black',
line_color='black', bar_color_inner='black', bar_color_outer='#f0f0f0')
vVar1 = IntVar() # top handle variable
vVar2 = IntVar() # down handle variable
rs2 = RangeSliderV(frame_2, [vVar1, vVar2], Width=81, Height=390, padY=11, min_val=0, max_val=5, font_size=12,
show_value=True, digit_precision='.0f', bgColor='#f0f0f0', line_s_color='black',
line_color='black', bar_color_inner='black', bar_color_outer='#f0f0f0')
self.button2 = tk.Button(frame_1, text="Plot", command=plot_init, width=10)
self.button2.grid(row=3, column=0, columnspan=2)
self.button3_P1 = tk.Button(self, text="Continue")
self.button3_P1.grid(row=2, column=0, columnspan=4, pady=5)
class PageTwo(tk.Frame):
def __init__(self, parent, data):
super().__init__(parent)
self.data = data
app = SampleApp()
app.mainloop()
目前,我收到此錯誤。
Traceback (most recent call last):
File "C:\Users\pymnb\Desktop\pycharm\Test.py", line 145, in <module>
app = SampleApp()
File "C:\Users\pymnb\Desktop\pycharm\Test.py", line 30, in __init__
frame = F(container, self.data)
File "C:\Users\pymnb\Desktop\pycharm\Test.py", line 122, in __init__
rs1 = RangeSliderH(frame_2, [hVar1, hVar2], Width=500, Height=55, padX=17, min_val=0, max_val=data.nx.get(), font_size=12,
File "C:\Users\pymnb\AppData\Local\Programs\Python\Python39\lib\site-packages\RangeSlider\RangeSlider.py", line 107, in __init__
pos = (value-min_val)/(max_val-min_val)
ZeroDivisionError: division by zero
uj5u.com熱心網友回復:
假設input file和是nx強制性ny輸入。在將它們傳遞給繪圖函式之前,您應該檢查它的正確值。
如果nxandny等于 0 是非法的,你必須檢查它是否大于 0,然后檢查用戶是否選擇了input file。
您應該在您的代碼中進行三處更改:
- 將您的滑塊代碼移動到
plot_init方法內并僅繪制一次 - 啟動變數
numstoNone,以檢查是否input file選擇了可能 - 檢查所有強制值并在不滿足條件時顯示錯誤訊息
此外,您可以將資料初始化為不同于 0 的默認值:
class Data:
def __init__(self):
self.nx = tk.IntVar(value=1)
self.ny = tk.IntVar(value=1)
這是之前的修改plot_init方法nums = None。
nums = None
self.rs1, self.rs2 = None, None
def plot_init():
global H, V, nums
x_max = data.nx.get()
y_max = data.ny.get()
if x_max == 0 or y_max == 0:
tk.messagebox.showerror(title="Entry Error", message="Check Your input, nx > 0 and ny > 0!")
return
if nums is None:
tk.messagebox.showerror(title="Entry Error", message="Check Your input, no file was opened!")
return
x, y = np.mgrid[slice(0, 6, 1), slice(0, 6, 1)]
z = np.reshape(nums, (5, 5), order='F')
figure = Figure(figsize=(7.3, 4.8))
ax = figure.add_subplot(111)
col_type = cm.get_cmap('rainbow', 256)
newcolors = col_type(np.linspace(0, 1, 1000))
white = np.array([1, 1, 1, 1])
newcolors[:1, :] = white
newcmp = ListedColormap(newcolors)
c = ax.pcolormesh(x, y, z, cmap=newcmp, edgecolor='lightgrey', linewidth=0.003)
ax.figure.colorbar(c)
ax.set_title('Title', fontweight="bold")
ax.set_xlabel("X", fontsize=14)
ax.set_ylabel("Y", fontsize=14)
canvas = FigureCanvasTkAgg(figure, frame_2)
canvas.get_tk_widget().place(x=80, y=0)
figure.patch.set_facecolor('#f0f0f0')
if self.rs1 is None:
self.rs1 = RangeSliderH(frame_2, [IntVar(), IntVar()], Width=500, Height=55, padX=17, min_val=0, max_val=data.nx.get(),
font_size=12,
show_value=True, digit_precision='.0f', bgColor='#f0f0f0', line_s_color='black',
line_color='black', bar_color_inner='black', bar_color_outer='#f0f0f0')
self.rs1.place(x=150, y=470)
if self.rs2 is None:
self.rs2 = RangeSliderV(frame_2, [IntVar(), IntVar()], Width=81, Height=390, padY=11, min_val=0, max_val=data.ny.get(),
font_size=12,
show_value=True, digit_precision='.0f', bgColor='#f0f0f0', line_s_color='black',
line_color='black', bar_color_inner='black', bar_color_outer='#f0f0f0')
self.rs2.place(x=0, y=50)
ax.set_xlim(self.rs1.getValues())
ax.set_ylim(self.rs2.getValues())
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/436166.html
上一篇:如何將GUI匯入python腳本
