EasyGUI-基于tkinter的pythonGUI敏捷开发库

1. 引言

Tkinter(Tk接口)是Python标准库中的一个GUI(图形用户界面)模块,它提供了创建和操作GUI应用程序所需的工具和组件。Tkinter的名字来自于Tk GUI工具包的接口,它是一个由Tcl语言编写的开源GUI工具包。

使用Tkinter,你可以创建窗口、对话框、按钮、标签、文本框、列表框、菜单、画布、滚动条、文本编辑器等多种GUI组件,并在这些组件上添加事件响应函数,实现与用户交互的功能。

tkinter上手相对简单,但其布局方式往往难以把握,新生可能不易达到想要的效果。

本工具是为减少GUI编写的复杂度而编写的父类, 使用时继承即可。

接口比较死板,且只实现了一些简单的功能,使用网格布局方式,经过简单设计后可以实现相对美观的布局。

如下是使用本工具实现的几个示例:
在这里插入图片描述
在这里插入图片描述

2. 工具源码

import tkinter as tk
from tkinter import filedialog
from PIL import Image, ImageTk

'简易GUI工具'
__author__ = 'littleHuang'
'''
为减少GUI编写的复杂度而编写的父类, 使用时继承即可
接口比较死板,且只实现了一些简单的功能,使用网格布局方式
'''


class EasyGui:
    def __init__(self):
        self.fatherWindow = tk.Tk()
        # 字体设置
        self.font = ('Arial', 15)
        # 封装一下,子类不需要重新import
        self.tk = tk

    def setWindowName(self, name=''):
        '''
        :param name: 窗口名
        :return:
        '''
        self.fatherWindow.title(name)

    def setLabel(self, text='', width=1, row=0, column=0, columnspan=1):
        '''
        :param text: 标签内容
        :param width: 标签宽度
        :param row: 放置行
        :param column: 放置列
        :param columnspan: 合并列
        :param sticky: 调整位置
        :return:
        '''
        tk.Label(self.fatherWindow, text=text, width=width, font=self.font).grid(row=row, column=column,
                                                                                 columnspan=columnspan, )

    def setButton(self, text='', command=None, width=1, row=0, column=0, columnspan=1):
        '''
        :param text:
        :param width:
        :param command: 按下按钮后执行的函数
        :param row:
        :param column:
        :param columnspan:
        :param sticky:
        :return: 按键对象
        '''
        b = tk.Button(self.fatherWindow, text=text, width=width, command=command, font=self.font)
        b.grid(row=row, column=column, columnspan=columnspan)
        return b

    def setEntry(self, width=1, row=0, column=0, columnspan=1,**args):
        '''
        :param width:
        :param row:
        :param column:
        :param columnspan:
        :param sticky:
        :return: 输入框对象
        '''
        e = tk.Entry(self.fatherWindow, width=width, font=self.font,**args)
        e.grid(row=row, column=column, columnspan=columnspan)
        return e

    def setText(self, width=1, height=1, row=0, column=0, columnspan=1):
        '''
        :param width:
        :param height: 文本框高度
        :param row:
        :param column:
        :param sticky:
        :param columnspan:
        :return: 文本框对象
        '''
        t = tk.Text(self.fatherWindow, width=width, height=height, font=self.font)
        t.grid(row=row, column=column, columnspan=columnspan)
        return t

    def setRadiobutton(self, text='', value='', var=None, row=0, column=0, columnspan=1):
        '''
        :param text:
        :param value: 可变字符串点击后的设定值
        :param var: 可变字符串
        :param row:
        :param column:
        :param sticky:
        :param columnspan:
        :return:
        '''
        tk.Radiobutton(self.fatherWindow, text=text, variable=var, value=value, font=self.font).grid(row=row,
                                                                                                     column=column,
                                                                                                     columnspan=columnspan)
    
    def set_windows(self, tittle):
        '''
        :param tittle: 窗口标题
        :return: 新创建的窗口
        '''
        # 创建一个Toplevel窗口
        window = tk.Toplevel(self.fatherWindow)
        # 设置窗口的标题
        window.title(tittle)
        return window
    
    def set_img(self, path):
        '''
        打开一个图片并转化为tk可以显示的格式
        :param path: 图片路径
        :return: 图像对象
        '''
        # 打开一张图片
        # photo = tk.PhotoImage(path)
        image = Image.open(path)
        # 将图片转换为Tkinter可以显示的格式
        photo = ImageTk.PhotoImage(image)
        return  photo, image


    def getPath(self, entry):
        '''
        获取文件夹路径
        :param entry: 要插入的标签
        :return:
        '''
        entry.delete(0, 'end')
        entry.insert(0, filedialog.askdirectory())

    def getFilePath(self, entry):
        '''
        获取文件路径
        :param entry: 要插入的标签
        :return:
        '''
        entry.delete(0, 'end')
        entry.insert(0, filedialog.askopenfilename())
    def run(self):
        self.fatherWindow.mainloop()

    

