Python 下用 Tkinter 制做 GUI

什么是 GUI

既然要制做 GUI,那么就要先明确什么是 GUI。wiki上是这么说的: html

图形用户界面(Graphical User Interface,简称 GUI)是指采用图形方式显示的计算机操做用户接口。 python

曾经有个同窗这么跟我说,“MATLAB 有个 GUI 的功能,貌似很强大啊”,听完我就凌乱了,图形用户界面何时成了 MATLAB 的专属功能了?我日常用的 Windows 或者 Linux、Mac 都是在图形用户界面下进行操做的,若是想看一看命令行界面,Windows 能够在“运行”中输入 cmd 而后回车,Linux下能够直接 alt+F1(切换回来用 alt+F7)。简单来讲,GUI 提供给用户一种更加直白的图形化的人机交互界面。 小程序

Python 中的 GUI 工具包

若是想用 Python 语言制做出一个程序的 GUI,不只仅能够用 Tkinter 一个包,最多见的还有 wxPython 和 PyQt,还有不少不少(我不熟悉啊 (╯▽╰))。 函数

  1. wxPython:wxPython 建立的是 wxWidgets。它的好处是,能够经过简单的命令就建立出比较漂亮的界面,而且在中国的使用人数挺多,遇到问题在网上找起答案来比较轻松。缺点是并非 Python 的标准工具包,还须要另外安装。官网在这里,官网提供的英文教程在这里 工具

  2. PyQt:和名字同样,建立的是 Qt 的 GUI。Qt 的 GUI 固然是漂亮的不能再漂亮了。优势是,建立出的 GUI 很漂亮,且有图形化的 GUI 设计软件 Qt Designer 来使整个设计过程简单化。缺点:一样不是 Python 的标准工具包,还须要另外安装,若是手工输入 GUI 代码习惯了,有时候图形化的 GUI 设计软件反而不习惯。官网在这里这里有一个比较不错的中文教程,主要讲的是 Qt Designer 的入门使用,很不错。 oop

  3. Tkinter: 从名字能够看出,建立的是 Tk 的GUI。优势很明显,是一个已经半官方化的工具包,能够直接使用,无需安装,而且教程众多,几乎全部介绍 Python 入门的书,只要说起 GUI 设计都会讲 Tkinter。缺点同样明显,设计出的 GUI 很难看,要问多难看,你本身看看 Python 的那个 IDLE 就行了,土的掉渣啊,并且元件同样不多,若是只是编写一些小程序的话还能够,若是编写大程序要用到比较复杂的元件的话,就须要从提供的元件里找一些替代品了,手工输入代码,有时候很累啊。可是我认为用 Tkinter 来入门 GUI 设计是很好的,由于思路清晰,代码简单,这也就是为何我在这里只介绍 Tkinter 的缘由。一个英文教程在这里以前的网站已经不在了,做者将其移到了这里,貌似开始将从前未写完的补充完整了{: style=“color: red”}),因为我不想记住全部元件的方法,因此用到的话就来这里查询,很方便。 学习

GUI 的设计基本思路

但你开始学习 Python 的时候,全部都会考诉你,Python 是 OOP(面向对象程序设计)的程序语言,可是我认为“类”的概念对于初学者是很是难以理解的,并且也没有人规定在 Python 中必须使用“类”,因此我下面的例子,都不是以定义“类”的形式出现,而是以简单的定义“函数”的形式出现,使代码简单、易懂。 网站

对于 GUI 的设计,我认为是“不要着急,不要着急”。先确保实现主要功能的函数正常运行再来考虑 GUI 也不迟。GUI 的设计主要包括下面三个步骤: ui

  1. 建立主窗体
  2. 建立元件
  3. 显示元件
  4. 进入窗体的主循环

下面是一个简单的例子: spa

import Tkinter

root=Tkinter.Tk()  %建立主窗体
MainLabel=Tkinter.Label(root,text="I am so ugly. -- Tkinter",font="Times 16 bold")  %建立元件
MainLabel.pack()  %显示元件
root.mainloop()  %进入窗体的主循环

这个例子中,只包含一个元件是 Label,最后效果就是

根据须要,能够在主窗口中建立多个元件,每个元件所拥有的参数不一样,可是有一点是同样的,就是第一个参数必定是其所属的窗口的变量名。上面的例子中,元件 Label就是隶属于 root,因此在调用 pack 方法以后,这个元件就会在 root 窗口中显示了,只与显示的位置和显示的样子,须要调整 pack方法的参数,我这里使用默认值,因此什么参数也没有,具体 pack 的用法能够参照这里

这三步其实就是 Tkinter GUI 设计的所有了,剩下的就是每一个元件的位置、样子、显示的文字、显示的图像、调用的函数等等元件参数上的设定了,这就涉及到每一个元件包含哪些参数、每一个参数是什么意思的问题了,这个能够经过查询我提到的那个网站来获得。

