《零基础入门学习Python》(35)--图形用户界面入门:EasyGui
0. 安装 EasyGUI
官网:https://github.com/robertlugg/easygui
进行下载,下载好了尽量将它放在你python安装目录下面,方面查找
使用 pip 进行安装:
1. 什么是 EasyGUI?
EasyGUI 是 Python 中一个非常简单的 GUI 编程模块,不同于其他的 GUI 生成器,它不是事件驱动的。相反,所有的 GUI 交互都是通过简地函数调用就可以实现。
EasyGUI 为用户提供了简单的 GUI 交互接口,不需要程序员知道任何有关 tkinter,框架,部件,回调或 lambda 的任何细节。
EasyGUI 可以很好地兼容 Python 2 和 3,并且不存在任何依赖关系。
EasyGUI 是运行在 Tkinter 上并拥有自身的事件循环,而 IDLE 也是 Tkinter 写的一个应用程序并也拥有自身的事件循环。因此当两者同时运行的时候,有可能会发生冲突,且带来不可预测的结果。因此如果你发现你的 EasyGUI 程序有这样的问题,请尝试在 IDLE 外去运行你的程序。
2. 一个简单的例子
在 EasyGui 中,所有的 GUI 互动均是通过简单的函数调用,下边一个简单的例子告诉你 EasyGui 确实很 Easy!
import easygui as g
import sys
while 1:
g.msgbox("嗨,欢迎进入第一个界面小游戏^_^")
msg ="请问你希望在鱼C工作室学习到什么知识呢?"
title = "小游戏互动"
choices = ["谈恋爱", "编程", "OOXX", "琴棋书画"]
choice = g.choicebox(msg, title, choices)
# 注意,msgbox的参数是一个字符串
# 如果用户选择Cancel,该函数返回None
g.msgbox("你的选择是: " + str(choice), "结果")
msg = "你希望重新开始小游戏吗?"
title = "请选择"
# 弹出一个Continue/Cancel对话框
if g.ccbox(msg, title):
pass # 如果用户选择Continue
else:
sys.exit(0) # 如果用户选择Cancel
3. EasyGUI 的各种功能演示
要运行 EasyGUI 的演示程序,在命令行调用 EasyGUI 是这样的:
python easygui.py
或者可以从 IDE(例如 IDLE, PythonWin, Wing, 等等)上调用:
>>> import easygui
>>> easygui.egdemo()
成功调用后将可以尝试 EasyGUI 拥有的各种功能,并将结果打印至控制台
4. 导入 EasyGUI
为了使用 EasyGUI 这个模块,你应该先导入它。
最简单的导入语句是:
import easygui
如果使用上面这种形式导入的话,那么你使用 EasyGUI 的函数的时候,必须在函数的前面加上前缀 easygui,像这样:
easygui.msgbox(...)
另一种选择是导入整个 EasyGUI 包:
from easygui import *
这使得我们更容易调用 EasyGUI 的函数,可以直接这样编写代码:
msgbox(...)
第三种方案是使用类似下边的 import 语句:
import easygui as g
这种方法还可以让你保持 EasyGUI 的命名空间,同时减少你的打字数量。
导入之后就可以这么调用 EasyGUI 的函数:
g.msgbox(...)
5. 使用 EasyGUI
一旦你的模块导入 EasyGUI,GUI 操作就是一个简单的调用 EasyGUI 函数的几个参数的问题了。
例如,使用 EasyGUI 来实现世界上最著名的打招呼:
import easygui as g
g.msgbox("Hello, world!")
6. EasyGUI 函数的默认参数
对于所有对话框而言,前两个参数都是消息主体和对话框标题。
按照这个规律,在某种情况下,这可能不是理想的布局设计(比如当对话框在获取目录或文件名的时候会选择忽略消息参数),但保持这种一致性且贯穿于所有的窗口部件是更为得体的考虑!
绝大部分的 EasyGUI 函数都有默认参数,几乎所有的组件都会显示消息主体和对话框标题。
标题默认是空字符串,消息主体通常有一个简单的默认值。
这使得你可以尽可能少的去设置参数,比如 msgbox() 函数标题部分的参数是可选的,因此你调用 msgbox() 的时候只需要指定一个消息参数即可,例如:
>>> g.msgbox('hello world!!!!')
当然你也可以指定标题参数和消息参数,例如:
>>> g.msgbox('hello world','go go go')
在各类按钮组件里,默认的消息是 “Shall I continue?”,所以你可以不带任何参数地去调用它们。
这里我们演示不带任何参数地去调用 ccbox(),当选择 “cancel” 或关闭窗口的时候返回一个布尔类型的值:
import easygui as g
while True:
if g.ccbox():
pass # user chose to continue
else:
exit() # user chose to cancel
7. 使用关键字参数调用EasyGui函数
调用EasyGui函数还可以使用关键字参数
现在假设你需要使用一个按钮组件,但你不想指定标题参数
(第二个参数),你仍可以使用关键字参数的方法指定choices
参数(第三个参数),像这样:
import easygui as g
xz = ['棒','真棒','超级棒']
replay = g.choicebox('我棒不棒?',choices=xz)
8. 使用按钮组建
根据需求,EasyGui在buttonbox()上建立了一系列的函数供调用。
8.1 msgbox()
>>> help(g.msgbox)
Help on function msgbox in module easygui.boxes.derived_boxes:
msgbox(msg='(Your message goes here)', title=' ', ok_button='OK', image=None, root=None)
Display a message box
:param str msg: the msg to be displayed
:param str title: the window title
:param str ok_button: text to show in the button
:param str image: Filename of image to display
:param tk_widget root: Top-level Tk widget
:return: the text of the ok_button
重写OK
按钮最简单的方法是使用关键字参数:
import easygui as g
g.msgbox('我一定要学会Python', ok_button='加油')
8.2 ccbox()
>>> help(g.ccbox)
Help on function ccbox in module easygui.boxes.derived_boxes:
ccbox(msg='Shall I continue?', title=' ', choices=('C[o]ntinue', 'C[a]ncel'), image=None, default_choice='Continue', cancel_choice='Cancel')
Display a msgbox with choices of Continue and Cancel.
The returned value is calculated this way::
if the first choice ("Continue") is chosen,
or if the dialog is cancelled:
return True
else:
return False
If invoked without a msg argument, displays a generic
request for a confirmation
that the user wishes to continue. So it can be used this way::
if ccbox():
pass # continue
else:
sys.exit(0) # exit the program
:param str msg: the msg to be displayed
:param str title: the window title
:param list choices: a list or tuple of the choices to be displayed
:param str image: Filename of image to display
:param str default_choice: The choice you want highlighted
when the gui appears
:param str cancel_choice: If the user presses the 'X' close,
which button should be pressed
:return: True if 'Continue' or dialog is cancelled, False if 'Cancel'
ccbox()
提供一个选择:Continue
或者Cancel
,并相应的返回1(选中Continue)或者0(选中Cancel)。
【注意】:ccbox()是返回整形的1或0,不是布尔类型的True或False。但你仍然可以这么些:
import sys
import easygui as g
if g.ccbox('要再来一次吗?',choices=('要啊要啊^_^', '算了吧T_T')):
g.msgbox('不给玩了,再玩就玩坏了……')
else:
sys.exit(0)
8.3 ynbox()
>>> help(g.ynbox)
Help on function ynbox in module easygui.boxes.derived_boxes:
ynbox(msg='Shall I continue?', title=' ', choices=('[<F1>]Yes', '[<F2>]No'), image=None, default_choice='[<F1>]Yes', cancel_choice='[<F2>]No')
Display a msgbox with choices of Yes and No.
The returned value is calculated this way::
if the first choice ("Yes") is chosen, or if the dialog is cancelled:
return True
else:
return False
If invoked without a msg argument, displays a generic
request for a confirmation
that the user wishes to continue. So it can be used this way::
if ynbox():
pass # continue
else:
sys.exit(0) # exit the program
:param msg: the msg to be displayed
:type msg: str
:param str title: the window title
:param list choices: a list or tuple of the choices to be displayed
:param str image: Filename of image to display
:param str default_choice: The choice you want highlighted
when the gui appears
:param str cancel_choice: If the user presses the 'X' close, which
button should be pressed
:return: True if 'Yes' or dialog is cancelled, False if 'No'
同8.2
8.4 buttonbox()
>>> help(g.buttonbox)
Help on function buttonbox in module easygui.boxes.button_box:
buttonbox(msg='', title=' ', choices=('Button[1]', 'Button[2]', 'Button[3]'), image=None, images=None, default_choice=None, cancel_choice=None, callback=None, run=True)
Display a msg, a title, an image, and a set of buttons.
The buttons are defined by the members of the choices global_state.
:param str msg: the msg to be displayed
:param str title: the window title
:param list choices: a list or tuple of the choices to be displayed
:param str image: (Only here for backward compatibility)
:param str images: Filename of image or iterable or iteratable of iterable to display
:param str default_choice: The choice you want highlighted when the gui appears
:return: the text of the button that the user selected
可以使用buttonbox()定义自己的一组按钮,buttonbox()会显示一组你定义好的按钮。
当用户点击任意一个按钮的时候,buttonbox()返回按钮的文本内容。如果用户取消或者关闭窗口,那么会返回默认选项(第一个选项)。请看示例:
import easygui as g
g.buttonbox(choices=('草莓','西瓜','芒果','巧克力'))
8.5 indexbox()
>>> help(g.indexbox)
Help on function indexbox in module easygui.boxes.derived_boxes:
indexbox(msg='Shall I continue?', title=' ', choices=('Yes', 'No'), image=None, default_choice='Yes', cancel_choice='No')
Display a buttonbox with the specified choices.
:param str msg: the msg to be displayed
:param str title: the window title
:param list choices: a list or tuple of the choices to be displayed
:param str image: Filename of image to display
:param str default_choice: The choice you want highlighted
when the gui appears
:param str cancel_choice: If the user presses the 'X' close,
which button should be pressed
:return: the index of the choice selected, starting from 0
基本上跟上边一样,区别就是当用户选择第一个按钮的时候返回序号0,选择第二个按钮的时候返回序号1
8.6 boolbox()
>>> help(g.boolbox)
Help on function boolbox in module easygui.boxes.derived_boxes:
boolbox(msg='Shall I continue?', title=' ', choices=('[Y]es', '[N]o'), image=None, default_choice='Yes', cancel_choice='No')
Display a boolean msgbox.
The returned value is calculated this way::
if the first choice is chosen, or if the dialog is cancelled:
returns True
else:
returns False
:param str msg: the msg to be displayed
:param str title: the window title
:param list choices: a list or tuple of the choices to be displayed
:param str image: Filename of image to display
:param str default_choice: The choice you want highlighted
when the gui appears
:param str cancel_choice: If the user presses the 'X' close, which button
should be pressed
:return: True if first button pressed or dialog is cancelled, False if
second button is pressed
如果第一个按钮被选中返回1,否则返回0.
9. 如何在buttonbox里显示图片
当你调用一个buttonbox函数(例如:msgbox(),ynbox(),indexbox()等)的时候,你还可以为关键字参数image赋值,这是设置一个.gif
格式的图像(注意仅支持GIF格式)
import easygui as g
g.buttonbox('大家说我长得帅吗?', image='1.gif', choices=('帅', '不帅', '你大爷'))
10. 为用户提供一系列选项
10.1 choicebox()
>>> help(g.choicebox)
Help on function choicebox in module easygui.boxes.choice_box:
choicebox(msg='Pick an item', title='', choices=[], preselect=0, callback=None, run=True)
Present the user with a list of choices.
return the choice that he selects.
:param str msg: the msg to be displayed
:param str title: the window title
:param list choices: a list or tuple of the choices to be displayed
:param preselect: Which item, if any are preselected when dialog appears
:return: List containing choice selected or None if cancelled
按钮组建方便提供用户一个简单的按钮选项,但如果有很多选项,或者选项的内容特别长的话,更好的策略是为它们提供一个可选择的列表。
choicebox()为用户提供了一个可选择的列表,使用序列(元祖或列表)作为选项,这些选项显示前会按照不区分大小写的方法排好序。
另外还可以使用键盘来选择其中一个选项(比较纠结,但一点儿都不重要):
- 例如当按下键盘上g键,将会选中第一个以g开头的选项。再次按下g键,则会选中下一个以g开头的选项。在选中最后一个以g开头的选项时候,再次按下g键将重新回到在列表的开头的第一个以g开头的选项。
- 如果选项中没有以g开头的,则会选中字符排序在g之前f的那个字符开头的选项
- 如果选项中没有字符排序在g之前,那么在列表中第一个元素将会被选中。
综合我们之前的学习文件功能,举个例子:
import easygui as g
target = ['.mp4','.avi','.rmvb','.mkv','.torrent']
vedio_list = []
import os
def serach_file(start_dir,target):
os.chdir(start_dir)
for each_file in os.listdir(os.curdir):
ext = os.path.splitext(each_file)[1]
if ext in target:
vedio_list.append(os.getcwd() + os.sep +each_file + os.linesep)
if os.path.isdir(each_file):
serach_file(each_file,target)
os.chdir(os.pardir)
start_dir = input('请输入需要查找的目录:')
program_dir = os.getcwd()
serach_file(start_dir,target)
f = open(program_dir + os.sep + 'vedioList.txt','w')
f.writelines(vedio_list)
f.close()
g.choicebox(msg='在 【%s】 系列路径下工搜索满足条件的文件如下' % start_dir,choices=vedio_list)
12. 让用户输入密码
有时候我们需要让用户输入密码,就是用户输入的东西看上去都是**********
12.1 passwordbox()
>>> help(g.passwordbox)
Help on function passwordbox in module easygui.boxes.derived_boxes:
passwordbox(msg='Enter your password.', title=' ', default='', image=None, root=None)
Show a box in which a user can enter a password.
The text is masked with asterisks, so the password is not displayed.
:param str msg: the msg to be displayed.
:param str title: the window title
:param str default: value returned if user does not change it
:return: the text that the user entered, or None if he cancels
the operation.
passwordbox()跟enterbox()样式一样,不同的是用户输入的内容用*
显示,返回用户输入的字符串:
12.2 multpasswordbox()
>>> help(g.multpasswordbox)
Help on function multpasswordbox in module easygui.boxes.multi_fillable_box:
multpasswordbox(msg='Fill in values for the fields.', title=' ', fields=(), values=(), callback=None, run=True)
Same interface as multenterbox. But in multpassword box,
the last of the fields is assumed to be a password, and
is masked with asterisks.
:param str msg: the msg to be displayed.
:param str title: the window title
:param list fields: a list of fieldnames.
:param list values: a list of field values
:return: String
**Example**
Here is some example code, that shows how values returned from
multpasswordbox can be checked for validity before they are accepted::
msg = "Enter logon information"
title = "Demo of multpasswordbox"
fieldNames = ["Server ID", "User ID", "Password"]
fieldValues = [] # we start with blanks for the values
fieldValues = multpasswordbox(msg,title, fieldNames)
# make sure that none of the fields was left blank
while 1:
if fieldValues is None: break
errmsg = ""
for i in range(len(fieldNames)):
if fieldValues[i].strip() == "":
errmsg = errmsg + ('"%s" is a required field.\n\n' %
fieldNames[i])
if errmsg == "": break # no problems found
fieldValues = multpasswordbox(errmsg, title,
fieldNames, fieldValues)
print("Reply was: %s" % str(fieldValues))
multpasswordbox()跟multenterbox()使用相同的接口,但当它显示的时候,最后一个输入框显示为密码的形式*
from easygui import *
msg = "验证登陆信息"
title = "密码函数multpasswordbox示例"
fieldNames = ["服务器 ID", "用户 ID", "密码"]
fieldValues = [] # we start with blanks for the values
fieldValues = multpasswordbox(msg, title, fieldNames)
print("输入的信息是: %s" % str(fieldValues))
13. 显示文本
EasyGui还提供函数用于显示文本。
13.1 textbox()
>>> help(g.textbox)
Help on function textbox in module easygui.boxes.text_box:
textbox(msg='', title=' ', text='', codebox=False, callback=None, run=True)
Display a message and a text to edit
Parameters
----------
msg : string
text displayed in the message area (instructions...)
title : str
the window title
text: str, list or tuple
text displayed in textAreas (editable)
codebox: bool
if True, don't wrap and width is set to 80 chars
callback: function
if set, this function will be called when OK is pressed
run: bool
if True, a box object will be created and returned, but not run
Returns
-------
None
If cancel is pressed
str
If OK is pressed returns the contents of textArea
textbox()函数默认会以比例字体(参数codebox = 1设置为等宽字体)来显示文本内容(会自动换行哦),这个函数适合用于显示一般的书面文字。
【注意】:text参数(第三个参数)可以是字符串,列表或者元祖类型。
13.2 codebox()
>>> help(g.codebox)
Help on function codebox in module easygui.boxes.derived_boxes:
codebox(msg='', title=' ', text='')
Display some text in a monospaced font, with no line wrapping.
This function is suitable for displaying code and text that is
formatted using spaces.
The text parameter should be a string, or a list or tuple of lines to be
displayed in the textbox.
:param str msg: the msg to be displayed
:param str title: the window title
:param str text: what to display in the textbox
codebox()以等宽字体显示文本内容,相当于testbox(codebox = 1)
14. 目录与文件
GUI编程中一个常见的场景是要求用户输入目录及文件名,EasyGui提供了一些基本函数让用户来浏览文件系统,选择一个目录或文件。
14.1 diropenbox()
>>> help(g.diropenbox)
Help on function diropenbox in module easygui.boxes.diropen_box:
diropenbox(msg=None, title=None, default=None)
A dialog to get a directory name.
Note that the msg argument, if specified, is ignored.
Returns the name of a directory, or None if user chose to cancel.
If the "default" argument specifies a directory name, and that
directory exists, then the dialog box will start with that directory.
:param str msg: the msg to be displayed
:param str title: the window title
:param str default: starting directory when dialog opens
:return: Normalized path selected by user
diropenbox()函数用于提供一个对话框,返回用户选择的目录名(带完整路径),如果用户选择Cancel
则返回None。
default参数用于设置默认的打开目录(请确保设置的目录已存在。)
>>> g.diropenbox()
14.2 fileopenbox()
>>> help(g.fileopenbox)
Help on function fileopenbox in module easygui.boxes.fileopen_box:
fileopenbox(msg=None, title=None, default='*', filetypes=None, multiple=False)
A dialog to get a file name.
**About the "default" argument**
The "default" argument specifies a filepath that (normally)
contains one or more wildcards.
fileopenbox will display only files that match the default filepath.
If omitted, defaults to "\*" (all files in the current directory).
WINDOWS EXAMPLE::
...default="c:/myjunk/*.py"
will open in directory c:\myjunk\ and show all Python files.
WINDOWS EXAMPLE::
...default="c:/myjunk/test*.py"
will open in directory c:\myjunk\ and show all Python files
whose names begin with "test".
Note that on Windows, fileopenbox automatically changes the path
separator to the Windows path separator (backslash).
**About the "filetypes" argument**
If specified, it should contain a list of items,
where each item is either:
- a string containing a filemask # e.g. "\*.txt"
- a list of strings, where all of the strings except the last one
are filemasks (each beginning with "\*.",
such as "\*.txt" for text files, "\*.py" for Python files, etc.).
and the last string contains a filetype description
EXAMPLE::
filetypes = ["*.css", ["*.htm", "*.html", "HTML files"] ]
.. note:: If the filetypes list does not contain ("All files","*"), it will be added.
If the filetypes list does not contain a filemask that includes
the extension of the "default" argument, it will be added.
For example, if default="\*abc.py"
and no filetypes argument was specified, then
"\*.py" will automatically be added to the filetypes argument.
:param str msg: the msg to be displayed.
:param str title: the window title
:param str default: filepath with wildcards
:param object filetypes: filemasks that a user can choose, e.g. "\*.txt"
:param bool multiple: If true, more than one file can be selected
:return: the name of a file, or None if user chose to cancel
fileopenbox()函数用于提供一个对话框,返回用户选择的文件名(带完整路径),如果用户选择Cancel则返回None
关于default参数的设置方法:
- default参数指定一个默认路径,通常包含一个或多个通配符。
- 如果设置了default参数,fileopenbox()显示默认的文件路径和格式。
- default默认的参数是*,即匹配所有格式的文件。
例如:
1. default = ‘c:/fishc/*.py’即显示c:\fishc文件夹下所有的Python文件
2. default = ‘c:/fishc/test*.py’即显示c:\fishc文件夹下所有的名字以test开头的Python文件
关于filetypes参数的设置方法:
- 可以是包含文件掩码的字符串列表。例如:filetypes = ['*.txt']
- 可以是字符串列表,列表的最后一项字符串是文件类型的描述,例如:filetypes = ['*.css',['*.htm','*.html','*.HTML files']]
>>> g.fileopenbox(default = 'E:\software\*.exe')
'E:\\software\\pycharm-professional-2018.1.1.exe'
>>> g.fileopenbox(filetypes = ['*.py',['*.py','*.python file']])
'D:\\untitled\\Python_learn\\将一个数分解成列表.py'
事例3:
提供一个文件夹浏览框,让用户选择需要打开的文件,打开并显示文件内容:
import easygui as g
import os
file_path = g.fileopenbox(default="*.txt")
with open(file_path) as f:
title = os.path.basename(file_path)
msg = "文件【%s】的内容如下:" % title
text = f.read()
g.textbox(msg, title, text)
14.3 filesavebox()
>>> help(g.filesavebox)
Help on function filesavebox in module easygui.boxes.filesave_box:
filesavebox(msg=None, title=None, default='', filetypes=None)
A file to get the name of a file to save.
Returns the name of a file, or None if user chose to cancel.
The "default" argument should contain a filename (i.e. the
current name of the file to be saved). It may also be empty,
or contain a filemask that includes wildcards.
The "filetypes" argument works like the "filetypes" argument to
fileopenbox.
:param str msg: the msg to be displayed.
:param str title: the window title
:param str default: default filename to return
:param object filetypes: filemasks that a user can choose, e.g. " \*.txt"
:return: the name of a file, or None if user chose to cancel
filesavebox()函数提供一个对话框,让用于选择的文件需要保存的路径(带完整路劲),如果用户选择Cancel则返回None。
default参数应该包含一个文件名(例如当前需要保存的文件名),当然你也可以设置为空的,或者包含一个文件格式掩码的通配符
filetypes参数类似于fileopenbox()函数的filetypes参数。
>>> g.filesavebox(default='test.txt')
事例4
在事例3的基础上增强功能:当用户点击OK
按钮的时候,比较当前文件是否修改过,如果修改过,则提示覆盖保存
,放弃保存
或另存为...
并实现相应功能。
(提示:解决这道题可能需要点耐心,因为你有可能被一个小问题卡住,但请坚持,自己想办法找到这个小问题并解决它!)
import easygui as g
import os
file_path = g.fileopenbox(default='*.txt')
with open(file_path) as old_file:
title = os.path.basename(file_path)
msg = '文件【%s】的内容如下:' % title
text = old_file.read()
text_after = g.textbox(msg,title,text)
if text != text_after[:-1]: #textbox的返回值会在末尾追加一个换行符
#buttonbox(msg='', title=' ', choices=('Button1', 'Button2', 'Button3'), image=None, root=None)
choice = g.buttonbox('检测到文件内容发生改变,请选择以下操作:','警告',('覆盖保持','放弃保存','另存为...'))
if choice == '覆盖保存':
with open(file_path,'w') as old_file:
old_file.write(text_after[:-1])
if choice == '放弃保存':
pass
if choice == '另存为...':
another_path = g.filesavebox(default='.txt')
if os.path.splitext(another_path)[1] != '.txt':
another_path += '.txt'
with open(another_path,'w') as new_file:
new_file.write(text_after[:-1])
15. 记住用户的设置
15.1 EgStore
>>> help(g.EgStore)
Help on class EgStore in module easygui.boxes.egstore:
class EgStore(builtins.object)
| EgStore(filename)
|
| A class to support persistent storage.
|
| You can use ``EgStore`` to support the storage and retrieval
| of user settings for an EasyGui application.
|
| **First: define a class named Settings as a subclass of EgStore** ::
|
| class Settings(EgStore):
| def __init__(self, filename): # filename is required
| # specify default values for variables that this application wants to remember
| self.user_id = ''
| self.target_server = ''
| settings.restore()
| *Second: create a persistent Settings object** ::
|
| settings = Settings('app_settings.txt')
| settings.user_id = 'obama_barak'
| settings.targetServer = 'whitehouse1'
| settings.store()
|
| # run code that gets a new value for user_id, and persist the settings
| settings.user_id = 'biden_joe'
| settings.store()
|
| **Example C: recover the Settings instance, change an attribute, and store it again.** ::
|
| settings = Settings('app_settings.txt')
| settings.restore()
| print settings
| settings.user_id = 'vanrossum_g'
| settings.store()
|
| Methods defined here:
|
| __getstate__(self)
| All attributes will be pickled
|
| __init__(self, filename)
| Initialize a store with the given filename.
|
| :param filename: the file that backs this store for saving and loading
|
| __repr__(self)
| Return repr(self).
|
| __setstate__(self, state)
| Ensure filename won't be unpickled
|
| __str__(self)
| "Format this store as "key : value" pairs, one per line.
|
| kill(self)
| Delete this store's file if it exists.
|
| restore(self)
|
| store(self)
| Save this store to a pickle file.
| All directories in :attr:`filename` must already exist.
|
| ----------------------------------------------------------------------
| Data descriptors defined here:
|
| __dict__
| dictionary for instance variables (if defined)
|
| __weakref__
| list of weak references to the object (if defined)
GUI编程中一个常见的场景就是要求用户设置一下参数,然后保存下来,以便下次用户使用你的程序的时候可以记住他的设置。
为了实现对用户的设置进行存储和恢复这一过程,EasyGui提供了一个EgStore的类。为了记住某些设置,你的应用程序必须定义一个类(暂时称之为“设置”类,尽管你随意的使用你想要的名称设置它)继承自EgStore类。
然后你的应用程序必须创建一个该类的对象(暂时称之为“设置”对象)
设置类的构造函数(__init__方法)必须初始化所有的你想要它记住的那些值。
一旦你这样做了,你就可以在“设置”对象中通过设定值去实例化变量,从而简单地记住设置。之后使用setting.store()方法在硬盘上持久化设置对象。
下面是创建一个“设置”类的例子:
#-----------------------------------------------------------------------
# create "settings", a persistent Settings object
# Note that the "filename" argument is required.
# The directory for the persistent file must already exist.
#-----------------------------------------------------------------------
settingsFilename = os.path.join("C:", "FishCApp", "settings.txt") # Windows example
settings = Settings(settingsFilename)
下面是使用“设置”对象的例子:
# we initialize the "user" and "server" variables
# In a real application, we'd probably have the user enter them via enterbox
user = "奥巴马"
server = "白宫"
# we save the variables as attributes of the "settings" object
settings.userId = user
settings.targetServer = server
settings.store() # persist the settings
# run code that gets a new value for userId
# then persist the settings with the new value
user = "小甲鱼"
settings.userId = user
settings.store()
16. 捕获异常
- exceptionbox()
>>> help(g.exceptionbox)
Help on function exceptionbox in module easygui.boxes.derived_boxes:
exceptionbox(msg=None, title=None)
Display a box that gives information about
an exception that has just been raised.
The caller may optionally pass in a title for the window, or a
msg to accompany the error information.
Note that you do not need to (and cannot) pass an exception object
as an argument. The latest exception will automatically be used.
:param str msg: the msg to be displayed
:param str title: the window title
:return: None
使用EasyGui编写GUI程序,有时候难免会产生异常。当然这取决于你如何运行你的应用程序,当你的应用程序崩溃的时候,堆栈追踪可能会被抛出,或者被写入到stdout标准输出函数中。
EasyGui通过exceptionbox()函数提供了更好的方式去处理异常,异常出现的时候,exceptionbox()会显示堆栈追踪在一个codebox()中并且允许你做进一步的处理。
exceptionbox()很容易使用,请看下例:
import easygui as g
try:
print('i love fishc.com')
int('FishC') #这里会产生异常
except:
g.exceptionbox()
事例5:
写一个程序统计你当前代码量的总和,并显示离十万行代码量还有多远?
- 要求1:递归搜索各个文件夹
- 要求2:显示各个类型的源文件和源代码数量
- 要求3:显示总行数与百分比
截图1:
截图2:
import easygui as g
import os
def show_result(start_dir):
lines = 0
total = 0
text = ""
for i in source_list:
lines = source_list[i]
total += lines
text += "【%s】源文件 %d 个,源代码 %d 行\n" % (i, file_list[i], lines)
title = '统计结果'
msg = '您目前共累积编写了 %d 行代码,完成进度:%.2f %%\n离 10 万行代码还差 %d 行,请继续努力!' % (total, total/1000, 100000-total)
g.textbox(msg, title, text)
def calc_code(file_name):
lines = 0
with open(file_name) as f:
print('正在分析文件:%s ...' % file_name)
try:
for each_line in f:
lines += 1
except UnicodeDecodeError:
pass # 不可避免会遇到格式不兼容的文件,这里忽略掉......
return lines
def search_file(start_dir) :
os.chdir(start_dir)
for each_file in os.listdir(os.curdir) :
ext = os.path.splitext(each_file)[1]
if ext in target :
lines = calc_code(each_file) # 统计行数
# 还记得异常的用法吗?如果字典中不存,抛出 KeyError,则添加字典键
# 统计文件数
try:
file_list[ext] += 1
except KeyError:
file_list[ext] = 1
# 统计源代码行数
try:
source_list[ext] += lines
except KeyError:
source_list[ext] = lines
if os.path.isdir(each_file) :
search_file(each_file) # 递归调用
os.chdir(os.pardir) # 递归调用后切记返回上一层目录
target = ['.c', '.cpp', '.py', '.cc', '.java', '.pas', '.asm']
file_list = {}
source_list = {}
g.msgbox("请打开您存放所有代码的文件夹......", "统计代码量")
path = g.diropenbox("请选择您的代码库:")
search_file(path)
show_result(path)