从Python应用程序中的Logic分离Tkinter GUI问题

时间:2015-01-15 04:12:36

标签: python user-interface tkinter tk separation-of-concerns

这是我的第一个应用程序。它运作良好,但我想从翻译逻辑中分离UI问题,如获取输入和创建标签。我想删除上一次翻译的输出,即一次只在屏幕上显示一个翻译。

如何将翻译逻辑与我的Tkinter GUI分开?

from Tkinter import *
import tkMessageBox


def start():
    inputg = input.get()
    if len(inputg) >= 2 and inputg.isalpha():
        new_word_out = Label(text=(inputg[1:] + (inputg[0] + "ay")).lower().title()).pack()
        out_message = Label(text="Cool! Try another!").pack()
        # restart()
    elif len(inputg) <= 1 and inputg.isalpha():
        show_error(message="Whoops! I need 2 or more characters to translate! Try again!")
        return
    elif len(inputg) >= 1 and not inputg.isalpha():
        show_error(message="Whoops! No numbers or symbols please! Try again!")
        return
    elif len(inputg) == 0:
        show_error(message="It seems you haven't given me anything to translate!")
        return


def show_error(message):
    tkMessageBox.showerror(title="Error", message=message)
    return


def quit():
    ask_exit = tkMessageBox.askyesno(title="Quit", message="Are you sure you want to quit?")
    if ask_exit > 0:
        root.destroy()
        return


root = Tk()
input = StringVar()  # stores user input into this variable as a string.

root.title("The Pig Translator")

root.protocol("WM_DELETE_WINDOW", quit)

labeltitle1 = Label(text="Hello there! This is my Pig Latin Translator!").pack()

labeltitle2 = Label(text="Please enter a word to continue!", fg='darkgreen', bg='grey').pack()

original_entry = Entry(textvariable=input, bd=5, fg='darkgreen').pack()

translate_button = Button(text="Translate", command=start).pack()
root.bind('<Return>', lambda event: start())  # essentially binds 'Return' keyboard event to translate_button

root.mainloop()

1 个答案:

答案 0 :(得分:2)

有许多方法可以将逻辑与GUI分开。通常我会建议使用类和回调函数。因此,我创建了一个生成gui的类。但是,翻译由名为do_translation的外部函数执行。

MyFrame对do_translation的方式知之甚少。它只知道它返回translated_str, message并将字符串作为参数。 do_translation也不会传播任何gui。 do_translation只接受一个输入字符串,执行它想要的操作,并返回已翻译的字符串和消息。 MyFrame将此函数作为回调。您可以进行任何其他翻译功能,只要输入和输出相同,它就可以工作。

我依赖于&#34;酷&#34;在按摩,表明翻译是好的。它的糟糕想法是让它继续传播“酷”#39;一句话,但不想太多改变你的代码。可能更好地提出一些错误,或使用消息代码等。

from Tkinter import *

import tkMessageBox


class MyFrame(Frame):

    def __init__(self, master, input_callback=None, **kwargs):
        Frame.__init__(self, master)

        self.set_input_callback(input_callback)
        self.create_widgets()
        self.pack()

    def create_widgets(self):

        self.input = StringVar()  # stores user input into this variable as a string.

        self.labeltitle1 = Label(text="Hello there! This is my Pig Latin Translator!")
        self.labeltitle1.pack()

        self.labeltitle2 = Label(text="Please enter a word to continue!", fg='darkgreen', bg='grey')
        self.labeltitle2.pack()

        self.original_entry = Entry(textvariable=self.input, bd=5, fg='darkgreen')
        self.original_entry.pack()

        self.translate_button = Button(text="Translate", command=self.start)
        self.translate_button.pack()

        self.new_word_out = Label(text='')
        self.out_message = Label(text='')

    def set_input_callback(self, some_fun):
        self.input_callback = some_fun

    def show_error(self, message):
        tkMessageBox.showerror(title="Error", message=message)
        return

    def start(self):
        inputg = self.input.get()

        if self.input_callback:

            translated_str, message = self.input_callback(inputg)

            if 'Cool' in message:
                self.new_word_out['text'] = translated_str
                self.new_word_out.pack()
                self.out_message['text'] = message
                self.out_message.pack()

            else:
                self.show_error(message)


def do_translation(inputg):
    translated_str = message = ''

    if len(inputg) >= 2 and inputg.isalpha():
        translated_str = (inputg[1:] + (inputg[0] + "ay")).lower()
        message = "Cool! Try another!"
    elif len(inputg) <= 1 and inputg.isalpha():
        message = "Whoops! I need 2 or more characters to translate! Try again!"
    elif len(inputg) >= 1 and not inputg.isalpha():
        message = "Whoops! No numbers or symbols please! Try again!"
    elif len(inputg) == 0:
        message = "It seems you haven't given me anything to translate!"

    return translated_str, message


def quit():
    ask_exit = tkMessageBox.askyesno(title="Quit", message="Are you sure you want to quit?")
    if ask_exit > 0:
        root.destroy()
        return


root = Tk()

root.title("The Pig Translator")
root.protocol("WM_DELETE_WINDOW", quit)

mf = MyFrame(root)
mf.set_input_callback(do_translation)

root.bind('<Return>', lambda event: start())  # essentially binds 'Return' keyboard event to translate_button

root.mainloop()

希望这会很有用。我知道,这里没有太多的解释,但是,没有太多时间来写它。你的问题很普遍。