【Python Gui】Tkinter 的入门学习

一、前面的话

Python 提供了多个图形开发界面的库,几个常用 Python GUI 库如下:

  • Tkinter: Tkinter 模块(Tk 接口)是 Python 的标准 Tk GUI 工具包的接口 .Tk 和 Tkinter 可以在大多数的 Unix 平台下使用,同样可以应用在 Windows 和 Macintosh 系统里。Tk8.0 的后续版本可以实现本地窗口风格,并良好地运行在绝大多数平台中。

  • wxPython:wxPython 是一款开源软件,是 Python 语言的一套优秀的 GUI 图形库,允许 Python 程序员很方便的创建完整的、功能健全的 GUI 用户界面。

  • Jython:Jython 程序可以和 Java 无缝集成。除了一些标准模块,Jython 使用 Java 的模块。Jython 几乎拥有标准的Python 中不依赖于 C 语言的全部模块。比如,Jython 的用户界面将使用 Swing,AWT或者 SWT。Jython 可以被动态或静态地编译成 Java 字节码。

本文仅以Tkinter为例,说说吧。很多年前,学过QT,当年貌似还在使用C++,了解过Qt-designer 以及 Qt-creator ,并且用它完成了个人毕业设计,至此,再也没有用过Qt。最近这些年一直忙于后台,其实会点界面知识也挺好,写点小工具方便自己。仅以此篇作为我Python gui的入门吧。

Tkinyer 和Qt 很多方面还是很类似的,有很多方便的组件,标签、列表、按钮等等。。。。而Qt 可以自己手动拖拽,这点其实要比Tkinyer要强的。不过谁让python是这么流行的语言呢!

二、Tkinter组件

Tkinter 组件

Tkinter的提供各种控件,如按钮,标签和文本框,一个GUI应用程序中使用。这些控件通常被称为控件或者部件。

目前有15种Tkinter的部件。我们提出这些部件以及一个简短的介绍,在下面的表:

控件 描述
Button 按钮控件;在程序中显示按钮。
Canvas 画布控件;显示图形元素如线条或文本
Checkbutton 多选框控件;用于在程序中提供多项选择框
Entry 输入控件;用于显示简单的文本内容
Frame 框架控件;在屏幕上显示一个矩形区域,多用来作为容器
Label 标签控件;可以显示文本和位图
Listbox 列表框控件;在Listbox窗口小部件是用来显示一个字符串列表给用户
Menubutton 菜单按钮控件,由于显示菜单项。
Menu 菜单控件;显示菜单栏,下拉菜单和弹出菜单
Message 消息控件;用来显示多行文本,与label比较类似
Radiobutton 单选按钮控件;显示一个单选的按钮状态
Scale 范围控件;显示一个数值刻度,为输出限定范围的数字区间
Scrollbar 滚动条控件,当内容超过可视化区域时使用,如列表框。.
Text 文本控件;用于显示多行文本
Toplevel 容器控件;用来提供一个单独的对话框,和Frame比较类似
Spinbox 输入控件;与Entry类似,但是可以指定输入范围值
PanedWindow PanedWindow是一个窗口布局管理的插件,可以包含一个或者多个子控件。
LabelFrame labelframe 是一个简单的容器控件。常用与复杂的窗口布局。
tkMessageBox 用于显示你应用程序的消息框。

1、tk初始

 这是一切的根源,你想要完成一个gui,他是地板,然后在上面进行扩展。

#!/usr/bin/python
# -*- coding: UTF-8 -*-
 
import Tkinter
top = Tkinter.Tk()
# 进入消息循环
top.mainloop()

tkwindow                

2、按钮  

这个有点类似于  Qt- 的信号-槽函数 的关系,点击button触发到事件。

#!/usr/bin/python
# -*- coding: UTF-8 -*-
 
import Tkinter
import tkMessageBox
 
top = Tkinter.Tk()
 
def helloCallBack():
   tkMessageBox.showinfo( "Hello Python", "Hello Runoob")
 
B = Tkinter.Button(top, text ="点我", command = helloCallBack)
 
B.pack()
top.mainloop()

3、标签 & 输入框

#!/usr/bin/python
# -*- coding: UTF-8 -*-

from Tkinter import *

top = Tk()
L1 = Label(top, text="网站名")
L1.pack(side=LEFT)
E1 = Entry(top, bd=5)
E1.pack(side=RIGHT)

top.mainloop()

三、Tk实战

《代码暂时不放出来了,之后再放吧》

1、翻译器

#!/usr/bin/python
# -*- coding: UTF-8 -*-

from  Tkinter import *
import tkMessageBox
import requests

