解决方案:Python3 Tkinter 从一个窗口跳转到另一个带有后退和下一个按钮的窗口

Mik*_*ell 5 navigation window tkinter python-3.x

我一直在研究 python3 中的 tkinter,发现很难在网上找到好的文档和答案。为了帮助其他遇到相同问题的人,我决定发布一个简单问题的解决方案,该问题似乎没有在线文档。

问题:创建一个类似向导的程序,该程序向用户显示一系列窗口,用户可以在单击下一步和后退按钮的窗口之间移动。

解决办法是:

  • 创建一个根窗口。
  • 创建与要呈现给用户的窗口一样多的框架。将所有框架附加到根窗口。
  • 用它需要的所有小部件填充每个框架。
  • 填充完所有帧后,使用该grid_forget()方法隐藏每个帧,但不隐藏第一帧,使其成为可见帧。框架上的所有子小部件都将与框架一起隐藏。
  • 当用户单击窗口上的 Next 或 Back 按钮时,调用一个子程序来隐藏其他框架(使用grid_forget())并使需要的框架可见(使用grid())。
  • 当您希望程序结束时,对根窗口使用 destroy - 方法。

因此,您将创建一个窗口并在其上显示不同的框架。

(顺便说一下,开始学习 tkinter 的最佳地点是:http : //www.tkdocs.com/tutorial/index.html

这是 Python3 中的示例实现。它有 3 个简单的窗口,每个窗口都有一个文本标签和两个用于浏览不同窗口的按钮。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#

# Creates three "windows" that the user can navigate through using Back and Next - buttons.

import tkinter
import tkinter.ttk

def create_widgets_in_first_frame():
    # Create the label for the frame
    first_window_label = tkinter.ttk.Label(first_frame, text='Window 1')
    first_window_label.grid(column=0, row=0, pady=10, padx=10, sticky=(tkinter.N))

    # Create the button for the frame
    first_window_quit_button = tkinter.Button(first_frame, text = "Quit", command = quit_program)
    first_window_quit_button.grid(column=0, row=1, pady=10, sticky=(tkinter.N))
    first_window_next_button = tkinter.Button(first_frame, text = "Next", command = call_second_frame_on_top)
    first_window_next_button.grid(column=1, row=1, pady=10, sticky=(tkinter.N))

def create_widgets_in_second_frame():
    # Create the label for the frame
    second_window_label = tkinter.ttk.Label(second_frame, text='Window 2')
    second_window_label.grid(column=0, row=0, pady=10, padx=10, sticky=(tkinter.N))

    # Create the button for the frame
    second_window_back_button = tkinter.Button(second_frame, text = "Back", command = call_first_frame_on_top)
    second_window_back_button.grid(column=0, row=1, pady=10, sticky=(tkinter.N))
    second_window_next_button = tkinter.Button(second_frame, text = "Next", command = call_third_frame_on_top)
    second_window_next_button.grid(column=1, row=1, pady=10, sticky=(tkinter.N))

def create_widgets_in_third_frame():
    # Create the label for the frame
    third_window_label = tkinter.ttk.Label(third_frame, text='Window 3')
    third_window_label.grid(column=0, row=0, pady=10, padx=10, sticky=(tkinter.N))

    # Create the button for the frame
    third_window_back_button = tkinter.Button(third_frame, text = "Back", command = call_second_frame_on_top)
    third_window_back_button.grid(column=0, row=1, pady=10, sticky=(tkinter.N))
    third_window_quit_button = tkinter.Button(third_frame, text = "Quit", command = quit_program)
    third_window_quit_button.grid(column=1, row=1, pady=10, sticky=(tkinter.N))

def call_first_frame_on_top():
    # This function can be called only from the second window.
    # Hide the second window and show the first window.
    second_frame.grid_forget()
    first_frame.grid(column=0, row=0, padx=20, pady=5, sticky=(tkinter.W, tkinter.N, tkinter.E))

def call_second_frame_on_top():
    # This function can be called from the first and third windows.
    # Hide the first and third windows and show the second window.
    first_frame.grid_forget()
    third_frame.grid_forget()
    second_frame.grid(column=0, row=0, padx=20, pady=5, sticky=(tkinter.W, tkinter.N, tkinter.E))

def call_third_frame_on_top():
    # This function can only be called from the second window.
    # Hide the second window and show the third window.
    second_frame.grid_forget()
    third_frame.grid(column=0, row=0, padx=20, pady=5, sticky=(tkinter.W, tkinter.N, tkinter.E))

def quit_program():
    root_window.destroy()

###############################
# Main program starts here :) #
###############################

# Create the root GUI window.
root_window = tkinter.Tk()

# Define window size
window_width = 200
window_heigth = 100

# Create frames inside the root window to hold other GUI elements. All frames must be created in the main program, otherwise they are not accessible in functions. 
first_frame=tkinter.ttk.Frame(root_window, width=window_width, height=window_heigth)
first_frame['borderwidth'] = 2
first_frame['relief'] = 'sunken'
first_frame.grid(column=0, row=0, padx=20, pady=5, sticky=(tkinter.W, tkinter.N, tkinter.E))

second_frame=tkinter.ttk.Frame(root_window, width=window_width, height=window_heigth)
second_frame['borderwidth'] = 2
second_frame['relief'] = 'sunken'
second_frame.grid(column=0, row=0, padx=20, pady=5, sticky=(tkinter.W, tkinter.N, tkinter.E))

third_frame=tkinter.ttk.Frame(root_window, width=window_width, height=window_heigth)
third_frame['borderwidth'] = 2
third_frame['relief'] = 'sunken'
third_frame.grid(column=0, row=0, padx=20, pady=5, sticky=(tkinter.W, tkinter.N, tkinter.E))

# Create all widgets to all frames
create_widgets_in_third_frame()
create_widgets_in_second_frame()
create_widgets_in_first_frame()

# Hide all frames in reverse order, but leave first frame visible (unhidden).
third_frame.grid_forget()
second_frame.grid_forget()

# Start tkinter event - loop
root_window.mainloop()
Run Code Online (Sandbox Code Playgroud)

Joh*_*Jr. 1

正如您冒昧地将答案作为问题发布一样。我想发表评论作为答案,并建议您也许应该将其贡献给 TkDocs(单击他们的“关于”选项卡,他们会谈论为该网站做出贡献)。

我认为如果用更多的例子来改进该网站会比把这个网站变成一本食谱更好。我认为你也可以为Active State Recipe做出贡献,它们似乎是 Tcl/Tk 火炬的携带者,所以 Tkinter 的东西在那里也很有意义。