python - 将 Tkinter UI 问题与 Python 应用程序中的逻辑分开

标签 python user-interface tkinter tk-toolkit 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()

最佳答案

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

MyFrame 不太了解如何do_translation。它只知道它返回 translated_str, message 并将字符串作为参数。 do_translation 也不依赖于任何图形用户界面。 do_translation 只接受一个输入字符串,做它想做的事,然后返回翻译后的字符串和消息。 MyFrame 将此函数作为回调。您可以制作任何其他翻译功能,只要输入和输出相同,它就可以工作。

我在这里依赖按摩中的“Cool”,这表明翻译没问题。让它依赖于“酷”字是个糟糕的主意,但又不想过多地更改您的代码。可能最好提出一些错误,或使用消息代码等。

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()

希望这会有用。我知道,这里没有太多解释发生了什么,但是,没有太多时间来写它。你的问题很笼统。

关于python - 将 Tkinter UI 问题与 Python 应用程序中的逻辑分开,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27956699/

相关文章:

python - 如何更改我的 Django 项目正在使用的 Python?

python - 逐元素应用

javascript - 浏览器插件?

Python tkinter 多次调用相同的标签

python - sqlite3.OperationalError...我的 sqlite 语法有什么问题?

python - 如何允许 f() 取小数值

python - 使用 Pandas 组合数据框中两行的不同部分

android - 从代码更改 Activity 背景

ios - iOS 9.3 系统字体名称是什么?

python - Tkinter:更新标签内容和按钮命令