3. 使用步骤

3.1 前端设计

首先应该评估界面大小,每一个组件的行宽和列高,可以借助Excel等工具先进行简单的绘图。
在这里插入图片描述

3.2 前端编写

首先继承此组件,并填写窗口名,设置字体

from easy_gui import EasyGui
class ShowGui(EasyGui):
    def __init__(self):
        super().__init__()
        self.setWindowName('演示程序')
        self.font= ("微软雅黑", 15)

之后依次放置各个组件,以label为例,主要参数有:

def setLabel(self, text='', width=1, row=0, column=0, columnspan=1):
    '''
    :param text: 标签内容
    :param width: 标签宽度
    :param row: 放置行
    :param column: 放置列
    :param columnspan: 合并列
    :param sticky: 调整位置
    :return:
    '''

width 标签宽度。最小宽度与内容有关,一般中文字符长度为2,英文和数字为1。小于最小宽度将导致内容不全。

row 放置行,即此标签放置在第几行,从上往下,起始位置为0

column 放置列,即此标签放置在第几列,从左向右,起始位置为0

columnspan 占用列,即此标签占用几列,这个根据我们事先的绘图填写

# 脚本路径四个汉字,最小宽度为8,因此我们宽度设置为8,起始位置在0行0列,根据表格,需要占用两列
self.setLabel("脚本路径", 8, 0, 0, 2)

# 根据表格,输入框宽度是前面标签的3倍,因此设置为24,同样在第0行,前面标签占了两列,因此在第列开始,根据表格占用6列
self.sh_path = self.setEntry(24, 0, 2, 6)
# button的第二个参数是需要绑定的方法,这里我们暂时设置为None,后续补充
self.start_button = self.setButton('开始测试', None, 8, 0, 8, 2)
self.node_name("节点名称", 8, 1, 0, 2)
self.sh_path = self.setEntry(16, 1, 2, 4)

# 这里虽然是两个汉字,最小宽度为4,但为了整齐,参考表格,我们仍然设置为8
self.start_button = self.setButton('攻击', None, 8, 1, 6, 2)
self.recovery_button = self.setButton('恢复', None, 8, 1, 8, 2)
self.function1_button = self.setButton('功能1', None,8,2,0,2)
self.function2_button = self.setButton('功能2', None,8,2,2,2)
self.function3_button = self.setButton('功能3', None,8,2,4,2)
self.function4_button = self.setButton('功能4', None,8,2,6,2)
self.function5_button = self.setButton('功能5', None,8,2,8,2)
# 消息框三个字占用整行,用于分割
self.setLabel("消息框", 40,3,0,10)
# 消息框第二个参数为高度,我们根据需要调整
self.messageText = self.setText(40, 10, 4, 0, 10)

初步效果如图

if __name__ == '__main__':
    sg = ShowGui()
    sg.run()

在这里插入图片描述

3.3 完善功能

为几个按钮编写功能

def start_test(self):
    path = self.sh_path.get()
    if not os.path.exists(path):
        self.messageText.insert('end', '脚本路径不存在\n')
        return
    pro = Process(target=os.system, args=('bash '+path,))
    pro.start()
    self.messageText.insert('end', '开始执行测试脚本\n')

