利用python的tkinter模块实现可视化科学计算器的开发

这个作业属于哪个课程<班级的链接>
这个作业要求在哪里https://bbs.csdn.net/forums/ssynkqtd-05?spm=1001.2014.3001.6685
这个作业的目标完成一个具有可视化界面的计算器
其他参考文献tkinter模块的帮助文档

目录:

0.项目基本功能展示

1. Gitcode项目地址

2. PSP表格

3. 解题思路描述

4. 接口设计和实现过程

5. 关键代码展示

6. 性能改进

7. 单元测试

8. 心得体会

 

 0.项目基本功能展示

1. Gitcode项目地址
 

GitHub - lff102101510/my_homework-1.0: 第一次软件工程作业

2. PSP表格
 

PSPPersonal Software Process Stages预估耗时(分钟)实际耗时(分钟)
Planning计划155
• Estimate• 估计这个任务需要多少时间1515
Development开发1015
• Analysis• 需求分析 (包括学习新技术)2015
• Design Spec• 生成设计文档3030
• Design Review• 设计复审1010
• Coding Standard• 代码规范 (为目前的开发制定合适的规范)1010
• Design• 具体设计2020
• Coding• 具体编码120180
• Code Review• 代码复审2030
• Test• 测试(自我测试,修改代码,提交修改)6060
Reporting报告2010
• Test Repor• 测试报告3030
• Size Measurement• 计算工作量155
• Postmortem & Process Improvement Plan• 事后总结, 并提出过程改进计划2510
合计420

445


3. 解题思路描述

        这次作业的要求是:使用任意语言,开发一个可视化的科学计算器。刚好Python语言中的Tkinter模块可以实现开发可视化GUI界面,再加上python有个bug级别的计算值语句“eval()"。所以我选择了python3作为语言进行开发。界面设计方面,我模仿了win10系统自带的科学计算器的布局。

        我定义了一个类,里面包括了前端界面的书写和后端计算机性能具体的函数实现。

        前端方面,使用tkinter模块中的Tk()创建计算器的窗口。使用tkinter模块中的Button

在界面上整齐地安放按钮并进行按钮样式的设计。

        后端方面,我在”calculator“类中定义了多个函数,如”equal""addchar"来进行具体的计算。

        作业要求提交exe文件和源代码,使用pyinstaller进行.exe文件的生成。 


4. 接口设计和实现过程
 

#使用Entry()函数创建输入框
#使用self.string变量承接输入框的输入内容,以字符串形式记录

entry = Entry(window, textvariable=self.string,width = 30,font = custom_font)
self.string = StringVar()
#在这里将输入框内输入的内容转化成“eval()”函数可以直接理解的内容
#这里我专门列出了‘sin’‘cos’等无法直接被eval函数的特殊情况
#直接在这一步调用math模块的函数把他们的结果记录在self.string中以便输出

 def addChar(self, char):

        if char == "sin":
            try:
                angle = float(self.string.get())
                self.value = math.sin(math.radians(angle))
                self.string.set(self.value)
            except ValueError:
                self.string.set("无效输入")
        elif char == "cos":
            try:
                angle = float(self.string.get())
                self.value = math.cos(math.radians(angle))
                self.string.set(self.value)
            except ValueError:
                self.string.set("无效输入")
        elif char == "tan":
            try:#这里可能存在精度问题
                angle = float(self.string.get())
                self.value = math.tan(math.radians(angle))
                self.string.set(self.value)
            except ValueError:
                self.string.set("无效输入")
        elif char == "log":
            try:
                angle = float(self.string.get())
                self.value = math.log(angle,10)
                self.string.set(self.value)
            except ValueError:
                self.string.set("无效输入")
        elif char == "e":
            try:
                self.string.set(2.7182818284590)
            except ValueError:
                self.string.set("无效输入")
        elif char == "pi":
            try:
                self.string.set(3.1415926535)
            except ValueError:
                self.string.set("无效输入")
        elif char == "sqrt":
            try:
                angle = float(self.string.get())
                self.value = math.sqrt(angle)
                self.string.set(self.value)
            except ValueError:
                self.string.set("无效输入")

        elif char == "pow":
            try:
                angle = float(self.string.get())
                self.value = math.pow(angle,2)
                self.string.set(self.value)
            except ValueError:
                self.string.set("无效输入")
        else:
            self.string.set(self.string.get() + str(char))
