全局变量及其在其他顶层函数中的使用

1 投票
1 回答
610 浏览
提问于 2025-04-18 17:38

我正在尝试为一个小程序创建一个“管理员”部分,这个程序可以执行一些数学运算。

在主窗口的管理员按钮点击后,会弹出一个新窗口,这个窗口里有一个输入框,只有当正确的密码输入到密码框里时,这个输入框才会启用(或者说等我弄明白怎么做的时候,它就会这样)。

提交按钮的目的是更新一个全局变量,这个变量代表一个价格,程序会记住这个价格,用户可以在输入框里输入新的价格。我的问题是,如何让这个全局变量在按下按钮后更新、改变,并且保持这个改变。

这段代码只是用来测试能否做到这一点,但为了提供一些背景,我还是把它贴在这里。任何帮助我实现这个目标的建议都非常欢迎。

问题是这段代码不工作,它不让我改变全局变量,并且出现了错误,提示变量int没有append这个属性?

进一步说,使用append是个错误,没问题,我的问题是global12mmprice = 200并没有更新全局变量,在程序的其他地方仍然引用的是原来的值。有没有办法完全更新全局变量,让程序反映新的值,而旧的值不再存在?

global12mmprice = 86.67
global15mmprice = 191.19
int12mmprice = int(global12mmprice)
int15mmprice = int(global15mmprice)


class mainwindow(tk.Frame):
    def __init__(self, root):
        tk.Frame.__init__(self, root)
        b1 = tk.Button(self, text="Glass Table", command = self.glsqWindow)
        b1.grid(column=1,row=2,pady=50,padx=10)
        self.count = 0
        b2 = tk.Button(self, text='Round Table', command = self.glrnWindow)
        b2.grid(column=2,row=2,pady=50,padx=10)
        self.count = 0
        b3 = tk.Button(self, text='Console Table', command = self.glcnWindow)
        b3.grid(column=3,row=2,pady=50,padx=10)
        self.count = 0
        b4 = tk.Button(self, text='Admin', command = self.admin)
        b4.grid(column=4,row=2,pady=50,padx=10)
        self.count = 0


    def admin(self):       
        self.count += 1
        window = tk.Toplevel(self)
        window.geometry("600x350+300+300")

        def submit():
            int12mmprice.append(200)


        b1 = tk.Button(window,text='Submit', command=submit)
        b1.grid(column=3,row=2,pady=50,padx=10)

后面还有很多代码,但这部分是相关的。此外,任何你可能有的建议当然也欢迎。

答案:在“fdhsdrg”的帮助下,我实现了这个解决方案,以便为将来有类似问题的人提供参考。

正如我所了解到的,我需要创建一个程序可以读写的文件,这样程序就能在需要时访问和修改必要的信息。

import tkinter as tk
from tkinter import *
from tkinter import Tk, Frame, Menu
import tkinter.messagebox as box
import pickle, os

file=open('prices.dat','rb')
data=pickle.load(file)
file.close
global12mmprice = data[0]
global15mmprice = data[1]

class mainwindow(tk.Frame):
    def __init__(self, root):
        tk.Frame.__init__(self, root)
        b1 = tk.Button(self, text="Glass Table", command = self.glsqWindow)
        b1.grid(column=1,row=2,pady=50,padx=10)
        self.count = 0
        b2 = tk.Button(self, text='Round Table', command = self.glrnWindow)
        b2.grid(column=2,row=2,pady=50,padx=10)
        self.count = 0
        b3 = tk.Button(self, text='Console Table', command = self.glcnWindow)
        b3.grid(column=3,row=2,pady=50,padx=10)
        self.count = 0
        b4 = tk.Button(self, text='Admin', command = self.admin)
        b4.grid(column=4,row=2,pady=50,padx=10)
        self.count = 0


    def admin(self):       
        self.count += 1
        window = tk.Toplevel(self)
        window.geometry("600x350+300+300")



        def submit():
            global data
            data[0] = '86.67'
            file=open('prices.dat','wb')
            pickle.dump(data,file)
            file.close        
            global root
            box.showinfo('Administration','The program will now terminate and the prices                   will be updated.')
            root.destroy()
        b1 = tk.Button(window,text='Submit', command=submit)
        b1.grid(column=3,row=2,pady=50,padx=10)

如你所见,.dat文件中的数据列表会被更新,稍后我会用get.entry()字段替换这个,但现在这展示了预期的设计。如果你希望程序在关闭后自动重新启动,可能要考虑使用resetboard而不是destroy。

1 个回答

2

嗯,你添加的错误信息基本上解释了所有问题。int12mmprice是一个整数类型,它没有append这个方法。append是一个可以在列表类型的对象上使用的方法:

>>> a=9
>>> type(a)
<type 'int'>
>>> a.append(15)
Traceback (most recent call last):
  File "<pyshell#1>", line 1, in <module>
    a.append(15)
AttributeError: 'int' object has no attribute 'append'

>>> a=[9]
>>> type(a)
<type 'list'>
>>> a.append(15)
>>> a
[9, 15]

编辑:

对了,现在我们来看看作用域的问题。要想在全局范围内编辑int12mmprice,你需要在submit函数的开头加上global int12mmprice。这样可以确保submit函数不会在自己的作用域里查找int12mmprice,而是去全局范围内查找。

撰写回答