在 GUI 设计中有如下几点须要注意(持续更新中):

  1. 对于元件函数的调用,有两种方式:直接绑定和间接绑定。直接绑定就是在元件 Button 中的参数 command 中设定回调的函数名称,以下:

    ButtonInput=Tkinter.Button(root,text="Input",command=InputString)

    间接绑定是用 bind 方法,对于全部元件都有这个方法,形式以下:

    ButtonInput.bind('<Return>',InputString)

    bind 须要指定一种触发方式,这里的触发方式就再也不仅仅局限于 Button 的左键单击了,键盘输入、鼠标点击都是能够的,我这里的触发方式是 <Return>,也就是回车。可是要注意的是,bind 是绑定在一个元件上的,也就是说,当焦点在这个元件上的时候触发才有用,并且回调的函数必需要要有一个 event 做为输入参数,若是没有就直接 None 好了,以下:

    def InputString(event=None):
       …
       …
       …

    这两种方法使用的时候有一个共同须要注意的地方就是,回调函数不要出现参数,下面这种就是错误的:

    ButtonInput=Tkinter.Button(root,text="Input",command=InputString())

    若是这样,程序就会直接调用函数 InputString(),而不是等到用户点击按钮的时候再调用了,若是必定要向回调的函数中加入参数的话,就用 lambda吧,以下:

    ButtonInput=Tkinter.Button(root,text="Input",command=lambda x: InputString(x))
  2. 显示元件的方法不只仅有 pack(),还有 grid(),若是元件排列须要很整齐,能够用 grid(),经过输入行数和列数来控制元件的显示位置,二者的比较和使用,能够参见这里

  3. 建立主窗口用 Tkinter.Tk(),可是有的时候须要有一些子窗口,能够用 Tkinter.Toplevel() 来建立,保证子窗口一建立出来就在全部窗口的最前面。当运行完某个回调函数须要找回焦点的时候能够用全部元件都有的方法 focus(),来获得某个元件的焦点。
  4. 窗口退出的时候,能够用方法 quit(),也能够用 destroy(),好比:

    root.quit()
  5. 若是某个元件须要更新,好比图片刷新,能够先调用 destroy() 这个方法摧毁掉这个元件,再将这个元件重建。若是只是 Label 元件的文字上的变更(好比状态栏的文字变化),能够用 StringVar(),须要输入什么直接调用 set() 方法就能够了,以下:

    v = Tkinter.StringVar()
    Tkinter.Label(master, textvariable=v).pack()
    v.set("New Text!")
  6. 菜单栏的建立比较麻烦,以下:

    from Tkinter import *
     root = Tk()
    
     def hello():
         print('hello')
    
     def about():
         print('我是开发者')
    
     menubar = Menu(root)
    
     #建立下拉菜单File,而后将其加入到顶级的菜单栏中
     filemenu = Menu(menubar,tearoff=0)
     filemenu.add_command(label="Open", command=hello)
     filemenu.add_command(label="Save", command=hello)
     filemenu.add_separator()
     filemenu.add_command(label="Exit", command=root.quit)
     menubar.add_cascade(label="File", menu=filemenu)
    
     #建立另外一个下拉菜单Edit
     editmenu = Menu(menubar, tearoff=0)
     editmenu.add_command(label="Cut", command=hello)
     editmenu.add_command(label="Copy", command=hello)
     editmenu.add_command(label="Paste", command=hello)
     menubar.add_cascade(label="Edit",menu=editmenu)
     #建立下拉菜单Help
     helpmenu = Menu(menubar, tearoff=0)
     helpmenu.add_command(label="About", command=about)
     menubar.add_cascade(label="Help", menu=helpmenu)
    
     #显示菜单
     root.config(menu=menubar)
    
     mainloop()

    其中 tearoff=0 就是下拉菜单和窗口是一体的,不能独立造成一个窗口,效果以下:

    若是 tearoff=1,则效果以下,点击那个虚线会造成一个新的窗口。

  7. 简单的提示窗口(好比报错之类的),能够直接调用 tkMessageBox 库,具体用法能够参见这里。简单的数字输入、文件选取、颜色选取,能够直接调用 tkSimpleDialog 库,具体用法能够参见这里
  8. Tkinter 自带的下拉框元件 Listbox 很很差用,可使用 ttk 库中的 Combobox 元件,使用以下:

    boudrate=Tkinter.StringVar()
    boudrate.set("9600")
    manul_boudrate=ttk.Combobox(root,text=boudrate,values=["2400","9600","12900"])

    须要获得 Combobox 中选中的字符串的时候,直接 boudrate.get() 就能够了。

相关文章
相关标签/搜索