#按下等号后,执行这个函数进行最终的计算

    def equals(self):
        result = ""
        try:
            result = eval(self.string.get())
            self.string.set(result)
        except:
            result = "无效输入"
        #这一句意思是将result添加到最后要输出的部分中
        self.string.set(result)
        self.value = 0


 
5. 关键代码展示

上面展示了基本接口和功能的代码,这里给大家看看界面设置前端部分的代码吧。

    def __init__(self):
        window = Tk()
        window.title('您的科学计算器')
        window.configure(background="white")
        self.string = StringVar()
        self.value = 0

        font_size = 16
        font_weight = "bold"
        custom_font  = font.Font(size = font_size,weight = font_weight)

        entry = Entry(window, textvariable=self.string,width = 30,font = custom_font)
        entry.grid(row=0, column=0,columnspan = 6,sticky = "NSEW")
        entry.configure(background="white")
        entry.focus()

        window.grid_rowconfigure(0,weight = 1)
        window.grid_columnconfigure(0,weight =1)

        values = ["(", ")", "%","C", "DEL",
                  "sqrt",  "pow","e","pi", "/",
                  "cos", "7", "8", "9", "*",
                  "tan", "4", "5", "6", "-",
                   "sin","1", "2", "3", "+",
                  "log",  "0", ".", "="]

        text = 1
        i = 0
        row = 1
        col = 0

        for txt in values:
            padx = 15
            pady = 15
            if (i == 5):
                row = 2
                col = 0
            if (i == 10):
                row = 3
                col = 0
            if (i == 15):
                row = 4
                col = 0
            if (i == 20):
                row = 5
                col = 0
            if (i == 25):
                row = 6
                col = 0
            if (txt == '='):
                style = Style()
                style.configure('Tbutton',borderwidth = 0,bodercolor = "Orange",relief = 'flat',borderradius = 100)
                btn = Button(window, height=2, width=4, padx=48, pady=5, text=txt,
                             command=lambda txt=txt: self.equals(),font = ("Arial",16),bd =2,highlightthickness = 2)
                btn.config(highlightcolor = "grey")
                btn.grid(row=row, column=col, columnspan=3, padx=0, pady=0)
                btn.configure(background="Orange")

            elif (txt == 'DEL'):
                btn = Button(window, height=2, width=4, padx=10, pady=5, text=txt,
                             command=lambda txt=txt: self.delete(),font = ("Arial",16),bd = 2,highlightthickness = 2)
                btn.config(highlightcolor="grey")
                btn.grid(row=row, column=col, padx=0, pady=0)
                btn.configure(background="grey")

            elif (txt == 'C'):
                btn = Button(window, height=2, width=4, padx=10, pady=5, text=txt,
                             command=lambda txt=txt: self.clearall(),font = ("Arial",16),bd = 2,highlightthickness = 2)
                btn.config(highlightcolor="grey")
                btn.grid(row=row, column=col, padx=0, pady=0)
                btn.configure(background="grey")

            elif(txt == '7' or txt =='8' or txt == '9' or txt == '4' or txt == '5' or txt == '6'or txt == '1' or txt == '2' or txt == '3' or txt == 'abs' or txt == '0' or txt == '.'):
                btn = Button(window, height=2, width=4, padx=10, pady=5, text=txt,
                             command=lambda txt=txt: self.addChar(txt),font = ("Arial",16),bd = 2,highlightthickness = 2)
                btn.config(highlightcolor = "grey")
                btn.grid(row=row, column=col, padx=0, pady=0)
                btn.configure(background="Snow")

            #加减乘除已经OK了
            elif( txt == '+' or txt == '-' or txt == '*' or txt =='/'):
                style = Style()
                style.configure('Tbutton', borderwidth=0, bodercolor="Orange", relief='flat', borderradius=100)
                btn = Button(window, height=2, width=4, padx=10, pady=5, text=txt,
                             command=lambda txt=txt: self.addChar(txt), font=("Arial", 16), bd=2, highlightthickness=2)
                btn.config(highlightcolor="grey")
                btn.grid(row=row, column=col, columnspan=3, padx=0, pady=0)
                btn.configure(background="Orange")

            else:
                btn = Button(window, height=2, width=4, padx=10, pady=5, text=txt,
                             command=lambda txt=txt: self.addChar(txt),font = ("Arial",16),bd = 2,highlightthickness = 2)
                btn.config(highlightcolor = "grey")
                btn.grid(row=row, column=col, padx=0, pady=0)
                btn.configure(background="LightGrey")

            col = col + 1
            i = i + 1
        window.mainloop()

