Tkinter是否为每个单选按钮返回相同的值?

时间:2019-11-15 07:56:15

标签: python tkinter

我正在使用Tkinter弹出一个自定义对话框。 我正在从另一个Tkinter窗口中打开它。

root = Tk()
class ListDialog:
    def __init__(self, names, prompt):
        self.names = names
        self.sub_root = Tk()
        self.sub_root.title("Intovex")
        self.sub_root.iconbitmap("Icon.ico")
        self.myfont = Font(root=self.sub_root, family="Arial", size=8)
        self.sub_root.maxsize(320, 240)
        self.sub_root.wm_attributes("-topmost", True)
        self.sub_root.wm_attributes("-toolwindow", True)
        self.var = IntVar()
        label = Label(self.sub_root, text=prompt)
        label.pack(fill=X)
        c=1
        print(names)
        for i in names:
            print(i)
            r = Radiobutton(self.sub_root, text=i, variable=self.var, value=c, command=self.end)
            r.pack(anchor=W)
            c+=1
        self.var.set(1)
        button = Button(self.sub_root, command=self.endit, text="OK", bg = "#448DE0", fg="White", bd=0, width=12, pady=4, padx=4, height=1,font=self.myfont, highlightcolor="#A3C7F0")
        button.pack(side=BOTTOM)
        self.choice = names[0]

    def end(self):
        ch = self.var.get()
        print(str(ch))
        self.choice = self.names[ch - 1]

    def endit(self):
        self.sub_root.destroy()

    def ask(self):
        self.sub_root.mainloop()
var2 = StringVar()
def get_choice():
    list = ListDialog(["Test1", "Test2"], "Testing")
    list.ask()
    var2.set(str(list.choice))

label = Label(root, text="", textvariable=var2)
button = Button(root, text="Test", command=get_choice)
label.pack()
button.pack()
root.mainloop()

但是,当它通过直接实例化该类并调用ask()方法而单独运行时,它可以工作。 您可能已经看到,代码中到处都有打印语句(用于调试),我发现它在哪里不起作用

  • 用于打印names列表参数的print语句正确地打印了整个列表。
  • 在for循环内,它还会正确打印names列表中的元素
  • 单击单选按钮时,它会调用end()方法。在那里,它始终会打印默认值。
root = Tk()
class ListDialog:
    def __init__(self, names, prompt):
        self.names = names
        self.sub_root = Tk()
        self.sub_root.title("Intovex")
        self.sub_root.iconbitmap("Icon.ico")
        self.myfont = Font(root=self.sub_root, family="Arial", size=8)
        self.sub_root.maxsize(320, 240)
        self.sub_root.wm_attributes("-topmost", True)
        self.sub_root.wm_attributes("-toolwindow", True)
        self.var = IntVar()
        label = Label(self.sub_root, text=prompt)
        label.pack(fill=X)
        c=1
        print(names)
        for i in names:
            print(i)
            r = Radiobutton(self.sub_root, text=i, variable=self.var, value=c, command=self.end)
            r.pack(anchor=W)
            c+=1
        self.var.set(1)
        button = Button(self.sub_root, command=self.endit, text="OK", bg = "#448DE0", fg="White", bd=0, width=12, pady=4, padx=4, height=1,font=self.myfont, highlightcolor="#A3C7F0")
        button.pack(side=BOTTOM)
        self.choice = names[0]

    def end(self):
        ch = self.var.get()
        print(str(ch))
        self.choice = self.names[ch - 1]

    def endit(self):
        self.sub_root.destroy()

    def ask(self):
        self.sub_root.mainloop()
list = ListDialog(["Test1", "Test2"], "Testing")
list.ask()
print(list.choice)

但是如果我将其作为TopLevel小部件打开,它会起作用。但是然后主窗口才等到弹出窗口返回值(选择)。

1 个答案:

答案 0 :(得分:1)

第一个代码段中的代码存在问题,是因为您在tkinter应用程序中多次调用Tk() -混淆了接口代码,可能会导致各种问题,如您所知

如果您将__init__()类的ListDialog方法内部的调用替换为tk.Toplevel(),则您的代码将开始工作。

我还简化了for循环,该循环通过更改Radiobutton来创建IntVar,以便使用内置的enumerate()函数自动保留名称计数。与此结合,我将ListDialog zero 的初始值设为不是选择单选按钮将为其分配值的值之一。因此,当第一次显示end()时,不会选择任何一个。它还确保了只要用户按下其中之一,就会调用list回调函数,因此,在发生这种情况时,始终会通知您的应用。

请注意,尽管我没有进行更改,但您不应命名变量from tkinter import * from tkinter.font import Font root = Tk() class ListDialog: def __init__(self, names, prompt): self.names = names # self.sub_root = Tk() # Wrong - don't call Tk() more than once. root.withdraw() # Hide root window. self.sub_root = Toplevel() # Create another top-level window. self.sub_root.title("Intovex") # self.sub_root.iconbitmap("Icon.ico") # I don't have this file... self.myfont = Font(root=self.sub_root, family="Arial", size=8) self.sub_root.maxsize(320, 240) self.sub_root.wm_attributes("-topmost", True) self.sub_root.wm_attributes("-toolwindow", True) self.var = IntVar(value=0) # Define and init value to one *not* produced by btns. label = Label(self.sub_root, text=prompt) label.pack(fill=X) print(names) for c, name in enumerate(names, start=1): print(c) r = Radiobutton(self.sub_root, text=c, variable=self.var, value=c, command=self.end) r.pack(anchor=W) button = Button(self.sub_root, command=self.endit, text="OK", bg = "#448DE0", fg="White", bd=0, width=12, pady=4, padx=4, height=1, font=self.myfont, highlightcolor="#A3C7F0") button.pack(side=BOTTOM) self.choice = names[0] def end(self): ch = self.var.get() print(str(ch)) self.choice = self.names[ch - 1] def endit(self): self.sub_root.destroy() root.deiconify() # Reshow root window. def ask(self): self.sub_root.mainloop() var2 = StringVar() def get_choice(): list = ListDialog(["Test1", "Test2"], "Testing") list.ask() var2.set(str(list.choice)) label = Label(root, text="", textvariable=var2) button = Button(root, text="Test", command=get_choice) label.pack() button.pack() root.mainloop() ,因为这样会用该名称隐藏内置类的名称。通常,您应该避免命名任何与现有标准Python名称冲突的内容。

select
    id.id as id,
    seq as maxSequence,
    data.someData as someData
from
(select id, max(sequenceId) as seq from #tab group by id) id
left join #tab data on id.id = data.id and id.seq = data.sequenceId