在 Python 应用程序中将 Tkinter UI 关注点与逻辑分离 [英] Separating Tkinter UI concerns from Logic in Python app

查看:34
本文介绍了在 Python 应用程序中将 Tkinter UI 关注点与逻辑分离的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的第一个应用程序.它运行良好,但我想将 UI 问题(例如获取输入和创建标签)与翻译逻辑分开.然后我想删除之前翻译的输出,即一次只在屏幕上显示一个翻译.

This is my first app ever. It is working well but I would like to separate the UI concerns like getting input and creating labels, from the translation logic. I would then like to remove the output from the previous translation, i.e., only showing one translation on the screen at a time.

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

How can I separate the translation logic from my 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 的外部函数执行的.

There are many ways you can separate logic from GUI. generally I would recommend using classes and callback functions. Thus, I made a class that generates the gui. However, the translation is performed by external function called do_translation.

MyFrame 不太了解 do_translation 的方法.它只知道它返回 translated_str, message 并接受字符串作为参数.do_translation 也不依赖于任何 gui.do_translation 只接受一个输入字符串,做它想做的事,并返回翻译后的字符串和消息.MyFrame 将此函数作为回调.你可以做任何其他的翻译功能,只要输入和输出相同,它就可以工作.

MyFrame does not know much about how do_translation. It only knows it returns translated_str, message and takes string as argument. do_translation does not relay on any gui as well. The do_translation takes only an input string, does what it wants, and returns translated string and message. The MyFrame take this function as a callback. You can make any other translation function, and as long as the input and output are same, it will work.

我在这里依赖按摩中的酷",这表明翻译没问题.让它转播酷"这个词是个坏主意,但不想过多地更改您的代码.可能更好地引发一些错误,或使用消息代码等.

I rely here on a "Cool" in a massage which indicates that translation was ok. Its poor idea to make it relay on 'Cool' word, but did not want to change your code too much. Probably better to raise some error, or use message codes, etc.

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

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

Hopefully this will be useful. I know, that there is not too much explanation what is happening here, but, don't have much time to write it. Your problem is very general.

这篇关于在 Python 应用程序中将 Tkinter UI 关注点与逻辑分离的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