# 定义button事件
def translation():
    content=entry.get()
    if  content == '':
        tkMessageBox.showinfo("提示", "请输入需要翻译的内容")
    else:
        print content
    header = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36'}
    url = "http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule"
    # url = "http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule"
    data = {}
    data['i'] = content
    data['from'] = 'AUTO'
    data['to'] = 'AUTO'
    data['smartresult'] = 'dict'
    data['client'] = 'fanyideskweb'
    # data['salt'] = '1530332652360' # 时间戳
    # data['sign'] = '7f281888e41d12a63b20790707672708'
    data['doctype'] = 'json'
    data['version'] = '2.1'
    data['keyfrom'] = 'fanyi.web'
    data['action'] = 'FY_BY_CLICKBUTTION'
    data['typoResult'] = 'false'
    result = requests.post(url,data=data,headers=header)
    translation = result.json()
    translation = translation['translateResult'][0][0]['tgt']
    print(translation)
    res.set(translation)


root = Tk()
#1、窗口标题

res = StringVar()

root.title('中英文互译')
#2、窗口大小,显示位置
root.geometry('290x100+573+286')
#3、标签控件
lable = Label(root,text='输入要翻译的文字',font=('微软雅黑',10), fg='black')
lable.grid()

lable = Label(root,text='翻译结果',font=('微软雅黑',10), fg='black')
lable.grid()

#4、输入控件
entry=Entry(root, font='微软雅黑')
entry.grid(row=0,column=1)
#显示翻译之后的内容
entry2=Entry(root, font='微软雅黑', textvariable=res)
#输入标签位置
entry2.grid(row=1,column=1)

#5、按钮控件
button = Button(root, text ="翻译",width=10,font=('微软雅黑',10),command=translation)
button.grid(row=2,column=0,sticky=W)

button = Button(root, text ="退出",width=10,font=('微软雅黑',10), command=root.quit)
button.grid(row=2,column=1,sticky=E)

#-----------------至此,界面已经画出来了---------------------------

root.mainloop()

2、音乐下载器

# -*- coding:utf-8 -*-
from tkinter import *
import  requests
from bs4 import BeautifulSoup
# 根据链接下载歌曲
import urllib
import os

def mkdir(path):
    # 去除首位空格
    path = path.strip()
    # 去除尾部 \ 符号
    path = path.rstrip("\\")

    isExists = os.path.exists(path)
    if not isExists:
        # 创建目录操作函数
        os.makedirs(path)
        print path + ' 创建成功'
        return True
    else:
        # 如果目录存在则不创建,并提示目录已存在
        print path + ' 目录已存在'
        return False

# 定义要创建的目录
mkpath = "D:\\music\\"
# 调用函数
mkdir(mkpath)


#网易云音乐为我们提供了一个根据歌曲 id 来下载歌曲的地址
#http://music.163.com/song/media/outer/url?id=543710263
def download_song():
    # 1.获取用户输入的url下载链接
    url = entry.get()
    # http://music.163.com/song/media/outer/url?id=543710263
    # 2.获取源代码
    # http://music.163.com/playlist?id=2302867766
    header = {
        'Host': 'music.163.com',
        'Referer': 'http://music.163.com/',
        'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36'
    }
    html = requests.get(url, headers=header).text
    # 3.创建对象,解析网页,获取的s的数据类型成为一个对象,并且显示的html代码格式变得清晰了
    s = BeautifulSoup(html, 'html.parser')
    # print(s)
    # 3.获取id
    muisc_dict = {}
    result = s.find('ul', {'class', 'f-hide'}).find_all('a')
    # print(result)
    for music in result:
        muisc_id = music.get('href').strip('/song?id=')
        music_name = music.text
        muisc_dict[muisc_id] = music_name
    # print(muisc_dict)

    for song_id in muisc_dict:
        #song_url = 'http://music.163.com/playlist?id=%s' % song_id
        song_url = 'http://music.163.com/song/media/outer/url?id=%s' % song_id
        # 下载路径
        path = 'D:\\music\\%s.mp3' % muisc_dict[song_id]

        # 添加数据到列表框的最后
        text.insert(END, '正在下载:%s' % muisc_dict[song_id])
        # 文本框向下滚动
        text.see(END)
        # 更新(不更新就一直卡在那,显示同样的内容)
        text.update()

        # 下载歌曲
        urllib.urlretrieve(song_url, path)

    text.insert(END,"下载完毕")

# 1.创建窗口
root = Tk()

# 2.窗口标题
root.title('网易云音乐')

# 3.窗口大小以及显示位置,中间是小写的x
root.geometry('550x400+550+230')
# 窗口显示位置
# root.geometry('+573+286')

# 4.标签控件
lable = Label(root,text='请输入要下载的歌单URL:',font=('微软雅黑',10))
lable.grid(row=0,column=0)