6. 性能改进
       

在实现拓展功能“实现‘sin’‘cos’等函数”的时候,发现一开始的处理方式无法适配这种情况。一调用‘sin’或者‘cos’函数,就显示“无效输入”。

self.string.set(self.string.get() + str(char))

        后来发现,出现这种情况和“eval()”函数的特性和我设置的异常处理机制有关系。在这里我使用“eval()”函数将 addchar()函数处理好的,直接是数学公式的字符串进行计算并求职,若字符串无法被“eval()”函数识别,就启动异常捕获机制,将输出内容变为“无效输入”。

        问题在于,如果我们在输入框按自然数学的习惯,键入”sin30",则会出现两个问题。

        一,eval()函数处理不了这个公式,只能抛出异常,异常被捕获之后便输出“无效输入”。        

        二,python中处理三角函数相关的语句应该是:

        math.sin(degree)

    def equals(self):
        result = ""
        try:
            result = eval(self.string.get())
            self.string.set(result)
        except:
            result = "无效输入"
        self.string.set(result)
        self.value = 0

        将代码改成如下格式之后成功解决。其他的调用python math库函数计算的功能也一并这么做。

 if char == "sin":
            try:
                angle = float(self.string.get())
                self.value = math.sin(math.radians(angle))
                self.string.set(self.value)
            except ValueError:
                self.string.set("无效输入")
        elif char == "cos":
            try:
                angle = float(self.string.get())
                self.value = math.cos(math.radians(angle))
                self.string.set(self.value)
            except ValueError:
                self.string.set("无效输入")
        elif char == "tan":
            try:#这里可能存在精度问题
                angle = float(self.string.get())
                self.value = math.tan(math.radians(angle))
                self.string.set(self.value)
            except ValueError:
                self.string.set("无效输入")
        elif char == "log":
            try:
                angle = float(self.string.get())
                self.value = math.log(angle,10)
                self.string.set(self.value)
            except ValueError:
                self.string.set("无效输入")
        elif char == "e":
            try:
                self.string.set(2.7182818284590)
            except ValueError:
                self.string.set("无效输入")
        elif char == "pi":
            try:
                self.string.set(3.1415926535)
            except ValueError:
                self.string.set("无效输入")
        elif char == "sqrt":
            try:
                angle = float(self.string.get())
                self.value = math.sqrt(angle)
                self.string.set(self.value)
            except ValueError:
                self.string.set("无效输入")

        elif char == "pow":
            try:
                angle = float(self.string.get())
                self.value = math.pow(angle,2)
                self.string.set(self.value)
            except ValueError:
                self.string.set("无效输入")
        else:
            self.string.set(self.string.get() + str(char))


7. 单元测试

用python跑测试也太麻烦了!妈呀,测试代码比原来的代码还多^ _ ^,话不多说,直接上代码!

import unittest
from tkinter import Tk,font
from tkinter import StringVar, Entry, Button
from tkinter.ttk import Style
import math

