如何关闭当前窗口并同时打开新窗口?

时间:2019-09-09 19:12:26

标签: python tkinter

此代码打开一个菜单,该菜单链接到另一个菜单。第一个按钮无法自行关闭并同时打开一个新按钮,该如何解决?

import tkinter as tk
import tkinter.messagebox as box


class EnterRLE(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title('Enter RLE')
        self.line_count_str = tk.StringVar()
        self.compressed_data_str = tk.StringVar(self)

        frame = tk.Frame(self)

        tk.Label(self, text='Line Count:').pack(padx=15, pady=5)
        tk.Entry(self, bd=5, textvariable=self.line_count_str).pack(padx=15, pady=5)
        tk.Button(self, text="Next", width=5, command=self.line_count_func).pack(side='right', padx=5)
        tk.Button(self, text='Exit', width=5, command=self.destroy).pack(side='right', padx=5)
        frame.pack(padx=100, pady=19)

    def line_count_func(self):
        if self.line_count_str.get().isdigit():
            if int(self.line_count_str.get()) < 3:
                box.showinfo(title="Error", message="Enter a number over 3")
            elif int(self.line_count_str.get()) > 1000000000:
                box.showinfo(title="Error", message="Enter a number under 1,000,000,000")
            else:
                self.enter_rle_2()

    def enter_rle_2(self):
        top = tk.Toplevel(self)
        top.title('Enter RLE')
        frame = tk.Frame(top)
        tk.Label(top, text='Compressed Data:').pack(padx=15, pady=5)
        tk.Entry(top, bd=5, textvariable=self.compressed_data_str).pack(padx=15, pady=5)
        tk.Button(top, text="Next").pack(side='right', padx=5)
        frame.pack(padx=19)





EnterRle1().mainloop()

我已经看到有人对这种类型的东西使用新的“ def”方法,但是我不确定如何使它们适应我的代码。

1 个答案:

答案 0 :(得分:0)

这里有几个问题。

第一个主要问题是两次使用Tk()。在这种特定情况下,清理代码后可以正常工作,但是通常您不希望使用多个Tk()实例。

第二个主要问题是您如何尝试破坏enter_rle函数中的linecount_button_clicked。您无法执行此操作,因为该函数对单独的函数不了解enter_rle。您需要在按钮命令中传递它。

第三个主要问题是int(linecount_STR.get())。如果get抓住了一个数字或空字符串以外的东西,这将出错。因此,您的else子句将永远不会发生,因为它将在您的if/else语句之前出错。因此,请使用isdigit()进行修复。

下一步,即使在这里没有任何问题,您仍想在函数顶部定义全局变量。

此处存在一些PEP8问题,这些问题不会损害代码,但如果将它们清理干净,将使其更易于阅读。

确实应该将其构建在类中,以便我们可以使用类属性和方法来管理所有内容。

这是您清理的代码,如果您有任何疑问,请告诉我。

from tkinter import *
import tkinter.messagebox as box


def enter_rle_1():
    enter_rle = Tk()
    linecount_STR = StringVar()
    enter_rle.title('Enter RLE')
    frame = Frame(enter_rle)
    label_linecount = Label(enter_rle, text='Linecount:')
    label_linecount.pack(padx=15, pady=5)
    linecount = Entry(enter_rle, bd=5, textvariable=linecount_STR)
    linecount.pack(padx=15, pady=5)
    ok_button = Button(enter_rle, text="Next", width=5,
                       command=lambda lc=linecount_STR: linecount_button_clicked(enter_rle, lc))
    ok_button.pack(side=RIGHT, padx=5)
    stop = Button(enter_rle, text='Exit', width=5, command=enter_rle.destroy)
    stop.pack(side=RIGHT, padx=5)
    frame.pack(padx=100, pady=19)
    enter_rle.mainloop()


def linecount_button_clicked(enter_rle, linecount_STR):
    linecount = linecount_STR.get()
    if linecount.isdigit():  # does nothing if value is not a digit.
        if int(linecount) < 3:
            box.showinfo(title="Error", message="Enter a number over 3")
        elif int(linecount) > 1000000000:
            box.showinfo(title="Error", message="Enter a number under 1,000,000,000")
        else:
            enter_rle_2(enter_rle)


def enter_rle_2(root):
    enter_rle = Toplevel(root)
    compressed_data_STR = StringVar(root)
    enter_rle.title('Enter RLE')
    frame = Frame(enter_rle)
    label_compressed_data = Label(enter_rle, text='Compressed Data:')
    label_compressed_data.pack(padx=15, pady=5)
    compressed_data = Entry(enter_rle, bd=5, textvariable=compressed_data_STR)
    compressed_data.pack(padx=15, pady=5)
    ok_button = Button(enter_rle, text="Next")
    ok_button.pack(side=RIGHT, padx=5)
    frame.pack(padx=100, pady=19)


enter_rle_1()

这是使用类属性和方法的代码的OOP版本。在Tkinter中管理此类交互更加容易,并且不再需要全球性的交互。

import tkinter as tk
import tkinter.messagebox as box


class EnterRle1(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title('Enter RLE')
        self.line_count_str = tk.StringVar()
        self.compressed_data_str = tk.StringVar(self)

        frame = tk.Frame(self)
        tk.Label(self, text='Line Count:').pack(padx=15, pady=5)
        tk.Entry(self, bd=5, textvariable=self.line_count_str).pack(padx=15, pady=5)
        tk.Button(self, text="Next", width=5, command=self.line_count_func).pack(side='right', padx=5)
        tk.Button(self, text='Exit', width=5, command=self.destroy).pack(side='right', padx=5)
        frame.pack(padx=100, pady=19)

    def line_count_func(self):
        if self.line_count_str.get().isdigit():
            if int(self.line_count_str.get()) < 3:
                box.showinfo(title="Error", message="Enter a number over 3")
            elif int(self.line_count_str.get()) > 1000000000:
                box.showinfo(title="Error", message="Enter a number under 1,000,000,000")
            else:
                self.enter_rle_2()

    def enter_rle_2(self):
        top = tk.Toplevel(self)
        top.title('Enter RLE')
        frame = tk.Frame(top)
        tk.Label(top, text='Compressed Data:').pack(padx=15, pady=5)
        tk.Entry(top, bd=5, textvariable=self.compressed_data_str).pack(padx=15, pady=5)
        tk.Button(top, text="Next").pack(side='right', padx=5)
        frame.pack(padx=100, pady=19)


EnterRle1().mainloop()