在Tkinter中获取单选框的值 - Python

2 投票
2 回答
12060 浏览
提问于 2025-04-16 20:39

我正在用Python的Tkinter模块创建一个图形用户界面(GUI),其中有两个单选框,让用户选择他们想要的选项。根据用户选择的框,程序会运行不同的函数,返回不同的结果。我想在窗口类外部使用这些结果,但我不知道怎么把类内部的值传到外部。我相信这应该很简单,但我就是搞不明白。

我现在的代码是:

class BatchIndiv():
def __init__(self, master):
    self.master=master
    self.startwindow()
    self.b=0

def startwindow(self):

    self.var1 = IntVar()
    self.textvar = StringVar()

    self.Label1=Label(self.master, text="Batch or indivdual import?")
    self.Label1.grid(row=0, column=0)

    self.Label2=Label(self.master, textvariable=self.textvar)
    self.Label2.grid(row=2, column=0)

    self.rb1 = Radiobutton(self.master, text="Batch", variable=self.var1,
                           value=1, command=self.cb1select)
    self.rb1.grid(row=1, column=0, sticky=W)

    self.rb2 = Radiobutton(self.master, text="Individual", variable=self.var1,
                           value=2, command=self.cb1select)
    self.rb2.grid(row=1, column=1, sticky=W)

    self.Button1=Button(self.master, text="ok", command=self.ButtonClick)
    self.Button1.grid(row=1, column=2)

def ButtonClick(self):
     if (self.var1.get())==1:
        b=BatchImport()
        return b
        self.master.quit()
        self.master.destroy()
     elif (self.var1.get())==2:
        b=IndivImport()
        return b
        self.master.quit()
        self.master.destroy()
     else: pass

def cb1select(self):
    return self.var1.get()

#End of class definition.
#Code:

root=Tk()
window=BatchIndiv(root)
b=BatchIndiv.ButtonClick.b
root.mainloop()

....

可以把BatchImport和IndivImport这两个函数当作黑箱,它们只返回一个整数值,我在ButtonClick()函数里把这个值赋给变量b。我需要这个值在root.mainloop()之后做一些事情(也就是……的地方),但我不知道怎么拿到它。Tkinter真的很让人烦恼,尤其是每个人的方法都不一样,网上的文档也总是不同。我试过按照各种文档上的写法去做,但结果只让我收到了更多的错误信息。

任何帮助都非常感谢。

PS - 我怎么才能在按下按钮时关闭窗口,同时把值b传回其他代码,而不是直接退出Python呢?如你所见,我试过用.quit()和.destroy(),但都没成功。

2 个回答

1

一般来说,在调用 mainloop 之后,你不应该再有任何代码,这就是图形界面程序的工作方式。

当用户按下按钮时,所有的操作应该在按钮的命令中进行(或者从那里开始)。如果你想让程序退出,你就销毁根窗口(这样会导致 mainloop 方法退出),然后你的程序就结束了。在 mainloop 之后不应该再运行其他东西。

...因此,如何将数据从按钮传递到 mainloop 之后的代码就变得不重要了。

所以,创建一个方法来完成你示例中 ... 的功能。在 ButtonClick 中调用这个方法,当你调用它时,可以传入你想要的任何来自图形界面的信息。

这样,ButtonClick 就变成了类似这样的内容:

def ButtonClick(self):
    if self.var1.get()==1:
        b=BatchImport()

    elif self.var1.get()==2:
        b=IndivImport()

    self.DotDotDot(b)
    self.master.quit()
2

你的变量 b 只是局限在你的类里面,所以当你删除这个类的时候(比如你执行了 destroyquit),b 就会被销毁。因此,你可以把变量 b 定义为全局变量。

b = 0                    # this is now in the global namespace

class BatchIndiv():
    def __init__(self, master):
        self.master=master
        self.startwindow()
        #self.b=0      # no need for this, directly store in the global variable

    def startwindow(self):

        self.var1 = IntVar()
        self.textvar = StringVar()

        self.Label1=Label(self.master, text="Batch or indivdual import?")
        self.Label1.grid(row=0, column=0)

        self.Label2=Label(self.master, textvariable=self.textvar)
        self.Label2.grid(row=2, column=0)

        self.rb1 = Radiobutton(self.master, text="Batch", variable=self.var1,
                               value=1, command=self.cb1select)
        self.rb1.grid(row=1, column=0, sticky=W)

        self.rb2 = Radiobutton(self.master, text="Individual", variable=self.var1,
                               value=2, command=self.cb1select)
        self.rb2.grid(row=1, column=1, sticky=W)

        self.Button1=Button(self.master, text="ok", command=self.ButtonClick)
        self.Button1.grid(row=1, column=2)

    def ButtonClick(self):
        global b
        if (self.var1.get())==1:
            b=BatchImport()
            self.master.quit()
            #self.master.destroy()    # either quit or destroy, I think one is sufficient, but confirm to be sure.
        elif (self.var1.get())==2:
            b=IndivImport()
            self.master.quit()
            #self.master.destroy()    # either quit or destroy, I think one is sufficient, but confirm to be sure
         else: pass

    def cb1select(self):
        return self.var1.get()

#End of class definition.
#Code:

root=Tk()
window=BatchIndiv(root)
root.mainloop()

# now do here whatever you want to do with the variable b
print b

(使用全局变量并不是个好主意,但因为我不知道你想用 b 做什么,所以没法给你其他建议。)

撰写回答