Python GUI:Tkinter ——1

Tkinter 是 Python 开发 GUI 应用的利器,也是被众多程序猿吐槽的对象。他是创造 ugly GUI 的代名词,同时也是开发小工具的福音。最近,从来没有开发过 GUI 的我也开始开发一款小工具啦,但在此之前,我觉得要学一下 GUI 开发。 于是,我的眼光投入到 Python 内置的 GUI 开发模块——Tkinter 中。

下面我只列出代码,不一一解释各个控件的意义。显然,开始做,而后开始想,才是学习一门技术的正确途经。因此,我希望我传播的也是这样一种理念,希望能够为各位先要开发小工具的人们,做一点绵薄的贡献。

那么,现在开始吧:
首先是成品的样子:
在这里插入图片描述
之后是代码:

import tkinter as tk
from tkinter import ttk
win = tk.Tk()    #创建一个主窗口,所有空间都在上面(面向对象的实例化啦)
win.title('标题')    #调用 title 属性,设置标题
# win.resizable(0,0)    #这个是设置窗口不可缩放
ttk.Label(win,text='Please put a name').grid(column=0,row=0)    #设置一个标签,位置是主窗口的第一行,第一列
"""这里注意,我用的是 grid 来管理 GUI 空间的布置的。大家可以把主窗口看成一个“动态”的网格,比如现在,窗口有1列1行"""

def clickMe():    #这里是定义 按键 空间的触发函数
    aButton.configure(text='hello'+name.get()+aCombobox.get())   
     #由于控件是 callback的,所以可以在的实例化对象前,直接调用
     #这跟普通的 Python 语法不同,因为 Python 是顺序执行的。所以,要看懂?请往下
     # 这就是所谓的“骚操作”了吧,反正只要记住,空间都是 callback 的就行了
 
name = tk.StringVar()    #这个亦不是 Python 语法了。因为 Python 是动态类编程,也就是不用“声明”就可以使用函数
# 但是,这里由于用的是 tkinter而非Python,所以不能这么做。换句话说,Python 只是调用 tk 这个 API 而已
aEntry = ttk.Entry(win,textvariable=name)    #win为控件的 master,即放在win上。textvaiable可以获取 Entry 的输入。另外,Entry 是一个输入文本的空间,相当于 HTML 的 <text>。
aEntry.grid(column=0,row=1)    #设置它的位置在第二行第一列,即前一个 Label 的下方

number = tk.StringVar()    #指定类型(声明)
aCombobox = ttk.Combobox(win,textvariable=number)    #创建一个下拉框,参数为 number
aCombobox['values']=(1,2,4,8)    #设置下拉框的可选值
aCombobox.grid(column=1,row=1)    #设位置
aCombobox.current(0)    #设置下拉框当前选的值,现在为1,若参数为1,则选的是2,若为2,则选的是4
# 下拉框可以被用户修改,当然,我们可以在实例化对象时,初始化参数 state = 'readonly',即不可被用户输入
   
aButton = ttk.Button(win,text='click me',command=clickMe)    #实例化一个按键控件,command选择触发函数,函数不用、也不可以加括号。注意,第一个参数与 Label 相同,是指 Master,也就是空间放在哪个窗口上,这里当然是主窗口啦
aButton.grid(column=2,row=1)    #前面说过,动态网格,所以现在主窗口是一行,二列。
"""grid 中的每一行,其列数和列的长度,都由最多、最长的列决定。
当然,可以用 .grid(row=2,column=0,columnspan=2)来避免"""
# aButton.configure(state='disable')    这句话能够让控件不可点击(不可用)



aFlag = tk.IntVar()    #声明一个 aFlag 变量,类型为 Int,下同
bFlag = tk.IntVar()
cFlag = tk.IntVar()
aCheckbutton = tk.Checkbutton(win,variable=aFlag,state='disable',text='Disable')  
#实例化一个 复选框 对象,设置其不可选中(state),其输出变量为 aFlag,方框后面的文字为 “Disable”
#若复选框被选中,则 aFlag = 1 否则为 0
aCheckbutton.select()    #令该复选框默认被选中
aCheckbutton.grid(column=0,row=2,sticky=tk.W)    #设置位置
#  sticky 参数为是否对齐,tk.W 是 West 的意思,即左对齐。这里对齐的,是 grid 的网格的 格子,而非整个窗口
bCheckbutton = tk.Checkbutton(win,variable=bFlag,text='Enable')
bCheckbutton.select()
bCheckbutton.grid(column=1,row=2,sticky=tk.W)
cCheckbutton = tk.Checkbutton(win,variable=cFlag,text='No')
cCheckbutton.deselect()   #令复选框默认不选中
cCheckbutton.grid(column=2,row=2,sticky=tk.W)

