【问题标题】:What is the problem with my code run on Tkinter?我的代码在 Tkinter 上运行有什么问题?
【发布时间】:2019-08-29 19:19:54
【问题描述】:

我是 Python 的 Tkinter 的新手,我想创建一个在其上运行的程序。但是,我的代码无法正常工作。

from tkinter import *

def conv1(self):
    gbp0 = 174000000
    galleons0 = 34000872
    sickles0 = 14
    knuts0 = 7

    galleons1 = float(galleons0 + sickles0 / 17 + knuts0 / 29 / 17)
    fracture = float(gbp0 / galleons1)
    convert1 = Toplevel(root)
    convert1.title("Pounds Sterling (GBP) to Galleons, Sickles and Knuts Converter")

    label1_1 = Label(convert1, text="Type the amount of money in GBP that you would like to convert to Galleons, Sickles and Knuts and press Enter.")
    label1_2 = Label(convert1, text="1 Galleon = 5.12 GBP")
    label1_3 = Label(convert1, text='GBP:')

    label1_1.pack()
    label1_2.pack()
    label1_3.pack()

    usergbpvar = DoubleVar()
    usergbp = Entry(convert1, textvariable=usergbpvar)
    usergbp.pack()

    a = float(usergbpvar.get() / fracture)

    galleons = int(a // 1)
    a = (a % 1) * 17

    sickles = int(a // 1)
    a = (a % 1) * 29

    if (a % 1) == 0.5:
        knuts = int(round(a, 0))
        knuts += 1
    else:
        knuts = int(round(a, 0))

    galleons, sickles, knuts = str(galleons), str(sickles), str(knuts)

    label1_4 = Label(convert1, text=galleons)
    label1_5 = Label(convert1, text=sickles)
    label1_6 = Label(convert1, text=knuts)

    label1_4.pack()
    label1_5.pack()
    label1_6.pack()

    convert1.mainloop()

root = Tk()
btn1 = Button(root, text='GBP to Galleons, Sickles and Knuts', bg='#555', fg='#ccc', font='16')
btn1.pack()
btn1.bind('<Button-1>', conv1)
root.mainloop()

它应该从输入的数字中计算出三个数字,并将它们显示在屏幕上。但是,当我运行程序时,按下按钮后,我看到所有数字都已经存在并且它们是 0。输入我的数字后,什么都没有改变。

您能告诉我代码中的问题出在哪里吗?

【问题讨论】:

  • 您创建了一个条目,然后立即在其上调用.get()。当然这返回零,用户什么时候有机会输入任何内容?您需要在顶级代码中创建条目,以便用户可以在单击按钮之前输入。

标签: python python-3.x tkinter


【解决方案1】:

问题/问题 1:

当我运行程序时,按下按钮后,我看到所有 数字已经存在,它们是 0。

当你打电话时 label1_4=Label(convert1, text=galleons) label1_4.pack() 这告诉 tkinter 立即使用给定值显示标签,例如label1_4 的 Galleons 为 0(其他标签相同)。这不是问题,是正常的,因为输入框的值一开始就是 0。

问题/问题 2:

输入我的号码后,什么都没有改变。

您实际上并没有告诉程序更新标签的值。正如TornaxO7所说,需要绑定回车(return)键才能调用函数usergbp.bind("&lt;Return&gt;", calculation_function_here)

我已编辑您的代码以提供面向对象的方法。我建议随着您的进步探索这种方法,并且可能需要多个窗口。 Best way to structure a tkinter application?

from tkinter import *

class gui_window:

    def __init__(self, master):
        # setup gui
        self.master = master 
        self.master.wait_visibility() # attempt to fix traceback error, see Problem/question 3 below

        self.master.grab_set() # stops button1 creating another gui_window instance
        self.master.title('Pounds Sterling (GBP) to Galleons, Sickles and Knuts Converter')

        self.label1_1=Label(master, text="Type the amount of money in GBP that you would like to convert to Galleons, Sickles and Knuts and press Enter.")
        self.label1_1.pack()

        self.label1_2=Label(master, text="1 Galleon = 5.12 GBP")
        self.label1_2.pack()

        self.label1_3=Label(master, text='GBP:')
        self.label1_3.pack()

        self.usergbpvar=DoubleVar()
        self.usergbp=Entry(master, textvariable=self.usergbpvar)
        self.usergbp.bind("<Return>", self.calculate) # when user presses enter call the conversion function
        self.usergbp.pack()

        label1_4_1 = Label(self.master, text = 'Galleons:').pack(anchor = 'w')
        self.label1_4=Label(self.master, text='0', anchor = 'e')
        self.label1_4.pack()

        label1_5_1 = Label(self.master, text = 'Sickles:').pack(anchor = 'w')
        self.label1_5=Label(self.master, text='0', anchor = 'e')
        self.label1_5.pack()

        label1_6_1 = Label(self.master, text = 'Knuts:').pack(anchor = 'w')
        self.label1_6=Label(self.master, text='0')
        self.label1_6.pack()


        self.gbp0=174000000
        self.galleons0=34000872
        self.sickles0=14
        self.knuts0=7
        self.galleons1=float(self.galleons0+self.sickles0/17+self.knuts0/29/17)
        self.fracture=float(self.gbp0/self.galleons1)

    def calculate(self, event):
        # do calculation
        a=float(self.usergbpvar.get()/self.fracture)
        galleons=int(a//1)
        a=a%1
        a=a*17
        sickles=int(a//1)
        a=a%1
        a=a*29
        if a%1==0.5:
            knuts=int(round(a, 0))
            knuts=knuts+1
        else:
            knuts=int(round(a, 0))
        galleons=str(galleons)
        sickles=str(sickles)
        knuts=str(knuts)

        # update the labels to reflect the calculation
        self.label1_4.config(text=galleons)
        self.label1_5.config(text=sickles)
        self.label1_6.config(text=knuts)



def create_gui(self):
    # create a gui_window Toplevel instance 
    convert1=Toplevel() 
    gui_window(convert1)

root=Tk()
btn1=Button(root, text='GBP to Galleons, Sickles and Knuts', bg='#555', fg='#ccc', font='16')
btn1.pack()
btn1.bind('<Button-1>', create_gui) # call function to make next window
root.mainloop()

来自 cmets 的问题/问题 3: 我相信错误:tkinter.TclError: grab failed: window not viewable 取决于您的操作系统。我无法在 Mac OS 上重现该错误,但添加 self.master.wait_visibility()(添加到我的代码中)可能会解决此问题: python tkinter treeview not allowing modal window with direct binding like on_rightclick

【讨论】:

  • 非常感谢!你的回答真的很有帮助!但现在我收到了一个 Traceback:
  • Tkinter 回调 Traceback 中的异常(最近一次调用最后一次):文件“/usr/lib/python3.5/tkinter/__init__.py”,第 1553 行,在 call return self.func(*args) File "/home/Michael/Python/test3.py", line 53, in create_gui gui_window(convert1) File "/home/Michael/Python/test3.py", line 5, in init self.master.grab_set() 文件“/usr/lib/python3.5/tkinter/__init__.py”,第 688 行,grab_set self.tk.call('grab', 'set' , self._w) _tkinter.TclError: 抓取失败: 窗口不可见
  • 多么奇怪,我怀疑这是一个依赖于操作系统的问题(我正在运行 MacOS Mojave)。最简单的就是去掉self.master.grab_set()
  • 谢谢!现在代码完美运行。我也认为问题可能出在操作系统上。现在我使用的是 Ubuntu (Linux),而通常我使用的是 Windows。再次感谢您的帮助!
【解决方案2】:

我猜你忘了绑定Return-key。
你应该在你的方法中添加convert1.bind("&lt;Return&gt;", *your function*)
“你的函数”是改变数字的函数。

【讨论】:

    猜你喜欢
    • 2018-06-22
    • 1970-01-01
    • 1970-01-01
    • 2021-03-18
    • 2020-12-10
    • 1970-01-01
    • 2011-07-28
    相关资源
    最近更新 更多