《Python编程》笔记(十二)
来源:互联网 发布:灰原穷 知乎 编辑:程序博客网 时间:2024/06/06 11:35
GUI编写技巧
技巧:
- 在“混合类”中提供常见的GUI操作
- 从数据结构模板中创建菜单和工具栏
- 为命令行工具添加GUI接口
- 将输入和输出流重定向到GUI组件
- 重新加载运行中的GUI回调处理程序
- 封装和自动化顶层窗口的接口
- 使用线程和队列避免GUI中的阻塞
- 根据需要从非GUI程序中弹出GUI窗口
- 用套接字和管道将GUI作为单独的程序实现添加
组件生成器函数:可以尽可能地将繁琐的组件设置放在函数中封装,使用时只需要调用函数即可完成设置。实际上这种方法可以用OOP来代替,那样可复用性更高!下面的代码演示了组件生成器函数的使用方法,完整的代码参见这里:
def frame(master, side=TOP, **kw): """ Generate a Frame widget with custom configurations. """ w = Frame(master) w.pack(side=side, expand=YES, fill=BOTH) if kw: w.config(**kw) return wdef main(): app = Tk() f = frame(app) app.mainloop()
- 混合类:在一个类中使用常用的方法,在任何需要的地方继承。混合类通常可以用来封装有用的工具,在需要的时候使用。下面给出一个简单的示例用法,完整示例参见这里:
class MixinDemo: def info_box(self, title, text, **options): return showinfo(title, text, **options) def question(self, title, text, **options): return askyesno(title, text, **options) def quit(self): ans = self.question('Quit?', 'Are you sure you want to quit?') if ans: exit()class Test(Frame, MixinDemo): def __init__(self, master=None, cnf={}, **kw): super(Test, self).__init__(master, cnf, **kw) self.pack() Button(self, text='Info Box', command=lambda: self.info_box('info', 'test info')).grid(row=0, column=0) Button(self, text='Question', command=lambda: self.question('question', 'test question')).grid(row=1, column=0) Button(self, text='Quit', command=self.quit).grid(row=2, column=0)
- 菜单栏和状态栏实际上是比较常用的,但是在
tkinter
中创建它们却比较繁琐,重复性工作很多,所以可以在类中封装生成的方法,通过读取并解析固定格式的配置来自动生成。 - 重定向流到组件:这里需要使用的技巧就是实现两个类似文件的类(即,分别实现
write
,read
等接口),然后将命令行中的sys.stdin
,sys.stdout
,sys.stderr
重定向到要显示的组件(如Text
组件)即可。
class GuiConsole(Frame): def __init__(self, master=None, cnf={}, **kw): super(GuiConsole, self).__init__(master, cnf, **kw) self.pack(fill=BOTH, expand=YES) self.console = ScrolledText(self, font=('Source Code Pro', 12, 'normal')) self.console.pack(side=TOP, fill=BOTH, expand=YES, padx=5, pady=5) self.console.focus() self.console.mark_set(INSERT, '1.0') def clear(self): self.console.delete('1.0', END) def write(self, text): text = '{}'.format(text) self.console.insert(INSERT, text) self.console.mark_set(INSERT, INSERT+'+{}c'.format(len(text))) def writeline(self, text): self.write('{}\n'.format(text)) def writelines(self, lines): for line in lines: self.writeline(line) def read(self): passdef main(): import sys app = Tk() c = GuiConsole(app) save_streams = sys.stdin, sys.stdout sys.stdout = c print('hello, world') sys.stdin, sys.stdout = save_streams app.mainloop()
动态重载回调处理器(仅作了解,需要时候深入):
- 即在GUI运行时修改GUI,这块很好理解,自己领悟!
importlib.reload
函数允许动态修改并且重载程序的模块,无须停止程序。这个特性特别适合开发需要很长事件才能重新启动的程序。对于连接到数据库或网络服务器的程序、初始化大型对象的程序、执行长期运行服务的程序,或者需要经过较多步骤才能重新触发回调的程序,都可以作为reload
的主要对象。它可以在开发周期中节省大量时间,并且使系统更加灵活- 相关的测试代码参见ch10/reload.py, ch10/actions.py,可以在测试中看到修改
actions.py
中的打印消息后,也会在按下按钮时打印最新修改后的结果。
GUI应用中,长期运行的操作必须在并行的线程中运行,这样才可以避免GUI因自我更新或响应新的用户请求而遭遇阻塞。长期运行的操作:时间密集型函数调用、服务器下载、阻塞输入/输出调用等。
- 多线程中,只使用主线程来更行显示,其他并行线程负责产生数据供主线程消费,这种是典型的生产者/消费者模型。
- 来看一个简单的示例,学习如何在GUI程序中使用多线程的生产者消费者模型。完整的代码参见ch10/queue-thread-gui.py,以及封装在类中的示例ch10/queue-thread-gui-class.py,以下是关键代码:
def producer(id_): for i in range(4): time.sleep(0.1) data.put('[producer: id is {}, count is {}]\n'.format(id_, i))def consumer(out): try: d = data.get(block=False) except queue.Empty: # out.writeline('No data in queue now.') pass else: out.write(d) out.after(100, lambda: consumer(out))
在队列中放置回调:通过将函数或其他任何可调用对象放置在队列中,生产者线程可以非常直接地告知GUI如何处理消息。所以,我们可以构建调用队列,等待主线程处理。相关的实例参见ch10/threadtools
可以通过进程间通信机制为非GUi脚本添加图形界面,比如利用管道、套接字、文件或者其他方式。
0 0
- 《Python编程》笔记(十二)
- python 学习笔记(十二)
- Python学习笔记(十二)
- Python学习笔记(十二)-- Python模块
- python(十二)I/O编程
- Python学习笔记(十二):lambda表达式与函数式编程
- Python核心编程学习笔记(十二)——文件和输入输出
- python 学习笔记(二十二)
- Python笔记(十二)--循环控制语句
- linux 自学笔记(十二)Shell编程
- Windows核心编程笔记(十二) 纤程
- Python学习笔记(十二)----Python continue 语句
- python基础教程学习笔记十二
- Python基础教程(十二):GUI编程、版本区别、IDE
- linux下python学习笔记(十二)数据结构2
- PYTHON框架之DJANGO学习笔记(十二)
- Programming Computer Vision with Python (学习笔记十二)
- python学习笔记(十二)标准库os
- 何必如此
- wireshark
- iOS 点击状态栏返回顶部(多scrollView的实现)
- android开发中控件editText对应的inputType的类型总结
- 树套树之线段树套线段树(POJ2155 Matrix)
- 《Python编程》笔记(十二)
- Event Handling Guide for iOS--(三)---Event Delivery: The Responder Chain(翻译)
- SMTP与ESMTP的关系和区别
- ios developer tiny share-20160811
- method="get/post",两种方式的区别
- 64位winform程序无法打开设计视图
- OJ------记负均正
- 2016.8.3
- 批量删除