# 5.输入控件
entry =Entry(root,font=('微软雅黑',25))
entry.grid(row=0,column=1)

# 6.列表框控件
text = Listbox(root,font=('微软雅黑',16),width=45,height=10)
# columnspan组件所跨越的列数
text.grid(row=1,columnspan=2)

# 7.按钮控件
button = Button(root,text='开始下载',width=10,font=('微软雅黑',10),command=download_song)
button.grid(row=2,column=0,sticky=W)

button1 = Button(root,text='退出',width=10,font=('微软雅黑',10),command=root.quit)
button1.grid(row=2,column=1,sticky=E)

# 消息循环,显示窗口
root.mainloop()

四、Python 打包发布

我们知道,C++生成的exe 有自己打包工具:advanced installer,那么python也有自己打包工具:pyinstaller.exe ,

  • 首先安装pyinstaller,生成在环境目录:Scripts
  • 在搜索框输入cmd
  • 执行  pyinstaller -F  -w   XXX.py
  • 生成可执行文件exe在 dist目录下面

五、效果展示

六、参考地址

http://www.runoob.com/python/python-gui-tkinter.html

https://gitbook.cn/books/5b4d510905a002571926ed7e/index.html

引用知乎:

作者:Naples
链接:https://www.zhihu.com/question/32703639/answer/165326590
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
 

先说下我个人的情况,使用Matlab已3年有余,期间编写过几个专业方面的计算程序以及做过数个地铁振动信号处理分析方面的项目,有一定的编程基础。大概4个月前正式学习Python,用了2个月时间过了一遍Python的基本知识及语法,然后用了2~3天(课余时间)的时间仿照扇贝网背诵英语单词的模式,写了一个背诵日语单词的软件Anki的底层代码(200余句),输入输出都在shell里,用起来很不方便。然后开始尝试GUI,首先选择的就是Python自带的Tkinter,然后在网上找了Tkinter的相关文档:第一份是Tkinter简明教程,不知所云,几乎没什么帮助;第二份是2014年度辛星Tkinter教程第二版,内容浅显易懂;第三份是Python GUI Programming Cookbook,内容详细,帮助很大。大概用了5-6天的时间,边看文档写出了带有简单GUI界面的Anki2.0。又经过之后的组件升级,增加了许多功能,更新到了Anki3.2。先上图:

先上结论:Tkinter真的不像大家说的那么差,基本的功能都能实现,而且简单易学容易上手。对于界面颜值没有太高要求的,用Tkinter写GUI是不错的选择。

1、组件

本软件中用到了大概5个组件:

1.1、Button按钮

语法如下:创建了名为Play播放的按钮,绑定了命令sound_play。

b1 = ttk.Button(xin, text = 'Play\n播放',  width = 10, command = sound_play)
b1.grid(row=3,column=4, padx=10, pady=10)

1.2、Label标签

语法如下:创建了名为Model的标签。

mm1 = ttk.Label(xin, text = 'Model')
mm1.grid(row=0,column=1)

1.3、Combobox下拉列表

number = tk.StringVar()
LessonChosen = ttk.Combobox(xin, width=12, textvariable=number, state='readonly')
LessonChosen['values'] = lesson_name     # 设置下拉列表的值
LessonChosen.grid(column=2, row=1)      # 设置其在界面中出现的位置  column代表列   row 代表行
LessonChosen.current(lesson_name.index(str(WW[0])))    # 设置下拉列表默认显示的值,0为 LessonChosen['values'] 的下标值

1.4、LabelFrame

labelframe1 = ttk.LabelFrame(xin, text='単語    (第    课,第    个单词)', height = 80, width=300) # 信息区
labelframe1.grid(row=3,column=1, columnspan = 3 , padx=10, pady=10) 
labelframe1.propagate(0) # 使组件大小不变,此时width才起作用
ttk.Label(labelframe1, text = "  ",font = ('Mincho, 20')).pack(fill="both", expand="yes")

1.5、Radiobutton单选按钮

#单选按钮radiobutton
v=tk.IntVar()  
v.set(1)
#f1.bind('<KeyPress-1>',word_know)
f1 = tk.Radiobutton(xin,text = 'Know', font =24, variable=v,value=1, command = word_know)  
f1.grid(row=6,column=2)
f1.configure(state='disabled')
#f2.bind('<KeyPress-2>',word_unknow)
f2 = tk.Radiobutton(xin,text = 'Unknow',font =24,variable=v,value=2, command = word_unknow)  
f2.grid(row=6,column=3)
f2.configure(state='disabled')

下面贴一段与『Play播放』按钮绑定的sound_play函数的命令:

#Play按钮
def sound_play():
    import winsound
    import time
    import os
    global xin
    global word_list
    if back_canshu == 0:
        if len(word_list_now)==0:
            showinfo(title = 'Message', message = '恭喜,本次单词已经背完!')
            if BSM == 0:
                word_list1 = [R[1:3]]
                for i in range(len(word_list)):
                    if len(word_list[i])>=6:
                        if word_list[i][5]!='':
                            word_list1.append(word_list[i])
                del word_list
                word_list =word_list1
                #保存file.txt
                import os
                os.remove(r'.\file.txt')
                #写出单词表信息
                write_file_word(word_list,r'.\file.txt')
        else:
            if len(word_list_now)>=1:
                lesson = int(word_list_now[0][0])
                mn = int(word_list_now[0][1])
                if os.path.exists(r".\audio\L"+str(lesson)+"\L"+str(lesson)+"_"+str(mn)+".wav")==False:
                    winsound.PlaySound(r".\audio\Windows_Background.wav", winsound.SND_FILENAME|winsound.SND_ASYNC)
                    #第三行:labelframe单词
                    labelframe1 = ttk.LabelFrame(xin, text='単語    (第 '+str(lesson)+' 课,第 '+str(mn)+' 个单词)', height = 80, width=300) # 信息区
                    labelframe1.grid(row=3,column=1, columnspan = 3 , padx=10, pady=10) 
                    labelframe1.propagate(0) # 使组件大小不变,此时width才起作用
                    ttk.Label(labelframe1, text = word_list_now[0][2], font = ('Mincho, 20')).pack(fill="both", expand="yes")
                else:
                    winsound.PlaySound(r".\audio\L"+str(lesson)+"\L"+str(lesson)+"_"+str(mn)+".wav", winsound.SND_FILENAME|winsound.SND_ASYNC)
    else:
        lesson = int(word_back[-back_canshu][0])
        mn = int(word_back[-back_canshu][1])
        if os.path.exists(r".\audio\L"+str(lesson)+"\L"+str(lesson)+"_"+str(mn)+".wav")==False:
            winsound.PlaySound(r".\audio\Windows_Background.wav", winsound.SND_FILENAME|winsound.SND_ASYNC)
        else:
            winsound.PlaySound(r".\audio\L"+str(lesson)+"\L"+str(lesson)+"_"+str(mn)+".wav", winsound.SND_FILENAME|winsound.SND_ASYNC)

2、软件封装打包

Python Tkinter打包封装的方法有:PyInstaller, py2exe, wxPython等方法。答主只是用了PyInstaller来打包,感觉特别好用,对其它方法不做评论。

网上有很多打包方法:Python | 用Pyinstaller打包发布exe应用,请自行参考!

要说的是,打包过程中可以添加如下指令,自行尝试打包后的差异:

-w指令,在指令内加入-w命令可以屏蔽发布的exe应用带命令行调试窗口;

-F指令,使用-F指令可以把应用打包成一个独立的exe文件,否则是一个带各种dll和依赖文件的文件夹;

-i指令,可以自定义图标。

简单写一下用pyinstaller打包软件的过程:

①准备好打包文件:

aiueo.py为代码,audio文件夹、tango文件夹和file.txt为程序关联调用的文件,a.ico为软件图标。

②在安装的Python文件夹下的Scripts目录下(包含pyinstaller.exe),shift+右键>>在此处打开命令窗口:

③输入:pyinstaller.exe -i C:\Users\Naples\aiueo\a.ico -w C:\Users\Naples\aiueo\aiueo.py 回车。

-i C:\Users\Naples\aiueo\a.ico 为图标所在的目录;

-w C:\Users\Naples\aiueo\aiueo.py 为程序所在目录。

④在C:\Python34\Scripts目录下就会出现这三个文件:

可以将第一、三个文件删除,只留下dist文件夹。将和程序关联的audio文件夹、tango文件夹和file.txt三个文件夹拷贝到dist/aiueo/目录下。双击aiueo.exe,程序就可以使用了。

可以发送桌面快捷方式,也可以将软件打包拷贝到相同平台下的电脑上使用。


 

软件是根据2017年度赴日留学博士班基础日语教程《実力日本語》编写,包含了基础日语L1~L60课的单词和录音,感兴趣的可以尝试下载,链接:http://pan.baidu.com/s/1i4O3gRN 密码:a8kq

Python教程:

Tkinter简明教程:http://pan.baidu.com/s/1o8v3baq

2014年度辛星Tkinter教程第二版:http://pan.baidu.com/s/1hr6ortE

Python GUI Programming Cookbook:http://pan.baidu.com/s/1eSimgQA

猜你喜欢

转载自blog.csdn.net/vevenlcf/article/details/82226531