class calculator:
    def __init__(self):
        window = Tk()
        window.title('您的科学计算器')
        window.configure(background="white")
        self.string = StringVar()
        self.value = 0

        font_size = 16
        font_weight = "bold"
        custom_font  = font.Font(size = font_size,weight = font_weight)

        entry = Entry(window, textvariable=self.string,width = 30,font = custom_font)
        entry.grid(row=0, column=0,columnspan = 6,sticky = "NSEW")
        entry.configure(background="white")
        entry.focus()

        window.grid_rowconfigure(0,weight = 1)
        window.grid_columnconfigure(0,weight =1)

        values = ["(", ")", "%","C", "DEL",
                  "sqrt",  "pow","e","pi", "/",
                  "cos", "7", "8", "9", "*",
                  "tan", "4", "5", "6", "-",
                   "sin","1", "2", "3", "+",
                  "log",  "0", ".", "="]

        text = 1
        i = 0
        row = 1
        col = 0

        for txt in values:
            padx = 15
            pady = 15
            if (i == 5):
                row = 2
                col = 0
            if (i == 10):
                row = 3
                col = 0
            if (i == 15):
                row = 4
                col = 0
            if (i == 20):
                row = 5
                col = 0
            if (i == 25):
                row = 6
                col = 0
            if (txt == '='):
                style = Style()
                style.configure('Tbutton',borderwidth = 0,bodercolor = "Orange",relief = 'flat',borderradius = 100)
                btn = Button(window, height=2, width=4, padx=48, pady=5, text=txt,
                             command=lambda txt=txt: self.equals(),font = ("Arial",16),bd =2,highlightthickness = 2)
                btn.config(highlightcolor = "grey")
                btn.grid(row=row, column=col, columnspan=3, padx=0, pady=0)
                btn.configure(background="Orange")

            elif (txt == 'DEL'):
                btn = Button(window, height=2, width=4, padx=10, pady=5, text=txt,
                             command=lambda txt=txt: self.delete(),font = ("Arial",16),bd = 2,highlightthickness = 2)
                btn.config(highlightcolor="grey")
                btn.grid(row=row, column=col, padx=0, pady=0)
                btn.configure(background="grey")

            elif (txt == 'C'):
                btn = Button(window, height=2, width=4, padx=10, pady=5, text=txt,
                             command=lambda txt=txt: self.clearall(),font = ("Arial",16),bd = 2,highlightthickness = 2)
                btn.config(highlightcolor="grey")
                btn.grid(row=row, column=col, padx=0, pady=0)
                btn.configure(background="grey")

            elif(txt == '7' or txt =='8' or txt == '9' or txt == '4' or txt == '5' or txt == '6'or txt == '1' or txt == '2' or txt == '3' or txt == 'abs' or txt == '0' or txt == '.'):
                btn = Button(window, height=2, width=4, padx=10, pady=5, text=txt,
                             command=lambda txt=txt: self.addChar(txt),font = ("Arial",16),bd = 2,highlightthickness = 2)
                btn.config(highlightcolor = "grey")
                btn.grid(row=row, column=col, padx=0, pady=0)
                btn.configure(background="Snow")

            #加减乘除已经OK了
            elif( txt == '+' or txt == '-' or txt == '*' or txt =='/'):
                style = Style()
                style.configure('Tbutton', borderwidth=0, bodercolor="Orange", relief='flat', borderradius=100)
                btn = Button(window, height=2, width=4, padx=10, pady=5, text=txt,
                             command=lambda txt=txt: self.addChar(txt), font=("Arial", 16), bd=2, highlightthickness=2)
                btn.config(highlightcolor="grey")
                btn.grid(row=row, column=col, columnspan=3, padx=0, pady=0)
                btn.configure(background="Orange")

            else:
                btn = Button(window, height=2, width=4, padx=10, pady=5, text=txt,
                             command=lambda txt=txt: self.addChar(txt),font = ("Arial",16),bd = 2,highlightthickness = 2)
                btn.config(highlightcolor = "grey")
                btn.grid(row=row, column=col, padx=0, pady=0)
                btn.configure(background="LightGrey")

            col = col + 1
            i = i + 1
        window.mainloop()

    def clearall(self):
        self.string.set("")


    def equals(self):
        result = ""
        try:
            result = eval(self.string.get())
            self.string.set(result)
        except:
            result = "无效输入"
        self.string.set(result)
        self.value = 0


    def addChar(self, char):

        if char == "sin":
            try:
                angle = float(self.string.get())
                self.value = math.sin(math.radians(angle))
                self.string.set(self.value)
            except ValueError:
                self.string.set("无效输入")
        elif char == "cos":
            try:
                angle = float(self.string.get())
                self.value = math.cos(math.radians(angle))
                self.string.set(self.value)
            except ValueError:
                self.string.set("无效输入")
        elif char == "tan":
            try:#这里可能存在精度问题
                angle = float(self.string.get())
                self.value = math.tan(math.radians(angle))
                self.string.set(self.value)
            except ValueError:
                self.string.set("无效输入")
        elif char == "log":
            try:
                angle = float(self.string.get())
                self.value = math.log(angle,10)
                self.string.set(self.value)
            except ValueError:
                self.string.set("无效输入")
        elif char == "e":
            try:
                self.string.set(2.7182818284590)
            except ValueError:
                self.string.set("无效输入")
        elif char == "pi":
            try:
                self.string.set(3.1415926535)
            except ValueError:
                self.string.set("无效输入")
        elif char == "sqrt":
            try:
                angle = float(self.string.get())
                self.value = math.sqrt(angle)
                self.string.set(self.value)
            except ValueError:
                self.string.set("无效输入")

        elif char == "pow":
            try:
                angle = float(self.string.get())
                self.value = math.pow(angle,2)
                self.string.set(self.value)
            except ValueError:
                self.string.set("无效输入")
        else:
            self.string.set(self.string.get() + str(char))


    def delete(self):
        self.string.set(self.string.get()[0:-1])

