Tkinter单选按钮初始化错误

2024-10-05 14:24:32 发布

您现在位置:Python中文网/ 问答频道 /正文

如果我在函数中放置一个单选按钮并绘制它们;第一次绘制它们时,如果不使它们看起来都已选定,则不能将鼠标悬停在它们上面。

函数中的同一代码不会显示这种行为。

from Tkinter import *

def App(master):
    v = StringVar()
    v.set('python') # initialize
    lable1 = Label(master, text=' hovering over below radio buttons will cause them to look like they are selected')
    lable1.pack()
    runtimeFrame = Frame(master, relief=GROOVE,  borderwidth = 3)
    runtimeFrame.pack(fill = X, pady = 5, padx = 5)
    for mode in ['java', 'python', 'jython']:
        b = Radiobutton(runtimeFrame, text=mode, variable=v, value=mode, indicatoron = 1 )
        b.pack(side = LEFT)


if __name__ == '__main__':
    master = Tk()

    App(master)

    #The following code chunk is the same as that in App()
    #------------------------
    v = StringVar()
    v.set('python') # initialize
    lable1 = Label(master, text=' hovering over below radio buttons will cause them to Not look selected as expected')
    lable1.pack()
    runtimeFrame = Frame(master, relief=GROOVE,  borderwidth = 3)
    runtimeFrame.pack(fill = X, pady = 5, padx = 5)
    for mode in ['java', 'python', 'jython']:
        b = Radiobutton(runtimeFrame, text=mode, variable=v, value=mode, indicatoron = 1 )
        b.pack(side = LEFT)
    #------------------------

    mainloop() 

一旦你做出选择,这种情况就不会再发生了。 我做错什么了吗?是否有解决方法,因为我的代码必须在函数中!

这是我在Tkinter发现的第二个基本错误。有没有更好的Python GUI开发工具?

ps:我正在使用Python2.7


Tags: 函数代码textinmasterapptkintermode
3条回答

试试这个,对我有用。

v = 0  # this is global variable

def some_function():
    global v
    v = IntVar()
    v.set(0)


    rb1 = Radiobutton (parent, variable = v, value = 0)
    rb1.pack()
    rb2 = Radiobutton (parent, variable = v, value = 1)
    rb2.pack()

做你的单选按钮,然后你得到你的单选按钮,因为他们应该。

存储变量对象的位置(在您的例子中是StringVar,v)必须保持不变,这样就不会出现这种奇怪的行为。我猜我们看到这种行为是因为v,超出了范围,出了问题。除了使用全局函数外,我想不出从函数中执行此操作的方法。

断码:

from Tkinter import *

def App(master):
    v = StringVar()
    v.set('python')

    lable1 = Label(master, text=' hovering over below radio buttons will cause them to look like they are selected')
    lable1.pack()

    runtimeFrame = Frame(master, relief=GROOVE, borderwidth=3)
    runtimeFrame.pack(fill=X, pady=5, padx=5)
    for mode in ['java', 'python', 'jython']:
        b = Radiobutton(runtimeFrame, text=mode, variable=v, value=mode, indicatoron=1)
        b.pack(side=LEFT)

if __name__ == '__main__':
    master = Tk()
    App(master)
    mainloop()

示例修复:

from Tkinter import *

def App(master, radio_var):
    radio_var.set('python')

    lable1 = Label(master, text=' hovering over below radio buttons will cause them to look like they are selected')
    lable1.pack()

    runtimeFrame = Frame(master, relief=GROOVE, borderwidth=3)
    runtimeFrame.pack(fill=X, pady=5, padx=5)
    for mode in ['java', 'python', 'jython']:
        b = Radiobutton(runtimeFrame, text=mode, variable=radio_var, value=mode, indicatoron=1)
        b.pack(side=LEFT)

if __name__ == '__main__':
    master = Tk()
    radio_var = StringVar()
    App(master, radio_var)
    mainloop()

考虑一下,如果有多个变量需要持久化,那么可以传入一个变量列表或字典。

另外,为了防止“必须在函数中”是家庭作业要求,请考虑将代码包装到类中。我不是tk专家,但这似乎是组织代码的首选方式。

示例修复2:

    from Tkinter import *

class App(object):
    def __init__(self, master):
        self.radio_var = StringVar()
        self.radio_var.set('python')

        lable1 = Label(master, text=' hovering over below radio buttons will cause them to look like they are selected')
        lable1.pack()

        runtimeFrame = Frame(master, relief=GROOVE, borderwidth=3)
        runtimeFrame.pack(fill=X, pady=5, padx=5)
        for mode in ['java', 'python', 'jython']:
            b = Radiobutton(runtimeFrame, text=mode, variable=self.radio_var, value=mode, indicatoron=1)
            b.pack(side=LEFT)

if __name__ == '__main__':
    master = Tk()
    app = App(master)
    mainloop()

注意到

app = App(master)

这是必需的,这样应用程序实例就不会过早地被垃圾回收。这将有效地把self.radio_var拉出范围,我们回到原点。

我知道这已经过去了很多时间,但我已经尝试了这里展示的所有策略,但没有一个能与我一起工作。对我有效的是简单的“重写”鼠标运动事件的事件处理程序。这不是一个完美的解决方案,因为我在终端上打印了一些垃圾,但在我的特殊情况下,这不是一个问题。

server_name = IntVar()
server_name.set(1)
server_name_rb_1 = Radiobutton(container_3, text="Server", variable=server_name, value=1)
server_name_rb_1.select()
server_name_rb_1.pack()
server_name_rb_2 = Radiobutton(container_3, text="Local", variable=server_name, value=2)
server_name_rb_2.deselect()
server_name_rb_2.pack()

server_name_rb_2.bind('<Motion>',lambda e: print(str(server_name.get())) )

备注:你不需要重写所有函数,只要重写其中一个就足够了。

相关问题 更多 >