《垃圾邮件识别器》(三)界面搭建

通过前面学习的 Tkinter 知识,这一节我们将《垃圾邮件识别器》所需要的界面搭建起来,界面主要包括:

  1. 主窗口
  2. 顶部菜单
  3. 中心文本框
  4. 底部状态栏

1. 主窗口

创建 MainFrame.py 文件,创建 MainFrame 类如下:

import tkinter as tk


class MainFrame(tk.Tk):

    def __init__(self):
        # 初始化父类
        super(MainFrame, self).__init__()
        # 定义窗口宽高
        self.window_w, self.window_h = 800, 500
        # 获得屏幕尺寸
        screen_w, screen_h = self.winfo_screenwidth(), self.winfo_screenheight()
        # 计算窗口屏幕中心位置
        start_x, start_y = int(screen_w / 2 - self.window_w / 2), int(screen_h / 2 - self.window_h / 2)
        # 设置屏幕尺寸以及初始位置
        self.geometry(f'{self.window_w}x{self.window_h}+{start_x}+{start_y}')
        # 设置窗口标题
        self.title('垃圾邮件识别器')
        # 初始化其他窗口
        self.init_widgets()

    def init_widgets(self):
        pass
       

    def show(self):
        self.mainloop()

创建程序入口文件 App.py,其中代码如下:

from MainFrame import MainFrame


if __name__ == '__main__':
    main_frame = MainFrame()
    main_frame.show()

2. 菜单类

创建一个 TopMenu.py 并在该文件中编写如下代码:

import sys
import tkinter as tk
from tkinter.filedialog import askopenfilenames
import codecs
import time
import hashlib


class TopMenu(tk.Menu):

    def __init__(self, predict_function):
        super(TopMenu, self).__init__()
        # 菜单回调
        self.predict_function = predict_function
        # 创建菜单
        self.file_menu()
        self.mail_menu()
        self.help_menu()

    # 添加文件菜单
    def file_menu(self):
        file_menu = tk.Menu(master=self, tearoff=False)
        file_menu.add_command(label='打开')
        file_menu.add_separator()
        file_menu.add_command(label='退出', command=sys.exit)
        self.add_cascade(label='文件', menu=file_menu)

    # 添加邮件菜单
    def mail_menu(self):
        mail_menu = tk.Menu(master=self, tearoff=False)
        mail_menu.add_command(label='识别', command=self.predict_function)
        self.add_cascade(label='邮件', menu=mail_menu)

    # 添加关于我菜单
    def help_menu(self):
        about_menu = tk.Menu(master=self, tearoff=False)
        about_menu.add_command(label='关于')
        self.add_cascade(label='帮助', menu=about_menu)


if __name__ == '__main__':

    window = tk.Tk()
    window.geometry('800x500+300+300')

    menu = TopMenu(predict_function=lambda : print('Hello World'))
    window.config(menu=menu)

    window.mainloop()

3. 中心文本框

创建 CenterText.py 文件,并在该文件中编写如下代码:

import tkinter as tk
from tkinter.scrolledtext import ScrolledText
import hashlib
from datetime import datetime

class CenText(tk.PanedWindow):

    INPUT_NULL = -1
    INPUT_SAME = -2

    def __init__(self):
        super(CenText, self).__init__()
        self.config(orient=tk.HORIZONTAL)
        self.widgetName = 'CenText'
        self.init_widgets()

    def init_widgets(self):
        # 窗口属性
        config = {'bd': 0, 'highlightthickness': 0, 'wrap': tk.NONE}
        # 输入文本框
        self.mail_area = ScrolledText(**config)
        # 信息提示框
        self.info_area = tk.Text(**config)
        self.set_info_disable()
        # 定义字体样式
        self.info_area.tag_configure("custom", font=("宋体", 10, "bold"),   foreground="red")
        self.info_area.tag_configure("normal", font=("宋体", 10, "bold"), foreground="black")
        # 添加文本框
        self.add(self.mail_area)
        self.add(self.info_area)
        # 邮件哈希值
        self.prev_hexdigest = ''

    def set_info_disable(self):
        """使得信息显示框不可输入"""
        self.info_area.config(state='disabled')

    def set_info_normal(self):
        """使得信息显示框可输入"""
        self.info_area.config(state='normal')

    def add_info(self, text, font='normal'):
        """信息框添加格式化的信息"""
        self.set_info_normal()

        # 获得当前时间
        cur_time = datetime.now()
        cur_time = cur_time.strftime("%Y/%m/%d %H:%M:%S")

        self.info_area.insert(tk.END, f'{cur_time} {text}\n', font)
        self.set_info_disable()
        # 滚动条移动到最后
        self.info_area.yview_moveto(1.0)

    def get_mail(self):
        """获得邮件输入框内容"""
        mail = self.mail_area.get("1.0", tk.END).strip()
        if len(mail) == 0:
            return CenText.INPUT_NULL

        # 计算文本哈希摘要
        hash = hashlib.sha256()
        hash.update(mail.encode())
        curr_hexdigest = hash.hexdigest()
        # 判断文本是否变化
        if curr_hexdigest == self.prev_hexdigest:
            return CenText.INPUT_SAME
        self.prev_hexdigest = curr_hexdigest

        return mail


if __name__ == '__main__':

    window = tk.Tk()
    window.geometry('800x500+300+300')

    text = CenText()
    text.pack(fill=tk.BOTH, expand=True)

    button1 = tk.Button(text='添加文本', command=lambda: text.add_info('这是测试文本', font='custom'))
    button1.pack(side=tk.BOTTOM)

    button2 = tk.Button(text='获得文本', command=lambda: print(text.get_mail()))
    button2.pack(side=tk.BOTTOM)

    window.mainloop()

4. 状态栏

创建 StatusBar.py 文件,并编写如下代码:

import random
import tkinter as tk


class StatBar(tk.Frame):

    def __init__(self):
        super(StatBar, self).__init__()
        # 设置控件属性
        self.config(borderwidth=0, bg='#bdc3c7')
        # 初始化子控件
        self.init_widgets()

    def init_widgets(self):
        self.message = tk.Label(self, text=" 准备就绪", bg='#bdc3c7')
        self.message.pack(side=tk.LEFT)

    def set_message(self, text):
        self.message['text'] = text


if __name__ == '__main__':
    window = tk.Tk()
    window.geometry('800x500+300+300')

    sbar = StatBar()
    sbar.pack(side=tk.BOTTOM, fill=tk.X)

    btn1 = tk.Button(text='改变状态栏文字',
                     command=lambda: sbar.set_message(f'状态文字修改:{random.randint(0, 100)}'))
    btn1.pack(side=tk.TOP)

    window.mainloop()

5. 整合控件到主窗口

将头部菜单、中心文本框、底部状态栏创建到主窗口 MainFrame 中,如下:

import tkinter as tk


class MainFrame(tk.Tk):

    ....

    def init_widgets(self):

        from TopMenu import TopMenu
        from StatBar import StatBar
        from CenText import CenText

        # 初始化头部菜单
        self.menu = TopMenu(predict_function=self.on_menu_predict)
        self.config(menu=self.menu)
        # 初始化中心文本框
        self.text = CenText()
        self.text.pack(fill=tk.BOTH, expand=True)
        # 初始化底部状态栏
        self.sbar = StatBar()
        self.sbar.pack(side=tk.BOTTOM, fill=tk.X)

    def on_menu_predict(self):
        print('预测邮件')

    ...

未经允许不得转载:一亩三分地 » 《垃圾邮件识别器》(三)界面搭建
评论 (0)

8 + 7 =