def attack_node(self):
    node = self.node_name.get()
    os.system('attack_node '+node)
    self.messageText.insert('end', f'已击毁节点{node}\n')

def recovery_node(self):
    node = self.node_name.get()
    os.system('recovery_node '+node)
    self.messageText.insert('end', f'已恢复节点{node}\n')

def show_img(self, path):
    if not os.path.exists(path):
        self.messageText.insert('end', '图像路径不存在\n')
        return
    img_name = path.split('/')[-1]
    # 创建一个Toplevel窗口
    window = self.set_windows(img_name)
    photo, image = self.set_img(path)
    label = self.tk.Label(window, image=photo)
    label.pack()
    image.show()
        

将功能绑定到按钮上

self.start_button = self.setButton('攻击', self.attack_node, 8, 1, 6, 2)
self.recovery_button = self.setButton(
'恢复', self.recovery_node, 8, 1, 8, 2)
self.function1_button = self.setButton('功能1', functools.partial(
self.show_img, '1.jpg'), 8, 2, 0, 2)
self.function2_button = self.setButton('功能2', functools.partial(
self.show_img, '2.jpg'), 8, 2, 2, 2)
self.function3_button = self.setButton('功能3', functools.partial(
self.show_img, '3.jpg'), 8, 2, 4, 2)
self.function4_button = self.setButton('功能4', functools.partial(
self.show_img, '4.jpg'), 8, 2, 6, 2)
self.function5_button = self.setButton('功能5', functools.partial(
self.show_img, '5.jpg'), 8, 2, 8, 2)

3.4 最终效果

在这里插入图片描述

整体代码

from easy_gui import EasyGui
from multiprocessing import Process
import os
import functools


class ShowGui(EasyGui):
    def __init__(self):
        super().__init__()
        self.setWindowName('演示程序')
        self.font = ("微软雅黑", 15)
        # 四个参数依次是 组件宽度 放置行 放置列 列宽(占用几列)
        self.setLabel("脚本路径", 8, 0, 0, 2)
        self.sh_path = self.setEntry(24, 0, 2, 6)
        self.start_button = self.setButton('开始测试', self.start_test, 8, 0, 8, 2)
        self.setLabel("节点名称", 8, 1, 0, 2)
        self.node_name = self.setEntry(16, 1, 2, 4)
        self.start_button = self.setButton('攻击', self.attack_node, 8, 1, 6, 2)
        self.recovery_button = self.setButton(
            '恢复', self.recovery_node, 8, 1, 8, 2)
        self.function1_button = self.setButton('功能1', functools.partial(
            self.show_img, '1.jpg'), 8, 2, 0, 2)
        self.function2_button = self.setButton('功能2', functools.partial(
            self.show_img, '2.jpg'), 8, 2, 2, 2)
        self.function3_button = self.setButton('功能3', functools.partial(
            self.show_img, '3.jpg'), 8, 2, 4, 2)
        self.function4_button = self.setButton('功能4', functools.partial(
            self.show_img, '4.jpg'), 8, 2, 6, 2)
        self.function5_button = self.setButton('功能5', functools.partial(
            self.show_img, '5.jpg'), 8, 2, 8, 2)
        self.setLabel("消息框", 40, 3, 0, 10)
        self.messageText = self.setText(40, 10, 4, 0, 10)

        # 设置初始值
        self.sh_path.insert(0, '/home/xxx/xxx.sh')
        self.node_name.insert(0, 'node1')

    def start_test(self):
        path = self.sh_path.get()
        if not os.path.exists(path):
            self.messageText.insert('end', '脚本路径不存在\n')
            return
        pro = Process(target=os.system, args=('bash '+path,))
        pro.start()
        self.messageText.insert('end', '开始执行测试脚本\n')

    def attack_node(self):
        node = self.node_name.get()
        os.system('attack_node '+node)
        self.messageText.insert('end', f'已击毁节点{node}\n')

    def recovery_node(self):
        node = self.node_name.get()
        os.system('recovery_node '+node)
        self.messageText.insert('end', f'已恢复节点{node}\n')

    def show_img(self, path):
        if not os.path.exists(path):
            self.messageText.insert('end', '图像路径不存在\n')
            return
        img_name = path.split('/')[-1]
        # 创建一个Toplevel窗口
        window = self.set_windows(img_name)
        photo, image = self.set_img(path)
        label = self.tk.Label(window, image=photo)
        label.pack()
        image.show()
        
    def run(self):
        super().run()


