Python3.6 : Trying to avoid using a global for my swap function with tkinter

标签 python python-3.x tkinter global-variables local-variables

我只编程了 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()

对上面代码的一个小注释:添加前缀__变量或方法允许您使用 the name mangling. 在类外部直接通过名称隐藏对它们的访问

UPD:根据 @Coal comment ,将双下划线前缀更改为单下划线,因为不需要使用名称修改。

关于Python3.6 : Trying to avoid using a global for my swap function with tkinter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47247867/

相关文章:

python - 从 python 3 中的 fetchone() 调用中检索值

python - print(input() + input()) 在 python 中如何工作?没有变量赋值?

python - 通过函数传递变量/列表

python - 为什么 __instancecheck__ 并不总是根据参数调用?

python - 如何获取选中的单选按钮的值?

python - 根据另一个类的字段动态获取字段类型(使用 Scapy 工具 - Python)

python - nopython 模式下 Numba 递归函数出错

python - 具有 1 个和 2 个可迭代元素的列表的字典理解

python - 我正在尝试使用变量更新 tkinter 标签,但标签只是显示为空白

Python列表弹出