class TestCalculator(unittest.TestCase):
    def setUp(self):
        self.window = Tk()
        self.calculator_instance = calculator()
    #测试加
    def test_addition(self):
        self.calculator_instance.addChar('2')
        self.calculator_instance.addChar('+')
        self.calculator_instance.addChar('3')
        self.calculator_instance.equals()
        self.assertEqual(self.calculator_instance.string.get(), '5')
    #测试减
    def test_subtraction(self):
        self.calculator_instance.addChar('5')
        self.calculator_instance.addChar('-')
        self.calculator_instance.addChar('3')
        self.calculator_instance.equals()
        self.assertEqual(self.calculator_instance.string.get(), '2')
    #测试乘
    def test_multiply(self):
        self.calculator_instance.addChar('5')
        self.calculator_instance.addChar('*')
        self.calculator_instance.addChar('3')
        self.calculator_instance.equals()
        self.assertEqual(self.calculator_instance.string.get(), '15')
    # 测试除
    def test_divide(self):
        self.calculator_instance.addChar('5')
        self.calculator_instance.addChar('/')
        self.calculator_instance.addChar('0')
        self.calculator_instance.equals()
        self.assertEqual(self.calculator_instance.string.get(), '无效输入')
    #测试sin cos tan
    def test_sin(self):
        self.calculator_instance.addChar('30')
        self.calculator_instance.addChar('sin')
        self.calculator_instance.equals()
        self.assertEqual(self.calculator_instance.string.get(), '0.49999999999999994')
    def test_cos(self):
        self.calculator_instance.addChar('60')
        self.calculator_instance.addChar('cos')
        self.calculator_instance.equals()
        self.assertEqual(self.calculator_instance.string.get(), '0.5000000000000001')
    def test_tan(self):
        self.calculator_instance.addChar('0.9999999999999999')
        self.calculator_instance.addChar('tan')
        self.calculator_instance.equals()
        self.assertEqual(self.calculator_instance.string.get(), '1')
    #测试pow和log
    def test_pow(self):
        self.calculator_instance.addChar('2')
        self.calculator_instance.addChar('pow')
        self.calculator_instance.equals()
        self.assertEqual(self.calculator_instance.string.get(), '4.0')

    def test_log(self):
        self.calculator_instance.addChar('10')
        self.calculator_instance.addChar('log')
        self.calculator_instance.equals()
        self.assertEqual(self.calculator_instance.string.get(), '1.0')



if __name__ == '__main__':
    unittest.main()

九个基本功能测试通过!
8. 异常处理

        出现异常的话,就使用except捕获异常,输出“无效输入”。

9.心得体会
       

        我将在两个方面阐述我的心得体会。

         在具体功能实现方面,我在实践中认识到了“eval”函数的局限性,即使是万能的python库函数也有它的限制,要充分了解它的特性才能得以利用。

         在界面设计方面,我感觉我的想法还没有完全实现。本来想把每个按钮的边角做成圆角,再把数字键设置成透明的,哈哈,利用Button生成按钮好像不能设计按钮的这一类样式呢。

          下次试试前后端分开!使用css ➕ html能对界面进行更多的操作!

           PS:用sin30,cos30,tan45去测试会出现“0.499999999999”,“0.50000000001”,“0.9999999999”,应该是把输入的角度值,转化成弧度值,再对输出值转化为float型这一连串操作产生的一些精度丢失。