if __name__ == '__main__':
    sg = ShowGui()
    sg.run()

4. 后记

本工具仅从部分使用场景出发,对部分tkinter库的操作进行了简化,很多功能并不完善,欢迎各位再次基础上进一步完善。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: easygui是一个用于创建图形用户界面的Python。它可以让你轻松地创建简单的对话框,如输入框、消息框和选择框等。使用easygui可以让你的程序在没有图形界面的环境下也能很好地工作。你可以使用pip安装easygui:`pip install easygui`。 示例代码: ``` import easygui easygui.msgbox("Hello, world!") name = easygui.enterbox("What is your name?") easygui.msgbox("Hello, " + name) ``` 这段代码会显示一个消息框,然后显示一个输入框,询问你的名字,最后再显示一个消息框,问候你。 ### 回答2: Python easygui是一个图形用户界面(GUI,它提供了一组简单易用的函数和类,用于创建和管理各种图形界面元素,如消息框、输入框、按钮等。使用easygui,我们可以以一种简单直观的方式构建交互式程序。 easygui的最大优点之一是其易学易用。它提供了一系列简洁明了的函数来创建各种界面元素,代码量相对较少,语法简单清晰,非常适合初学者入门学习。 另一个重要的特点是easygui的跨平台性。它基于Tkinter开发,可以在几乎所有的操作系统上运行,包括Windows、Linux和Mac等。 使用easygui的时候,我们可以利用它的各种函数来创建对话框,用于与用户进行交互。例如,使用easygui的msgbox函数我们可以创建一个简单的消息框,并显示一条提示信息。使用buttonbox函数,我们可以创建一个带有按钮的对话框,用户可以通过点击按钮来选择不同的操作。 easygui还提供了一些其他常用的对话框函数,如choicebox、enterbox和multenterbox等,它们分别用于创建选择框、输入框和多行输入框。 总之,Python easygui是一个简单易用且功能强大的图形用户界面,适用于初学者和快速开发的场景。它提供了一系列简洁明了的函数,可以快速创建各种界面元素,并与用户进行交互。使用easygui可以大大简化GUI程序的开发过程,提高开发效率。 ### 回答3: Python easygui是一个简单易用的图形用户界面(GUI。它提供了一系列方便的函数和方法,可以帮助开发者快速创建基于文本的用户界面。通过使用easygui开发者可以简化用户与程序之间的交互,从而提高开发效率。 在使用easygui时,开发者只需要调用相应的函数,就可以实现很多常见的GUI操作,例如创建对话框、输入框、消息框等。开发者可以通过简单地指定一些参数,如标题、提示信息、按钮的文本等,就可以轻松地定制出符合自己需求的用户界面。 easygui还支持多种类型的用户输入,包括文本输入、单选框、复选框等。这些输入控件都可以直接调用中提供的函数来创建,并且还可以添加默认值和限制条件,增加用户输入的准确性和方便性。 此外,easygui还提供了一些特殊的控件,如文件选择框、颜色选择框等。这些控件可以帮助开发者实现更加丰富的用户界面,并提供了更多的选项和功能供用户选择。 总的来说,Python easygui提供了一个简单、易用的方式来创建图形用户界面。它可以帮助开发者快速实现GUI操作,提高开发效率,并且还支持多种用户输入和特殊控件的使用。无论是初学者还是有经验的开发者,都可以从easygui中受益,快速开发出符合自己需求的用户界面。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值