Python3.6 :试图避免使用全局作为我与tkinter的交换函数



我只编程了 3 个月,所以任何关于改进我的代码的建议都值得赞赏,即使它与我的特定问题有关。

这是一个带有tkinter的简单小项目。两个字段输入您的名字和姓氏,然后点击交换按钮,它将交换您在名称字段中输入的内容。问题是我不想使用全局变量,而且我似乎无法弄清楚,我知道这可能很容易,我确实花时间试图弄清楚。如果您对代码有任何改进,请告诉我。

from tkinter import *
### I dont Want Globals but cant figure out another method for doing this
### Hope some one can help me with this part
evar = ""
evar1 = ""

def mainWindow():
    root = Tk()
    root.title("Swap Names")
    root.geometry("400x150+100+250")
    return root
def createVar():
        global evar
        global evar1
        evar = StringVar()
        evar1 = StringVar()
def firstNameFrame(root):
    frame1 = Frame(root)
    frame1.pack(side=TOP, padx=2, pady=2)
    label = Label(frame1, text="First Name:")
    label.pack(side=LEFT, padx=2, pady=2)
    entry = Entry(frame1, textvariable = evar)
    entry.pack(side=LEFT, pady = 2)
def lastNameFrame(root):
    frame2 = Frame(root)
    frame2.pack(side=TOP, padx=2, pady=2)
    label = Label(frame2, text="Last Name:")
    label.pack(side=LEFT, padx=1, pady=1)
    entry = Entry(frame2, textvariable = evar1)
    entry.pack(side=LEFT, pady = 5)
def swapFrame(root):
    frame3 = Frame(root)
    frame3.pack(side=TOP, padx=10, pady = 10)
    swapButton = Button(frame3, text="Swap",command = swap)
    swapButton.pack(side=LEFT, padx =5, pady=5)
### I would like to some how use swap with out using a global 
def swap():
    b=evar.get()
    evar.set(evar1.get())
    evar1.set(b)

def main():
    root = mainWindow()
    createVar()
    firstNameFrame(root)
    lastNameFrame(root)
    swapFrame(root)
    root.mainloop()

main()

其中一个解决方案可以是将与初始化相关的所有代码包装在一起,并在一个单独的类中使用 Tk,因此我们将使用类实例变量,而不是全局变量:

from tkinter import *

class Gui(object):
    def __init__(self):
        self.root = Gui._init_main_window()
        self.first_name_var = StringVar()
        self.last_name_var = StringVar()
        self._init_first_name_frame()
        self._init_last_name_frame()
        self._init_swap_frame()
    @staticmethod
    def _init_main_window():
        root = Tk()
        root.title("Swap Names")
        root.geometry("400x150+100+250")
        return root
    def _init_first_name_frame(self):
        frame1 = Frame(self.root)
        frame1.pack(side=TOP, padx=2, pady=2)
        label = Label(frame1, text="First Name:")
        label.pack(side=LEFT, padx=2, pady=2)
        entry = Entry(frame1, textvariable=self.first_name_var)
        entry.pack(side=LEFT, pady=2)
    def _init_last_name_frame(self):
        frame2 = Frame(self.root)
        frame2.pack(side=TOP, padx=2, pady=2)
        label = Label(frame2, text="Last Name:")
        label.pack(side=LEFT, padx=1, pady=1)
        entry = Entry(frame2, textvariable=self.last_name_var)
        entry.pack(side=LEFT, pady=5)
    def _init_swap_frame(self):
        frame3 = Frame(self.root)
        frame3.pack(side=TOP, padx=10, pady=10)
        swap_button = Button(frame3, text="Swap", command=self._swap)
        swap_button.pack(side=LEFT, padx=5, pady=5)
    def _swap(self):
        tmp = self.first_name_var.get()
        self.first_name_var.set(self.last_name_var.get())
        self.last_name_var.set(tmp)
    def mainloop(self):
        return self.root.mainloop()

def main():
    gui = Gui()
    gui.mainloop()

if __name__ == '__main__':
    main()

对上面代码的一个小注释:向变量或方法添加前缀__允许您使用名称重整直接在类外部按名称隐藏对它们的访问。

UPD:根据@Coal评论,将双下划线前缀更改为单下划线,因为无需使用名称重整。

这是

假设当你说你不想使用global时,你也意味着你不想使用self

from tkinter import Tk, Button, Entry
def swap(fn, ln):
    # Get the contents of the two fields.
    first = fn.get()
    last = ln.get()
    # Clear the contents of both fields.
    first_name.delete(0, 'end')
    last_name.delete(0, 'end')
    # Set each field to the previous content of the other field.
    first_name.insert(0, last)
    last_name.insert(0, first)

root = Tk()
first_name = Entry(root)
last_name = Entry(root)
first_name.insert(0, "Enter first name")
last_name.insert(0, "Enter last name")
first_name.pack()
last_name.pack()
swap_button = Button(root, text="SWAP", command=lambda:swap(first_name, last_name))
swap_button.pack()

root.mainloop()

最新更新