Table of Contents generated with DocToc

Py Tkinter-GUI 日记本

V1.0 基本功能实现

  • 打开文件
  • 保存文件
  • 关闭窗口
  • 关于(messagebox实现)

    代码是参考一个小例子修改过来的,它是用menu执行,我修改为按钮的方式, 参考案例Menu方式实现效果

我修改后的实现效果,界面粗暴,权当学习。

附V1.0 我的源代码

# -*- coding: utf-8 -*-

# 导入Tk GUI模块
from Tkinter import *
from ScrolledText import *
import tkMessageBox
from tkFileDialog import *
import fileinput
import time

import sys
reload(sys)
sys.setdefaultencoding('utf-8')

t1 = []
root=None

# Add your code here
# Delete the description when you start coding.




class diary(Frame):

 def __init__(self,rt):

    if rt == None:
      self.t=Tk()    #创建顶层窗口t(master)
    else:
      self.t=Toplevel(rt) #使用toplevel窗口模式
    self.t.title("窗口- %d"%len(t1))
    Frame.__init__(self,rt)
    self.pack(fill=BOTH, expand=1)

    '''定义按钮'''
    '''Possible values are specified as compass directions:
    "n" (north, or top edge), "ne", (north-east, or top right corner), 
    "e", "se", "s", "sw", "w", "nw" or "center".
    Layout布局
    pack side :It can be top, bottom, left and right. The default is top
    color: color names (e.g. "red") or hex RGB codes (e.g. "#ff340a").
    anchor :Pack widget will be anchored to specific side if the width is less than space is assigned. The valid edges are n,e,w,s(东西南北)
    '''

    self.open = Button(self)
    self.open["text"] = "打开文件"
    self.open["fg"] = "Blue"
    self.open["command"] = self.diary_open_txt
    self.open.pack({"side":"left"})
    self.open.pack({"anchor":"n"})

    self.save = Button(self)
    self.save["text"] = "保存"
    self.save["fg"] = "#0fff0a" 
    self.save["command"] = self.savefile
    self.save.pack({"side":"left"})
    self.save.pack({"anchor":"n"})

    self.quit = Button(self)
    self.quit["text"] = "关闭"
    self.quit["fg"] = "red"
    self.quit["command"] = self.close
    self.quit.pack({"side":"left"})
    self.quit.pack({"anchor":"n"})

    self.guan_yu = Button(self)
    self.guan_yu["text"] = "关于"
    self.guan_yu["fg"] = "red"
    self.guan_yu["command"] = self.about1
    self.guan_yu.pack({"side":"left"})
    self.guan_yu.pack({"anchor":"s"})



    self.f=Frame(self,width=512)
    self.f.pack(expand=1,fill=BOTH)

    self.st=ScrolledText(self.f,background="white")
    self.st.pack(side=LEFT,fill=BOTH,expand=1)

#定义打开文件函数    
 def diary_open_txt(self):
    p1=END
    oname=askopenfilename(filetypes=[("文本文件","*.txt*")])
    if oname:
        for line in fileinput.input(oname):
         self.st.insert(p1,line)

    self.t.title(oname)

 def savefile(self):
  sname=asksaveasfilename()
  if sname:
   ofp=open(sname,"w")
   ofp.write(self.st.get(1.0,END))
   ofp.flush()  #刷新
   ofp.close()
   self.t.title(sname + u"已保存")

 def close(self):
  self.t.destroy() #注意此处销毁当前窗口
  print "close"

 def about1(self):
  tkMessageBox.showinfo("小小记事本","V1.0\n"
  "创建于2015年10月26日\n"
  "作者:robo_one")
  print u"关于"



def neweditor():
 global root
 t1.append(diary(root))

if __name__=="__main__":
 root=None
 t1.append(diary(root))
 root=t1[0].t
root.mainloop()

V1.0 BUG

V1.1 更新

代码

  • 修改各组件的执行代码顺序
  • 熟悉anchor参数, n, ne, e, se, s, sw, w, nw, or center
  • 写文件增加时间戳
  • 关于按钮尝试增加lambda表达式
  • 增加新建(有Bug)
  • 更正GB2312编码文本的输出问题

self.f=Frame(self,width=512)
self.f.pack(expand=1,fill=BOTH)

self.st=ScrolledText(self.f,background="gray")
self.st.pack(side=LEFT,fill=BOTH,expand=1)

self.open = Button(self)
self.open["text"] = "打开文件"
self.open["fg"] = "Blue"
self.open["command"] = self.diary_open_txt
self.open.pack({"side":"left"})
self.open.pack({"anchor":"nw"})

self.newfile = Button(self)
self.newfile["text"] = "新建"
self.newfile["fg"] = "black"
self.newfile["command"] = neweditor
self.newfile.pack({"side":"left"})
self.newfile.pack({"anchor":"nw"})

self.save = Button(self)
self.save["text"] = "保存"
self.save["fg"] = "black" 
self.save["command"] = self.savefile
self.save.pack({"side":"left"})
self.save.pack({"anchor":"n"})

self.quit = Button(self)
self.quit["text"] = "关闭"
self.quit["fg"] = "red"
self.quit["command"] = self.close
self.quit.pack({"side":"left"})
self.quit.pack({"anchor":"center"})

self.guan_yu = Button(self)
self.guan_yu["text"] = "关于"
self.guan_yu["fg"] = "red"
self.guan_yu["command"] = lambda:self.about1()
'''lambda后面跟的是表达式,注意调用函数需要增加()
可以多试试它,挺不错的'''
self.guan_yu.pack({"side":"right"})
self.guan_yu.pack({"anchor":"center"})

V1.1BUG

  • 新建窗口无法打开新的窗口,而是在原窗口下方新建

感想

  • Python思想:不论函数命名、类、变量的定义力求简单明了
  • Tk.pack布局太坑了~反人类的设计,我想要的是所见即所得的GUI,目前了解的有
  • 未完待续

参考资料

Tkinter什么鬼

《Practical Programming in Tcl and Tk》 关于Tk中pack的理解

Tkinter pack_layout布局案例

Python Tkinter Frame

Layout management in Tkinter

An Introduction to Tkinter (Work in Progress)

The Tkinter Scrollbar Widget

  • get() Gets the current slider position.Offset 0.0 means that the slider is in its topmost (or leftmost) position, and offset 1.0 means that it is in its bottommost (or rightmost) position.
  • 关于 class中的 _init _

Python类的函数为什么要有self参数? 显胜于隐的哲学思想~~

  • What-is-the-purpose-of-self-in-python

    • Thomas-wouters的最佳回答:Python's all for making things explicit, making it obvious what's what, and although it doesn't do it entirely everywhere, it does do it for instance attributes. That's why assigning to an instance attribute needs to know what instance to assign to, and that's why it needs self..
  • self在Python里不是关键字。self代表当前对象的地址。self能避免非限定调用造成的全局变量。

Python自然语言编码转换