"""以下代码设置单选框(圆框),单选框只能选择一个,重复选择会撤销上一个选择"""
"""因此,和复选框不一样,多个圆框不需要多个变量,他们可以共用,设置 value 参数可以更改值。
因此,就这一点来说,他们可以用循环来实现。
下面被注释掉的代码,不用循环实现"""

# COLOR1='Blue'    
# COLOR2='Gold'
# COLOR3='Red'
# radVar = tk.IntVar()
# def clickRadio():
#     flag = radVar.get()
#     if flag==1: 
#         win.configure(background=COLOR1)
#     elif flag==2:
#         win.configure(background=COLOR2)
#     elif flag==3:
#         win.configure(background=COLOR3)

# aRadiobutton = tk.Radiobutton(win,variable=radVar,text=COLOR1,value=1,command=clickRadio)
# aRadiobutton.grid(column=0,row=3,sticky=tk.W)
# bRadiobutton = tk.Radiobutton(win,text=COLOR2,variable=radVar,value=2,command=clickRadio)
# bRadiobutton.grid(column=1,row=3,sticky=tk.W)
# cRadiobutton = tk.Radiobutton(win,text=COLOR3,variable=radVar,value=3,command=clickRadio)
# cRadiobutton.grid(column=2,row=3,sticky=tk.W)
"""循环实现"""
COLOR = ['Blue','Gold','Red']    #设置颜色
radVar = tk.IntVar()    #声明
radVar.set(99)    #初始化值,如果不初始化,这某个圆框会被 默认 选中
def clickRadio():    #圆框选择触发事件
    flag = radVar.get()
    if flag==0:    
        win.configure(background=COLOR[0])    #修改 主窗口 的背景颜色
    elif flag==1:
        win.configure(background=COLOR[1])
    elif flag==2:
        win.configure(background=COLOR[2])
        
for col in range(3):
    rad = 'Rad'+ str(col)    #这个用于设置 对象名
    rad = tk.Radiobutton(win,variable=radVar,value=col,text=COLOR[col],command=clickRadio)
    #实例化一个圆框对象,设置变量为 radVar。被选中时,其值设置为 col。 设置 圆框后面的字符为 COLOR
    # 设置触发事件为 clickRadio 函数
    rad.grid(column=col,row=3,sticky=tk.W)    #设置位置,且左对齐

from tkinter import scrolledtext    #scrolledtext 可以输入很长的文本,并自动换行。还会生成一个滚动条
srcW = 40    #宽度变量(不想违背 DRY 原则,这是我的习惯,可以不管)
srcH = 3    #高度变量
scrVar = tk.StringVar()   #声明
aScrtxt = scrolledtext.ScrolledText(win,width=srcW,height=srcH,
                                    wrap=tk.WORD)    #实例化一个 scrolledtext 对象
# 其中 wrap 参数用于设置分割。tk.WORD 为换行分割以单词为单位。wrap默认值为 tk.CHAR,即换行时以字符为单位                
aScrtxt.grid(column=0,columnspan=3,row=4,sticky=tk.W)    #这里的 columnspan 是为了让其独占三格
aScrtxt.focus()    #窗口被打开时,将鼠标的角点移动到这个空间。

aLabelFrame = ttk.LabelFrame(win,text='A label frame')    #初始化一个 LabelFrame
aLabelFrame.grid(column=0,row=5,sticky=tk.W)    
"""Frame相当于一个小窗口,可以作为其他空间的 Master,并且在Frame里面,grid 是另起的"""
ttk.Label(aLabelFrame,text='label1').grid(column=0,row=0)    #设置Master为aLabelFrame,grid此时另起
ttk.Label(aLabelFrame,text='label2').grid(column=0,row=1)
ttk.Label(aLabelFrame,text='label3').grid(column=0,row=2)
win.mainloop()     #这个一定要加。窗口是一个无限的循环。这个循环用来接收空间中的所有事件。比如鼠标一点等等。

大家可以尝试将 aLabelFrame 中某一个控件的 text 改长一点。可以发现,太长的话,会导致一整列都变得很宽,导致整个版面变得非常难看。如何避免这种情况呢?请看下一篇:Python GUI:Tkinter——2

猜你喜欢

转载自blog.csdn.net/weixin_42141390/article/details/106398665
今日推荐