-1

我希望程序:

  1. 使根窗口保持打开状态
  2. 当点击按钮时,它将打开一个顶层窗口
  3. 在顶层窗口中单击下一步时,它将破坏该顶层窗口并创建另一个顶层窗口,这将一直持续到 List 的所有元素都将被迭代

但它没有按预期工作。

只出现一个顶层窗口,我无法进入下一个顶层

我的代码是:

from tkinter import *

root = Tk()
def go_cmd():
    list = [1,2,3,4,5]
    for i in list:
        win = Toplevel()

        def next_cmd():
            win.destroy()

        l = Label(text = i)
        l.grid(row=0,column=0)
        b = Button(text="Next",command=next_cmd)
        b.grid(row=1,column=0)

        win.mainloop()



b1 = Button(root,text = " Go ",command = go_cmd)
b1.grid(row=0,column=0)




root.mainloop()
4

2 回答 2

0

“为什么不能在 Python3 的循环中重复创建 tkinter 顶层?”

可以在循环内重复创建:

try:                        # In order to be able to import tkinter for
    import tkinter as tk    # either in python 2 or in python 3
except ImportError:
    import Tkinter as tk


if __name__ == '__main__':
    root = tk.Tk()
    for _ in range(5):
        tk.Toplevel(root, bg='red')
    root.mainloop()

在 OP 的代码win.mainloop块中,它在循环中进一步移动,因为它while True本身就是一个“”循环。


实现所需行为的一种好方法是创建一个子类Toplevel并一个一个地调用它们:

try:                        # In order to be able to import tkinter for
    import tkinter as tk    # either in python 2 or in python 3
except ImportError:
    import Tkinter as tk


class MyToplevel(tk.Toplevel):
    def __init__(self, master, text):
        tk.Toplevel.__init__(self, master)
        self.label = tk.Label(self, text=text)
        self.button = tk.Button(self, text="Next", command=self.destroy)
        self.label.grid(row=0, column=0)
        self.button.grid(row=1, column=0)


def next_window(window_widget, index, a_list):
    if window_widget:
        window_widget.destroy()
    if index < len(a_list):
        window_widget = MyToplevel(root, a_list[index])
        if (index + 1) < len(a_list):
            window_widget.button['command'] = lambda: next_window(
                                            window_widget, index + 1, a_list)


if __name__ == '__main__':
    root = tk.Tk()
    a_list = [1, 2, 3, 4, 5]
    current_window = None
    go_button = tk.Button(root, text="Go", command=lambda:next_window(
                                                current_window, 0, a_list))
    go_button.pack()
    root.mainloop()
于 2018-02-08T14:46:05.210 回答
0

您不应该使用循环来创建您的窗口。您设置函数的方式将一次创建所有窗口。

下面的代码将根据列表本身创建窗口,因此当您想要更改“下一步”按钮将转到的页数时,您需要做的就是更新列表。

请记住,这种方式可能不是处理列表的最佳方法。对于更清晰的 OOP 方法,您可能希望在 Class 中编写一些内容。下面仅用于展示如何使用该列表来决定接下来要创建的 Toplevel。

from tkinter import *

root = Tk()

mylist = [1,2,3,4,5]

current_toplevel = None

def go_cmd(x):
    # global is used to make variables that are outside of the function
    # in the global namespace accessible.
    global current_toplevel, mylist

    wx = root.winfo_x()
    wy = root.winfo_y()
    next_index = x + 1

    # This will check if the next_index variable will be within the available
    # index range and if next_index is outside the index range it will reset
    # to index zero. This will prevent the "outside index" error.
    if next_index not in list(range(len(mylist))):
        next_index = 0

    # if the variable current_toplevel is not set to none then destroy it
    # so we can create the next window.
    if current_toplevel != None:
        current_toplevel.destroy()

    current_toplevel = Toplevel()

    # set the location of the new top level window based off of the
    # root windows location. This can be changed to anything but
    # I wanted to use this as the example.
    current_toplevel.geometry("+{}+{}".format(wx, wy))

    Label(current_toplevel, width = 10, text = mylist[x]).grid(row=0,column=0)

    # because we need to prep the "Next" button for the next index
    # we will need to use a lambda command for getting the next window
    b = Button(current_toplevel, width = 10, text="Next",
               command = lambda a = next_index: go_cmd(a)).grid(row=1,column=0)

b1 = Button(root,text = "Go", width = 10,
            command = lambda: go_cmd(0)).grid(row=0,column=0)

root.mainloop()

这是没有所有说明性注释的代码。

从 tkinter 导入 *

root = Tk()

mylist = [1,2,3,4,5]

current_toplevel = None

def go_cmd(x):
    global current_toplevel, mylist

    wx = root.winfo_x()
    wy = root.winfo_y()
    next_index = x + 1

    if next_index not in list(range(len(mylist))):
        next_index = 0

    if current_toplevel != None:
        current_toplevel.destroy()

    current_toplevel = Toplevel()
    current_toplevel.geometry("+{}+{}".format(wx, wy))

    Label(current_toplevel, width = 10, text = mylist[x]).grid(row=0,column=0)

    b = Button(current_toplevel, width = 10, text="Next",
               command = lambda a = next_index: go_cmd(a)).grid(row=1,column=0)

b1 = Button(root,text = "Go", width = 10,
            command = lambda: go_cmd(0)).grid(row=0,column=0)

root.mainloop()
于 2018-02-08T14:52:17.007 回答