服务端: 服务端程序启动之后弹出窗口,管理员输入IP、端口等信息之后点击启动按钮,服务器启动,服务端窗口自动关闭,之后跳转至服务端信息展示界面,包含用户上线提醒,用户发送信息记录展示。 客户端: 客户端程序启动之后,需要弹出登录界面,当用户成功输入昵称、密码、端口、IP等信息(考虑到用户权限问题,本程序在后台默认有固定IP、端口,)用户只需输入昵称、密码(密码用于后期连接数据库时用来匹配数据库存储的用户信息)。当用户成功输入用户名。昵称、密码等信息客户端登录成功跳转至用户进行端对端的聊天界面。聊天界面大致分为聊天记录展示界面,在线好友信息界面以及用户发送信息处。用户在发送消息处输入想要发送的文本消息,选择在线好友中的好友昵称点击选择好友即可选中您要发给的好友昵称,然后点击发送按钮,即可将消息发送给所选择的好友,同时将信息展示在自己的聊天界面中的聊天记录处 2.2. 功能要求 §2.2.1服务端功能要求: 当管理员输入服务器IP、以及端口等信息之后点击启动按钮之后,服务端正常启动之后,需要保持一直开机状态满足所有用户不论在何时登录之后都能进行与好友之间的聊天交流等,同时服务端还要满足监控用户登录信息,不同用户登录客户端之后,服务器后台能够看到某某客户上线了等提示信息。用于服务端查看好友在线状态同时作为服务器,还要能够监控用户的聊天记录,用于监控用户不能发送一些不利言论,从而将其用户及时作封号处理。阻止其传播一些不健康的言论。 §2.2.2客户端要求: 用户在登录界面输入昵称、密码等信息之后成功登录之后,进行窗口之间的跳转,由登录窗口跳转至进行用户之间的聊天窗口,之前的登录窗口也要随之消失。在聊天窗口之中用户需要根据好友在线信息情况选择自己想要与其进行聊天的对象。用户点击在线好友的昵称点击选择好友即可向该好友发送信息,发送成功之后同时要将其发送的信息以及时间信息展示在自己的窗口之中,同时也要在指定好友的窗口之中有所显示以及时间信息
这是一个VB6的IDE插件(Addin),使用VB6的IDE直接设计Python的界面。 Python和VB都是能让人快乐的编程语言,我使用了Python之后,很多自己使用的工具都使用Python开发或改写了,因为最终实现Python代码实在太短了(相比VB),有时候Python一行代码就可以实现VB一个函数的功能。 Python就是这种让人越用越开心的语言。 不过说实在,使用Python开发GUI界面还是麻烦了一些了,自带的标准库Tkinter使用起来非常简单,不过对于习惯了VB拖放控件完成界面设计的偶来说,还是不够人性化。TK也有一个工具叫GUI Builder,不过它使用Layout布局,不够直观,而且用起来很不爽。。 至于PyQt/wxPython等GUI库,尽管有可视化设计工具,但总感觉做一般的轻量级应用是杀鸡用牛刀, 而且不够环保,不够低碳,要带一个很大的库,需要目标机器上夜同样安装了PyQt/wxPython,做不了绿色软件。 所以最终的结果是我更喜欢Tkinter,用起来很简单,绿色环保,真正的跨平台,一个py文件到处运行(担心泄密就编译成pyc)。 很多人都认为TK的界面不够美观,不过我经过多次实验后发现导入Python自带的标准TTK主题库,界面非常Native,不输PyQt/wxPython。 此Addin默认启用TTK支持,也可选择关闭。 总而言之,轻量级GUI,TK+TTK足够。 使用此Addin,你可以不用写一句代码就可以生成一个完整可运行的Python的GUI界面,支持2.X和3.X。 安装方法:将压缩包解压到你希望的目录,然后执行Setup.exe完成注册插件过程,打开VB6就可以用了。 在VB窗体上设计完成界面后(你可以大胆的设置各控件的属性,Addin尽量将其翻译为tkinter的控件属性),点工具栏上的VisualTkinter(图标为一片羽毛),再点'生成代码'按钮,即可生成可运行的Python代码,可以拷贝至剪贴板或保存至文件。 一般情况下你可以不用再改变tkinter的控件属性,但是如果你熟悉tkinter,需要更多的控制,可以一一核对各属性,并且修改,再生成代码。 当然除了用来设计界面外,此ADDIN内置的各控件属性列表可以做为编程参考,比较完整,除了极少数我认为大多数人都不用的属性外,属性定义基本上是我从官方的tkinter文档直接翻译的。 如果还没有VB6,网上找一个VB6精简版即可,不到20M,小巧玲珑。 代码已经在Github上托管,更新的版本可以在这上面找到,需求也可以在上面提: https://github.com/cdhigh/Visual-Tkinter-for-Python
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值