首页 > 解决方案 > Tkinter 应用程序返回随机值

问题描述

我使用 Tkinter 制作了一个 Python 应用程序来进行电磁学作业。它是一个 3 维向量的幅度计算器。

编码:

from tkinter import *

root = Tk()

root.title("Calculator")

coordinates = []

n=0

X = Entry(root)
X.insert(END, "Enter the x-coordinate")
X.grid(row=0, column=0, columnspan=3, padx=12, pady=15)

Y = Entry(root)
Y.insert(END, "Enter the y-coordinate")
Y.grid(row=1, column=0, columnspan=3, padx=12, pady=15)

Z = Entry(root)
Z.insert(END, "Enter the z-coordinate")
Z.grid(row=2, column=0, columnspan=3, padx=12, pady=15)

def x():
    global n
    n=1
    
def y():
    global n
    n=2
    
def z():
    global n
    n=3
    
def S(m):
    if n == 1:
        a = X.get()
        X.delete(0,END)
        X.insert(0,str(a)+str(m))
        coordinates.append(X)
    if n == 2:
        b = Y.get()
        Y.delete(0,END)
        Y.insert(0,str(b)+str(m))
        coordinates.append(Y)
    if n == 3:
        c = Z.get()
        Z.delete(0,END)
        Z.insert(0,str(c)+str(m))
        coordinates.append(Z)
        
def clear():
    X.delete(0,END)
    Y.delete(0,END)
    Z.delete(0,END)
    
def equal():
    sq = 0
    for d in coordinates:
        e = float(d.get())
        sq = sq + e**2 
    mag = sq**0.5
    val = Label(root, text="The magnitude of the vector is: " + str(mag))
    val.grid(row=3, column=0, columnspan=3, padx=12, pady=15)
    
b1 = Button(root, text="1", padx=30, pady=15, command=lambda: S("1"))
b2 = Button(root, text="2", padx=30, pady=15, command=lambda: S("2"))
b3 = Button(root, text="3", padx=30, pady=15, command=lambda: S("3"))
b4 = Button(root, text="4", padx=30, pady=15, command=lambda: S("4"))
b5 = Button(root, text="5", padx=30, pady=15, command=lambda: S("5"))
b6 = Button(root, text="6", padx=30, pady=15, command=lambda: S("6"))
b7 = Button(root, text="7", padx=30, pady=15, command=lambda: S("7"))
b8 = Button(root, text="8", padx=30, pady=15, command=lambda: S("8"))
b9 = Button(root, text="9", padx=30, pady=15, command=lambda: S("9"))
b0 = Button(root, text="0", padx=30, pady=15, command=lambda: S("0"))
bx = Button(root, text="x", padx=30, pady=15, command=x)
by = Button(root, text="y", padx=30, pady=15, command=y)
bz = Button(root, text="z", padx=30, pady=15, command=z)
bclear = Button(root, text="Clear", padx=19, pady=15, command=clear)
bequal = Button(root, text="=", padx=29, pady=15, command=equal)

b1.grid(row=6, column=0)
b2.grid(row=6, column=1)
b3.grid(row=6, column=2)
b4.grid(row=5, column=0)
b5.grid(row=5, column=1)
b6.grid(row=5, column=2)
b7.grid(row=4, column=0)
b8.grid(row=4, column=1)
b9.grid(row=4, column=2)
b0.grid(row=7, column=1)
bx.grid(row=8, column=0)
by.grid(row=8, column=1)
bz.grid(row=8, column=2)
bclear.grid(row=7, column=2)
bequal.grid(row=7, column=0)

root.mainloop()

似乎只有一个问题:

当用户为其中一个输入输入大于 10 的值时,输出似乎大于实际值。它仅适用于非常小的输入,例如,如果输入的数字是 3、4、5。

标签: pythonlisttkinter

解决方案


这是一个摆脱数字按钮的矢量计算器的简单示例,并且:

  • 将矢量计算与 GUI 分开。这class Vector是可以在有或没有 GUI 的情况下使用的“模型”。
  • 将 GUI 的各种组件隔离在它们自己的可重用类中:这里一个类用于输入字段,一个用于输出。

您可以使用此骨架作为基础来添加更多操作,并改进使用以使其能够以更流畅的方式链接操作。

import tkinter as tk


class Vector:
    def __init__(self, x, y, z):
        self.x = x
        self.y = y
        self.z = z
    def __add__(self, other):
        return Vector(self.x + other.x, self.y + other.y, self.z + other.z)
    def dot(self, other):
        return sum(s*o for s, o in zip(self, other))
    def mag(self):
        return self.dot(self)**.5
    def __iter__(self):
        for elt in self.x, self.y, self.z:
            yield elt
    def __str__(self):
        return f'Vector({self.x}, {self.y}, {self.z})'

    
class VecEntry(tk.Frame):
    def __init__(self, master):
        self.master = master
        super().__init__(master)
        tk.Label(self, text='x coord').grid(column=0, row=0)
        self.x_entry = tk.Entry(self)
        self.x_entry.grid(column=1, row=0)
        
        tk.Label(self, text='y coord').grid(column=0, row=1)
        self.y_entry = tk.Entry(self)
        self.y_entry.grid(column=1, row=1)
        
        tk.Label(self, text='z coord').grid(column=0, row=2)
        self.z_entry = tk.Entry(self)
        self.z_entry.grid(column=1, row=2)
        
    def get_coords(self):
        x = float(self.x_entry.get())
        y = float(self.y_entry.get())
        z = float(self.z_entry.get())
        return x, y, z

    
class VecOut(tk.Frame):
    def __init__(self, master, vector):
        self.master = master
        super().__init__(master)
        self.vector = vector
        
        tk.Label(self, text='x coord').grid(column=0, row=0)
        tk.Label(self, text=str(self.vector.x)).grid(column=1, row=0)

        tk.Label(self, text='y coord').grid(column=0, row=1)
        tk.Label(self, text=str(self.vector.y)).grid(column=1, row=1)
   
        tk.Label(self, text='z coord').grid(column=0, row=2)
        tk.Label(self, text=str(self.vector.z)).grid(column=1, row=2)
        
        tk.Label(self, text='mag: ').grid(column=0, row=3)
        tk.Label(self, text=str(self.vector.mag())).grid(column=1, row=3)
                
        
class VectorCalc(tk.Tk):
    def __init__(self):
        super().__init__()
        self.vecentry_1 = VecEntry(self)
        self.vecentry_1.pack(anchor=tk.NE)
        self.vecentry_2 = VecEntry(self)
        self.vecentry_2.pack(anchor=tk.NE)
        self.add = tk.Button(self, text='+', command=self.add_vectors)
        self.add.pack(side=tk.RIGHT)
        self.vecout = None
        
    def add_vectors(self):
        v0 = Vector(*self.vecentry_1.get_coords())
        v1 = Vector(*self.vecentry_2.get_coords())
        result = v0 + v1
        print(f'{v0} + {v1} = {result}')
        print(f'the magnitude of the resultant vector is: {result.mag()}')
        self.vecout = VecOut(self, result)
        self.vecout.pack()
        
        
        
VectorCalc().mainloop()

控制台输出:

Vector(4.0, 4.0, 4.0) + Vector(5.0, 5.0, 5.0) = Vector(9.0, 9.0, 9.0)
the magnitude of the resultant vector is: 15.588457268119896

图形界面方面:

在此处输入图像描述


推荐阅读