Tkinter全网最全笔记

前言

Tkinter模块(“Tk 接口”)是Python的标准Tk GUI工具包的接口,

Tk和Tkinter可以在大多数的Unix平台下使用,同样可以应用在Windows和Macintosh系统里,

Tk8.0的后续版本可以实现本地窗口风格,并良好地运行在绝大多数平台中。

上手简单,适合新手入手GUI编程

本博客诸多内容参考自:https://www.cnblogs.com/yudanqu/p/9467803.html

常见问题

设置窗口大小不可变

window.resizable(width=False, height=False)# 窗口大小不可改变

设置组件不可用

btn1.state(['disabled'])
btn1.state(['!disabled'])
btn1['state'] = DISABLED   ###禁用
btn1['state'] = NORMAL

好看的字体

font=('Microsoft YaHei', 10)

好看的颜色

在线查看颜色:https://encycolorpedia.cn/html

颜色参看:https://blog.csdn.net/chl0000/article/details/7657887
在这里插入图片描述

Entry如何插入或删除数据

import tkinter as tk

win = tk.Tk()
# e输入框显示字符串:木芙蓉
def _show():
    e.insert(0, '木芙蓉')
# 清空e输入框中的内容
def _clear():
    e.delete(0, tk.END)
var = tk.StringVar()
e = tk.Entry(win, textvariable=var)
e.pack()
b_show = tk.Button(win, text='显示木芙蓉', command=_show)
b_show.pack()
b_clear = tk.Button(win, text='清空', command=_clear)
b_clear.pack()

win.mainloop()

Text如何插入或删除数据

获取Text文本内容:text.get('0.0','end')
该方式表示获取text中现有的全部内容;

设置Text文本内容:
text.insert('end',s):该方法是将s插入到text的末尾,原来的内容不变;
text.insert('insert',s);该方法是将s插入到鼠标点击的地方;
text.insert(1.1, var)  #表示在第一行第一位显示

删除Text文本内容:
text.delete('1.0','end'):该方法是将text文本内的内容全部清空。

三种布局方式布局方式

全局只能使用一种方式,笔者喜欢place

详情参考:https://blog.csdn.net/diaoweisang7683/article/details/101968216

绝对布局place

绝对布局(绝对布局,窗口的变化对位置没有影响)

label1.place(x=10,y=10)

相对布局pack

相对布局,窗体改变对控件有影响

label2.pack(fill=tkinter.X, side=tkinter.TOP)

表格布局grid

label.grid(row=1,column=1)

如何放置图片

import tkinter as tk

window = Tkinter.Tk()
image_file1 = tk.PhotoImage(file='./data/bg5.png')
l1=tk.Label(window,image=image_file1)
l1.place(x=-2,y=0)
window.mainloop()

如何询问文件路径

from tkinter.filedialog import askopenfilename
filename = askopenfilename()
print(filename)

如何修改label、button的text

label['text'] = '修改后'

设置界面初始的桌面位置

这里的100、200,表示相对于桌面的x=100,y=200

window.geometry("400x400+100+200")

面向对象设计GUI

import tkinter as tk
from tkinter import ttk

class Program(tk.Tk):        
    def __init__(self, *args, **kwargs):   
        tk.Tk.__init__(self, *args, **kwargs)

        container = tk.Frame(self)
        container.pack(side="top", fill="both", expand=True)
        container.grid_rowconfigure(0, weight=1)
        container.grid_columnconfigure(0, weight=1)
        container.grid_rowconfigure(2, weight=1)
        container.grid_columnconfigure(2, weight=1)

        self.frames = {}
        frame = Login(container, self)
        self.frames[Login] = frame

        frame.grid(row=1, column=1, sticky="nsew")

        for F in (Login, AdminHome):

            frame = F(container, self)
            self.frames[F] = frame
            frame.grid(row = 1, column = 1, sticky = "nsew")

        self.show_frame(Login)

    def show_frame(self,cont):
        frame = self.frames[cont]
        frame.tkraise()

class Login(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)

        name = tk.Label(self, text = "Program")
        name.grid(row=0, columnspan=5, sticky="W"+"E")

        username = tk.Label(self, text="Username: ")
        username.grid(row=1, columnspan=2, sticky="W")

        user = ttk.Entry(self, text ="", width=45)
        user.grid(row=1, column=2 ,columnspan=3, sticky="w")

        password = tk.Label(self, text="Password: ")
        password.grid(row=2, columnspan=2, sticky="W")

        passentry = ttk.Entry(self, text ="", width=45)
        passentry.grid(row=2, column=2 ,columnspan=3, sticky="W")

        loginb = ttk.Button(self, text = "Login", command = lambda: controller.show_frame(AdminHome))
        loginb.grid(row=3, columnspan=5, sticky="W"+"E")

class AdminHome(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)

        name = tk.Label(self, text = "Admin Home")
        name.grid(row=0, sticky="W")

        name = tk.Label(self, text = "FirstName + LastName")
        name.grid(row=0, column=5 ,sticky="E")

        update = ttk.Button(self, text = "Update Online", command = lambda: controller.show_frame(AdminHome))
        update.grid(row=1, columnspan=6, sticky="W"+"E")

        fetch = ttk.Button(self, text = "Fetch Data", command = lambda: controller.show_frame(AdminHome))
        fetch.grid(row=2, columnspan=6, sticky="W"+"E")

        a = ttk.Button(self, text = "a", command = lambda: controller.show_frame(AdminHome))
        a.grid(row=3, columnspan=2, sticky="W"+"E")

        b = ttk.Button(self, text = "b", command = lambda: controller.show_frame(AdminHome))
        b.grid(row=3, column=2, columnspan=2, sticky="W"+"E")

        c = ttk.Button(self, text = "c", command = lambda: controller.show_frame(AdminHome))
        c.grid(row=3, column=4, columnspan=2, sticky="W"+"E")

        edit = ttk.Button(self, text = "Edit Details", command = lambda: controller.show_frame(AdminHome))
        edit.grid(row=4, columnspan=6, sticky="W"+"E")

app = Program()
app.state('zoomed')
app.mainloop()

组件使用示例

1、简单实例

下面的代码是创建出一个窗口,其他的操作就在这个平台上进行。执行之后会在桌面弹出一个窗口,窗口的标题就是代码中设置的win.title。

import tkinter

# 创建主窗口
win = tkinter.Tk()
# 设置标题
win.title("yudanqu")
# 设置大小和位置
win.geometry("400x400+200+50")

# 进入消息循环,可以写控件
win.mainloop()

2、Label控件

import tkinter

win = tkinter.Tk()
win.title("yudanqu")
win.geometry("400x400+200+50")

'''
Label:标签控件,可以显示文本
'''
# win:父窗体
# text:显示的文本内容
# bg:背景色
# fg:字体颜色
# font:字体
# wraplength:指定text文本中多宽之后换行
# justify:设置换行后的对齐方式
# anchor:位置 n北,e东,w西,s南,center居中;还可以写在一起:ne东北方向
# 属性relief为控件呈现的3D浮雕样式,有FLAT(平的)、RAISED(凸起的)、SUNKEN(凹陷的)、GROOVE(沟槽状边缘)和RIDGE(脊状边缘)5种。
# must be flat, groove, raised, ridge, solid, or sunken
label = tkinter.Label(win,
                      text="this is a word",
                      bg="pink", fg="red",
                      font=("黑体", 20),
                      width=20,
                      height=10,
                      wraplength=100,
                      justify="left",
                      anchor="ne")

# 显示出来
label.pack()

win.mainloop()

3、Button控件

'''
按钮控件:指定关联事件
'''
import tkinter

win = tkinter.Tk()
win.title("yudanqu")
win.geometry("400x400+200+50")

def func():
    print("aaaaaaaaaaaaaaaaaaaaaaa")
# 创建按钮
button1 = tkinter.Button(win, text="按钮", command=func, width=10, height=10)
button1.pack()

button2 = tkinter.Button(win, text="按钮", command=lambda: print("bbbbbbbbbbbb"))
button2.pack()

button3 = tkinter.Button(win, text="退出", command=win.quit)
button3.pack()


win.mainloop()

4、Entry控件

'''
文本控件:用于显示单行文本
'''
import tkinter as tk

window = tk.Tk()
window.title('My Window')
window.geometry('500x300')
# 第4步,在图形界面上设定输入框控件entry并放置控件
# 添加invalidcommand属性绑定输入事件
e1 = tk.Entry(window, show='*', font=('Arial', 14))  # 显示成密文形式
e2 = tk.Entry(window, show=None, font=('Arial', 14))  # 显示成明文形式
e1.pack()
e2.pack()
# 第5步,主窗口循环显示
window.mainloop()

5、点击按钮输出输入框中的内容

import tkinter

win = tkinter.Tk()
win.title("yudanqu")
win.geometry("400x400+200+50")

def showinfo():
    # 获取输入的内容
    print(entry.get())

entry = tkinter.Entry(win)
entry.pack()
button = tkinter.Button(win, text="按钮", command=showinfo)
button.pack()

win.mainloop()

6、Text控件

'''
文本控件:用于显示多行文本
'''
import tkinter

win = tkinter.Tk()
win.title("yudanqu")
win.geometry("400x400+200+50")

# height表示的是显示的行数
text = tkinter.Text(win, width=30, height=10)
text.pack()

str = '''盖闻天地之数,有十二万九千六百岁为一元。'''

text.insert('end', str)
win.mainloop()

7、带滚动条的Text

import tkinter

win = tkinter.Tk()
win.title("yudanqu")
# win.geometry("400x400+200+50")



# 创建滚动条
scroll = tkinter.Scrollbar()

text = tkinter.Text(win, width=30, height=10)
# side放到窗体的哪一侧,  fill填充
scroll.pack(side=tkinter.RIGHT, fill=tkinter.Y)
text.pack(side=tkinter.LEFT, fill=tkinter.Y)
# 关联
scroll.config(command=text.yview)
text.config(yscrollcommand=scroll.set)
text.pack()

str = '''盖闻天地之数,有十二万九千六百岁为一元。
将一元分为十二会,乃子、丑、寅、卯、辰、巳、午、未、申、酉、戌、亥之十二支也。
每会该一万八百岁。且就一日而论:子时得阳气,而丑则鸡鸣;
寅不通光,而卯则日出;辰时食后,而巳则挨排;
日午天中,而未则西蹉;申时晡而日落酉;
戌黄昏而人定亥。譬于大数,若到戌会之终,则天地昏蒙而万物否矣。
再去五千四百岁,交亥会之初,则当黑暗,而两间人物俱无矣,故曰混沌。
又五千四百岁,亥会将终,贞下起元,近子之会,而复逐渐开明。邵康节曰:“冬至子之半,天心无改移。
一阳初动处,万物未生时。”到此,天始有根。'''

text.insert('end', str)
win.mainloop()

8、Radiobutton圆圈单选框

import tkinter as tk
window = tk.Tk()
window.title('My Window')
window.geometry('500x300')

# 第4步,在图形界面上创建一个标签label用以显示并放置
var = tk.StringVar()  # 定义一个var用来将radiobutton的值和Label的值联系在一起.
var.set('A')#默认选中A
l = tk.Label(window, bg='yellow', width=20, text='empty')
l.pack()


# 第6步,定义选项触发函数功能
def print_selection():
    print(var.get())
    l.config(text='you have selected ' + var.get())


# 第5步,创建三个radiobutton选项,其中variable=var, value='A'的意思就是,当我们鼠标选中了其中一个选项,把value的值A放到变量var中,然后赋值给variable
r1 = tk.Radiobutton(window, text='Option A', variable=var, value='A', command=print_selection)
r1.pack()
r2 = tk.Radiobutton(window, text='Option B', variable=var, value='B', command=print_selection)
r2.pack()
r3 = tk.Radiobutton(window, text='Option C', variable=var, value='C', command=print_selection)
r3.pack()

# 第7步,主窗口循环显示
window.mainloop()

9、Checkbutton方形多选框控件

import tkinter as tk

window = tk.Tk()
window.title('My Window')
window.geometry('500x300')

l = tk.Label(window, bg='yellow', width=20, text='empty')
l.pack()


def print_selection():
    if (var1.get() == 1) & (var2.get() == 0):  # 如果选中第一个选项,未选中第二个选项
        l.config(text='I love only Python ')
    elif (var1.get() == 0) & (var2.get() == 1):  # 如果选中第二个选项,未选中第一个选项
        l.config(text='I love only C++')
    elif (var1.get() == 0) & (var2.get() == 0):  # 如果两个选项都未选中
        l.config(text='I do not love either')
    else:
        l.config(text='I love both')  # 如果两个选项都选中


# 第5步,定义两个Checkbutton选项并放置
var1 = tk.IntVar()  # 定义var1和var2整型变量用来存放选择行为返回值
var2 = tk.IntVar()
c1 = tk.Checkbutton(window, text='Python', variable=var1, onvalue=1, offvalue=0,
                    command=print_selection)  # 传值原理类似于radiobutton部件
c1.pack()
c2 = tk.Checkbutton(window, text='C++', variable=var2, onvalue=1, offvalue=0, command=print_selection)
c2.pack()

# 第7步,主窗口循环显示
window.mainloop()

10、Listbox控件一

import tkinter

win = tkinter.Tk()
win.title("yudanqu")
win.geometry("400x400+200+50")

'''
列表框控件:可以包含一个或多个文本框
作用:在listbox控件的小窗口显示一个字符串
'''

# 创建一个listbox,添加几个元素
lb = tkinter.Listbox(win, selectmode=tkinter.BROWSE)
lb.pack()

for item in ["good", "nice", "handsome", "aaa", "bbb", "ccc", "ddd"]:
    # 按顺序添加
    lb.insert(tkinter.END, item)
# 在开始添加
lb.insert(tkinter.ACTIVE, "cool")

# 将列表当做一个元素添加
# lb.insert(tkinter.END, ["very good", "very nice"])

# 删除:参数1为开始的索引,参数2为结束的索引,如果不指定参数2,只删除第一个索引处的内容
lb.delete(1,3)
# 选中:参数1为开始的索引,参数2为结束的索引,如果不指定参数2,只选中第一个索引处的内容
lb.select_set(2,3)
# 取消选中:参数1为开始的索引,参数2为结束的索引,如果不指定参数2,只取消第一个索引处的内容
lb.select_clear(2)

# 获取到列表中的元素个数
print(lb.size())
# 获取值
print(lb.get(2,3))
# 返回当前的索引项,不是item元素
print(lb.curselection())
# 判断:一个选项是否被选中
print(lb.selection_includes(3))

win.mainloop()

11、Listbox控件二

import tkinter

win = tkinter.Tk()
win.title("yudanqu")
win.geometry("400x400+200+50")

# 绑定变量
lbv = tkinter.StringVar()

# 与BORWSE相似,但是不支持鼠标按下后移动选中位置
lb = tkinter.Listbox(win, selectmode=tkinter.SINGLE, listvariable=lbv)
lb.pack()

for item in ["good", "nice", "handsome", "aaa", "bbb", "ccc", "ddd"]:
    # 按顺序添加
    lb.insert(tkinter.END, item)

# 打印当前列表中的选型
print(lbv.get())

# 设置选项
# lbv.set(("1","2","3"))

# 绑定事件
def myprint(event):
    # print(lb.curselection()) # 返回下标
    print(lb.get(lb.curselection())) # 返回值
lb.bind("<Double-Button-1>", myprint)

win.mainloop()

12、Scale控件

import tkinter as tk
window = tk.Tk()
window.title('My Window')
window.geometry('500x300')

# 第4步,在图形界面上创建一个标签label用以显示并放置
l = tk.Label(window, bg='green', fg='white', width=20, text='empty')
l.pack()

# 第6步,定义一个触发函数功能
def print_selection(v):
    l.config(text='you have selected ' + v)


# 第5步,创建一个尺度滑条,长度200字符,从0开始10结束,以2为刻度,精度为0.01,触发调用print_selection函数
s = tk.Scale(window, label='try me', from_=0, to=10, orient=tk.HORIZONTAL, length=200, showvalue=0, tickinterval=2,
             resolution=0.01, command=print_selection)
s.pack()
s.set(20)
print(s.get())

# 第7步,主窗口循环显示
window.mainloop()

13、Spinbox控件(上下箭头选择数值)

'''
数值范围控件
'''

import tkinter

win = tkinter.Tk()
win.title("yudanqu")
win.geometry("400x400+200+50")


# 绑定变量
v = tkinter.StringVar()

def updata():
    print(v.get())

# increment:步长,默认为1
# values要输入一个元组 最好不要和from和to同时使用,而且步长也没用
# command 只要值改变就会执行updata方法
sp = tkinter.Spinbox(win, from_=0, to=100, increment=5,
                     textvariable=v, command=updata)
# sp = tkinter.Spinbox(win, values=(0,2,4,6,8))
sp.pack()

# 赋值
v.set(20)
# 取值
print(v.get())

win.mainloop()

14、Menu顶层菜单

import tkinter

win = tkinter.Tk()
win.title("yudanqu")
win.geometry("400x400+200+50")

# 菜单条
menubar = tkinter.Menu(win)
win.config(menu=menubar)

def func():
    print("**********")

# 创建一个菜单选项
menu1 = tkinter.Menu(menubar, tearoff=False)

# 给菜单选项添加内容
for item in ['python','c','java','c++', 'c#','php','B','退出']:
    if item == '退出':
        # 添加分割线
        menu1.add_separator()
        menu1.add_command(label=item, command=win.quit)
    else:
        menu1.add_command(label=item, command=func)

# 向菜单条上添加菜单选项
menubar.add_cascade(label='语言', menu=menu1)

win.mainloop()

15、Menu鼠标右键菜单

import tkinter

win = tkinter.Tk()
win.title("yudanqu")
win.geometry("400x400+200+50")

# 菜单条
menubar = tkinter.Menu(win)

def func():
    print("**********")

# 菜单
menu = tkinter.Menu(menubar, tearoff=False)
# 给菜单选项添加内容
for item in ['python','c','java','c++', 'c#','php','B','退出']:
    if item == '退出':
        # 添加分割线
        menu.add_separator()
        menu.add_command(label=item, command=win.quit)
    else:
        menu.add_command(label=item, command=func)

menubar.add_cascade(label="语言", menu=menu)

def showMenu(event):
    menubar.post(event.x_root, event.y_root)

win.bind("<Button-3>", showMenu)

win.mainloop()

16、Combobox下拉选项控件

import tkinter
from tkinter import ttk

win = tkinter.Tk()
win.title("yudanqu")
win.geometry("400x400+200+50")

# 绑定变量
cv = tkinter.StringVar()

com = ttk.Combobox(win, textvariable=cv,state="readonly")# 不设置会导致可以直接修改
com.pack()

# 设置下拉数据
com["value"] = ("黑龙江", "吉林", "辽宁")

# 设置默认值
com.current(0)

# 绑定事件

def func(event):
    print(com.get())
    print(cv.get())
com.bind("<<ComboboxSelected>>", func)

win.mainloop()

17、messagebox弹出窗口

import tkinter as tk  # 使用Tkinter前需要先导入
import tkinter.messagebox  # 要使用messagebox先要导入模块

window = tk.Tk()
window.title('My Window')
window.geometry('500x300')
# 第5步,定义触发函数功能
def hit_me():
    tkinter.messagebox.showinfo(title='Hi', message='你好!')  # 提示信息对话窗
    tkinter.messagebox.showwarning(title='Hi', message='有警告!')       # 提出警告对话窗
    tkinter.messagebox.showerror(title='Hi', message='出错了!')         # 提出错误对话窗
    print(tkinter.messagebox.askquestion(title='Hi', message='你好!'))  # 询问选择对话窗return 'yes', 'no'
    print(tkinter.messagebox.askyesno(title='Hi', message='你好!'))     # return 'True', 'False'
    print(tkinter.messagebox.askokcancel(title='Hi', message='你好!'))  # return 'True', 'False'

# 第4步,在图形界面上创建一个标签用以显示内容并放置
tk.Button(window, text='hit me', bg='green', font=('Arial', 14), command=hit_me).pack()

# 第6步,主窗口循环显示
window.mainloop()

18、弹出窗口接收数据

import tkinter as tk
from tkinter.simpledialog import askstring, askinteger, askfloat
# 接收一个整数
def print_integer():
    res = askinteger("Spam", "Egg count", initialvalue=12*12)
    print(res)
# 接收一个浮点数
def print_float():
    res = askfloat("Spam", "Egg weight\n(in tons)", minvalue=1, maxvalue=100)
    print(res)
# 接收一个字符串
def print_string():
    res = askstring("Spam", "Egg label")
    print(res)
root = tk.Tk()
tk.Button(root, text='取一个字符串', command=print_string).pack()
tk.Button(root, text='取一个整数', command=print_integer).pack()
tk.Button(root, text='取一个浮点数', command=print_float).pack()
root.mainloop()

19、Notebook选项卡标签(很好玩)

import tkinter as tk  #装载tkinter模块,用于Python3
from tkinter import ttk  #装载tkinter.ttk模块,用于Python3

root =tk.Tk()  # 创建窗口对象
root.title(string = 'ttk.Notebook演示')  #设置窗口标题
root.geometry('400x300+200+200')

tabControl = ttk.Notebook(root)  #创建Notebook
tab1 = tk.Frame(tabControl,bg='blue')  #增加新选项卡
tabControl.add(tab1, text='信息窗')  #把新选项卡增加到Notebook
tab2 = tk.Frame(tabControl,bg='yellow')
tabControl.add(tab2, text='综合信息')
tab3 = tk.Frame(tabControl,bg='green')
tabControl.add(tab3, text='技术分析')
tab4 = tk.Frame(tabControl,bg='blue')
tabControl.add(tab4, text='编写代码')
tab5 = tk.Frame(tabControl,bg='blue')
tabControl.add(tab5, text='模拟回测')



tabControl2 = ttk.Notebook(root)
tab6 = ttk.Frame(tabControl2)
tabControl2.add(tab6, text='双色球')
tabControl.add(tabControl2, text='双色球')

tabControl.pack(expand=1, fill="both")

tabControl.select(tab1) #选择tab1

root.mainloop()     # 进入消息循环

20、分割控件

# 分隔控件的作用就是把控件分隔为几个部分。分隔控件有2两种:水平(HORIZONTAL )或者垂直(VERTICAL )。
# 如果是使用grid布局管理器,需要使用sticky来拉伸分隔控件,否则可能只是窄窄的一条线。
# 如果是使用pack布局管理器,使用使用fill来拉伸控件。

import tkinter as tk
from tkinter import ttk
root = tk.Tk()
root.geometry('320x240')
#设置风格
# s=ttk.Style()
# s.configure('red.TSeparator',background='red')
# b=ttk.Separator(root,orient='horizontal',
#                 style='red.TSeparator')
b=ttk.Separator(root,orient='horizontal')
a=ttk.Button(root,text='Button')
a.pack()
b.pack(fill=tk.X)

root.mainloop()

from tkinter import *
from tkinter import ttk

root = Tk()
root.geometry("400x400+30+150")
ttk.Label(root, text="line1").grid(row=1, column=1)
ttk.Label(root, text="line2").grid(row=1, column=3)
ttk.Label(root, text="line3").grid(row=3, column=1)
ttk.Label(root, text="line4").grid(row=3, column=3)
sh = ttk.Separator(root, orient=HORIZONTAL)
sh.grid(row=2, column=1, columnspan=3, sticky="we")

sv = ttk.Separator(root, orient=VERTICAL)
sv.grid(row=1, column=2, rowspan=3, sticky="ns")

root.columnconfigure(1, weight=1)
root.rowconfigure(1, weight=1)

root.columnconfigure(3, weight=1)
root.rowconfigure(3, weight=1)

#问题是您没有被grid_columnconfigure要求告诉tkinter如何处理额外的空间。
# 由于您没有告诉内部框架如何处理多余的空间,因此将其留空。
# 当小部件放置在其父级中并展开时,您的内部小部件未使用多余的空间。
root.mainloop()

21、Frame控件

import tkinter

win = tkinter.Tk()
win.title("yudanqu")
win.geometry("400x400+200+50")

'''
框架控件:在桌面上显示一个矩形区域,多作为一个容器控件
'''

frm = tkinter.Frame(win)
frm.pack()

# left
frm_l = tkinter.Frame(frm)
tkinter.Label(frm_l, text="左上", bg="pink").pack(side=tkinter.TOP)
tkinter.Label(frm_l, text="左下", bg="blue").pack(side=tkinter.TOP)
frm_l.pack(side=tkinter.LEFT)

# right
frm_r = tkinter.Frame(frm)
tkinter.Label(frm_r, text="右上", bg="green").pack(side=tkinter.TOP)
tkinter.Label(frm_r, text="右下", bg="red").pack(side=tkinter.TOP)
frm_r.pack(side=tkinter.RIGHT)

win.mainloop()

21、表格数据(Treeview)

https://blog.csdn.net/weixin_42268054/article/details/82902296

from tkinter import ttk
from tkinter import *

root = Tk()  # 初始框的声明
columns = ("姓名", "IP地址")
treeview = ttk.Treeview(root, height=18, show="headings", columns=columns)  # 表格

treeview.column("姓名", width=100, anchor='center')  # 表示列,不显示
treeview.column("IP地址", width=300, anchor='center')

treeview.heading("姓名", text="姓名")  # 显示表头
treeview.heading("IP地址", text="IP地址")

treeview.pack(side=LEFT, fill=BOTH)

name = ['电脑1', '服务器', '笔记本']
ipcode = ['10.13.71.223', '10.25.61.186', '10.25.11.163']
for i in range(min(len(name), len(ipcode))):  # 写入数据
    treeview.insert('', i, values=(name[i], ipcode[i]))


def treeview_sort_column(tv, col, reverse):  # Treeview、列名、排列方式
    l = [(tv.set(k, col), k) for k in tv.get_children('')]
    l.sort(reverse=reverse)  # 排序方式
    # rearrange items in sorted positions
    for index, (val, k) in enumerate(l):  # 根据排序后索引移动
        tv.move(k, '', index)
    tv.heading(col, command=lambda: treeview_sort_column(tv, col, not reverse))  # 重写标题,使之成为再点倒序的标题


def set_cell_value(event):  # 双击进入编辑状态
    for item in treeview.selection():
        # item = I001
        item_text = treeview.item(item, "values")
        # print(item_text[0:2])  # 输出所选行的值
    column = treeview.identify_column(event.x)  # 列
    row = treeview.identify_row(event.y)  # 行
    cn = int(str(column).replace('#', ''))
    rn = int(str(row).replace('I', ''))
    entryedit = Text(root, width=10 + (cn - 1) * 16, height=1)
    entryedit.place(x=16 + (cn - 1) * 130, y=6 + rn * 20)

    def saveedit():
        treeview.set(item, column=column, value=entryedit.get(0.0, "end"))
        entryedit.destroy()
        okb.destroy()

    okb = ttk.Button(root, text='OK', width=4, command=saveedit)
    okb.place(x=90 + (cn - 1) * 242, y=2 + rn * 20)


def newrow():
    name.append('待命名')
    ipcode.append('IP')
    treeview.insert('', len(name) - 1, values=(name[len(name) - 1], ipcode[len(name) - 1]))
    treeview.update()
    newb.place(x=120, y=(len(name) - 1) * 20 + 45)
    newb.update()


treeview.bind('<Double-1>', set_cell_value)  # 双击左键进入编辑
newb = ttk.Button(root, text='新建联系人', width=20, command=newrow)
newb.place(x=120, y=(len(name) - 1) * 20 + 45)

for col in columns:  # 绑定函数,使表头可排序
    treeview.heading(col, text=col, command=lambda _col=col: treeview_sort_column(treeview, _col, False))
'''
1.遍历表格
t = treeview.get_children()
for i in t:
    print(treeview.item(i,'values'))
2.绑定单击离开事件
def treeviewClick(event):  # 单击
    for item in tree.selection():
        item_text = tree.item(item, "values")
        print(item_text[0:2])  # 输出所选行的第一列的值
tree.bind('<ButtonRelease-1>', treeviewClick)  
3、删除treeview
def delButton(tree):
    x=tree.get_children()
    for item in x:
        tree.delete(item)
------------------------------
鼠标左键单击按下1/Button-1/ButtonPress-1 
鼠标左键单击松开ButtonRelease-1 
鼠标右键单击3 
鼠标左键双击Double-1/Double-Button-1 
鼠标右键双击Double-3 
鼠标滚轮单击2 
鼠标滚轮双击Double-2 
鼠标移动B1-Motion 
鼠标移动到区域Enter 
鼠标离开区域Leave 
获得键盘焦点FocusIn 
失去键盘焦点FocusOut 
键盘事件Key 
回车键Return 
控件尺寸变Configure
------------------------------
'''

root.mainloop()  # 进入消息循环

22、树状数据

import tkinter
from tkinter import ttk

win = tkinter.Tk()
win.title("yudanqu")
win.geometry("400x400+200+50")

tree = ttk.Treeview(win)
tree.pack()

# 添加一级树枝
treeF1 = tree.insert("",0,"中国",text= "中国Chi", values=("F1"))
treeF2 = tree.insert("",1,"美国",text= "美国USA", values=("F1"))
treeF3 = tree.insert("",2,"英国",text= "英国UK", values=("F1"))

# 二级树枝
treeF1_1 = tree.insert(treeF1,0,"黑龙江",text="中国黑龙江",values=("F1_1"))
treeF1_2 = tree.insert(treeF1,1,"吉林",text="中国吉林",values=("F1_2"))
treeF1_3 = tree.insert(treeF1,2,"辽宁",text="中国辽宁",values=("F1_3"))

treeF2_1 = tree.insert(treeF2,0,"aaa",text="aaaa",values=("F2_1"))
treeF2_2 = tree.insert(treeF2,1,"bbb",text="bbbb",values=("F2_2"))
treeF2_3 = tree.insert(treeF2,2,"ccc",text="cccc",values=("F2_3"))

# 三级树枝
treeF1_1_1 = tree.insert(treeF1_1,0,"哈尔滨",text="黑龙江哈尔滨")
treeF1_1_2 = tree.insert(treeF1_1,1,"五常",text="黑龙江五常")

win.mainloop()

23、组件的鼠标点击事件

import tkinter

win = tkinter.Tk()
win.title("yudanqu")
win.geometry("400x400+200+50")


def func(event):
    print(event.x, event.y)

# <Button-1>  鼠标左键
# <Button-2>  鼠标滚轮
# <Button-1>  鼠标右键
# <Double-Button-1>  鼠标双击左键
# <Triple-Button-1>  鼠标三击左键

button1 = tkinter.Button(win, text="leftmouse button")
# bind 给控件绑定数据(参数一是绑定的事件,参数二是触发事件的函数)
button1.bind("<Button-1>", func)
button1.pack()

win.mainloop()

24、组件的鼠标移动事件

import tkinter

win = tkinter.Tk()
win.title("yudanqu")
win.geometry("400x400+200+50")


# <B1-Motion>  左键移动
# <B2-Motion>  中键移动
# <B3-Motion>  右键移动


label = tkinter.Label(win, text="*********")
label.pack()

def func(event):
    print(event.x, event.y)

label.bind("<B1-Motion>", func)

win.mainloop()

25、组件的鼠标释放事件

import tkinter

win = tkinter.Tk()
win.title("yudanqu")
win.geometry("400x400+200+50")

# <ButtonRelease-1> 释放鼠标左键
# <ButtonRelease-2> 释放鼠标中键
# <ButtonRelease-3> 释放鼠标右键


label = tkinter.Label(win, text="*********", bg="red")
label.pack()

def func(event):
    print(event.x, event.y)

label.bind("<ButtonRelease-1>", func)

win.mainloop()

26、进入和离开事件

import tkinter

win = tkinter.Tk()
win.title("yudanqu")
win.geometry("400x400+200+50")

# <Enter>  当鼠标进入控件时触发事件
# <Leave>  当鼠标离开控件时触发事件

label = tkinter.Label(win, text="*********", bg="red")
label.pack()

def func(event):
    print(event.x, event.y)

label.bind("<Enter>", func)
label.bind("<Leave>", func)


win.mainloop()

27、响应所有按键的事件

import tkinter

win = tkinter.Tk()
win.title("yudanqu")
win.geometry("400x400+200+50")

# <Key>  响应所有的按键(要有焦点)

label = tkinter.Label(win, text="*********", bg="red")
# 设置焦点
label.focus_set()
label.pack()

def func(event):
    print("event.char=", event.char)
    print("event.keycode=", event.keycode)

label.bind("<Key>", func)

win.mainloop()

28、响应特殊按键事件

import tkinter

win = tkinter.Tk()
win.title("yudanqu")
win.geometry("400x400+200+50")

# <Shift_L>  只响应左侧的shift键
# <Shift_R>
# <F5>
# <Return>  也就是回车键
# <BackSpace>  返回,也就是退格键

label = tkinter.Label(win, text="*********", bg="red")
# 设置焦点
label.focus_set()
label.pack()

def func(event):
    print("event.char=", event.char)
    print("event.keycode=", event.keycode)

label.bind("<Shift_L>", func)

win.mainloop()

29、指定按键事件

import tkinter

win = tkinter.Tk()
win.title("yudanqu")
win.geometry("400x400+200+50")


label = tkinter.Label(win, text="*********", bg="red")
# 设置焦点
label.focus_set()
label.pack()

def func(event):
    print("event.char=", event.char)
    print("event.keycode=", event.keycode)

win.bind("a", func) # 注意前面改成了win,只需要写出按键名即可

win.mainloop()

30、组合按键事件

import tkinter

win = tkinter.Tk()
win.title("yudanqu")
win.geometry("400x400+200+50")


# <Control-Alt-a>
# <Shift-Up>
# 只是control+alt不行

label = tkinter.Label(win, text="*********", bg="red")
# 设置焦点
label.focus_set()
label.pack()

def func(event):
    print("event.char=", event.char)
    print("event.keycode=", event.keycode)

win.bind("<Control-Alt-a>", func) # 注意前面改成了win,只需要写出按键名即可

win.mainloop()

综合案例

多功能计算器

import tkinter,time,decimal,math,string #加载各种库
window=tkinter.Tk()             #创建tkinter对象
window.title('计算器')             #设置标题
window.resizable(0,0)           #设置大小不可变
#全局变量,storage存储列表,vartext存储字符串,result存储结果,symbol存储符号
global storage, vartext, result, symbol
result = symbol = None          #变量result和symbol设置值为None
vartext = tkinter.StringVar()        #创建StringVar对象
storage = []                  #变量storage设置为列表

#按键值类
class key_press:
    global storage, vartext, result, symbol    #引用全局变量
    #构造方法,设置按键属性
    def __init__(self,anjian):
        self.key = anjian        #按键名称

    #添加,用于将按键值添加到storage列表,再将storage的值设置为vartext的值
    def jia(self):
        storage.append(self.key)      #将按键值添加到storage列表
        vartext.set(''.join(storage))  #将storage的值连接生成一个新的字符串,并设置为vartext的值

    #删除功能
    def retreat(self):
        storage.pop()           #移除storage列表的值(默认最后一个元素)
        vartext.set(''.join(storage))  #将storage的值连接生成一个新的字符串,并设置为vartext的值

    #清除功能
    def clear(self):
        storage.clear()             #清空storage列表
        vartext.set('')             #设置vartext的值为空
        result = None           #变量result结果改为None
        symbol = None        #变量symbol结果改为None

    #切换正负功能
    def plus_minus(self):
        if storage[0]:          #先判断storage[0]是否有值
            if storage[0] == '-':     #如果storage[0]值为“-”
                storage[0] = '+'   #将storage[0]值改为“+”
            elif storage[0] == '+':    #如果storage[0]值为“+”
                storage[0] = '-'      #将storage[0]值为“-”
            else:
                storage.insert(0, '-') #如果storage[0]的值既不是“+”,又不是“-”,则表示没有符号,添加一个“-”
        vartext.set(''.join(storage))  #将storage的值连接生成一个新的字符串,并设置为vartext的值
    
    #添加小数点功能
    def decimal_point(self):
        if storage.count('.') >= 1:       #如果已经存在小数点,则什么都不做
            pass
        else:
            if storage == []:     #如果storage为空
                storage.append('0')    #给storage队列添加0
            storage.append('.')       #给storage队列添加.
            vartext.set(''.join(storage))  #将storage的值连接生成一个新的字符串,并设置为vartext的值

    #运算        
    def operation(self):
        global storage, vartext, result, symbol    #引用全局变量
        if vartext.get() == '':       #如果vartext中没有值,则什么也不做
            pass
        else:
            get1 = decimal.Decimal(vartext.get())        #获取输入的数值
            if self.key in ('1/x','sqrt'):    #如果按键值属于'1/x'和'sqrt'其中之一
                if self.key == '1/x':     #如果按键值是“1/x”
                    result = 1/get1       #将1/变量get1的结果赋值给变量result
                elif self.key == 'sqrt':   #如果按键值是“sqrt”
                    result = math.sqrt(get1)            #计算变量get1的平方根
            elif  self.key in ('+','-','*','/','='):            #判断按键值
                if symbol is not None: #如果symbol变量不是None
                    get1 = decimal.Decimal(result)    #获取第一次输入的数值
                    get2 = decimal.Decimal(vartext.get())  #获取第二次输入的数值
                    if symbol == '+':              #如果符号是“+”
                        result = get1 + get2            #相加
                    elif symbol == '-':                #如果符号是“-”
                        result = get1 - get2            #相减
                    elif symbol == '*':                #如果符号是“*”
                        result = get1 * get2            #相乘t
                    elif symbol == '/':                #如果符号是“/”
                        result = get1 / get2            #相除
                else:                          #如果没有输入符号
                    result = get1                 #获取get1的值
                if self.key == '=':                   #如果输入的键值为“=”
                    symbol = None        #变量symbol则赋值为None
                else:                    #输入的键值不为“=”
                    symbol = self.key        #将输入的键值赋值给symbol
            print(symbol)                 #输出变量symbol,表示符号
            print(result)                 #输出变量result,表示结果
            vartext.set(str(result))   #将结果转为字符串形式,并设置为vartext的值
            storage.clear()                   #清空storage列表

#计算器布局
def layout(window):
    global storage, vartext, result, symbol          #引用全局变量
    #设置顶部标签,用于展示按键的值
    entry1 = tkinter.Label(window, width=30, height=2, bg='white', anchor='se',\
        textvariable=vartext)
    entry1.grid(row=0, columnspan=5)

    #添加按钮
    buttonJ=tkinter.Button(window,text='←',width=5,command=key_press('c').retreat)
    buttonCE=tkinter.Button(window,text='保存',width=5)
    buttonC=tkinter.Button(window,text=' C ',width=5,command=key_press('c').clear)
    button12=tkinter.Button(window,text='±',width=5,\
        command=key_press('c').plus_minus)
    buttonD=tkinter.Button(window,text='√',width=5,\
        command=key_press('sqrt').operation)
    buttonJ.grid(row=2,column=0)
    buttonCE.grid(row=2,column=1)
    buttonC.grid(row=2,column=2)
    button12.grid(row=2,column=3)
    buttonD.grid(row=2,column=4)
    button7=tkinter.Button(window,text=' 7 ',width=5,command=key_press('7').jia)
    button8=tkinter.Button(window,text=' 8 ',width=5,command=key_press('8').jia)
    button9=tkinter.Button(window,text=' 9 ',width=5,command=key_press('9').jia)
    buttonc=tkinter.Button(window, text=' / ',width=5,command=key_press('/').operation)
    buttonf= tkinter.Button(window, text='删除',width=5)
    button7.grid(row=3,column=0)
    button8.grid(row=3,column=1)
    button9.grid(row=3,column=2)
    buttonc.grid(row=3,column=3)
    buttonf.grid(row=3,column=4)
    button4=tkinter.Button(window,text=' 4 ',width=5,command=key_press('4').jia)
    button5=tkinter.Button(window,text=' 5 ',width=5,command=key_press('5').jia)
    button6=tkinter.Button(window,text=' 6 ',width=5,command=key_press('6').jia)
    buttonx=tkinter.Button(window,text=' * ',width=5,command=key_press('*').operation)
    buttonfs=tkinter.Button(window,text='1/x',width=5,\
        command=key_press('1/x').operation)
    button4.grid(row=4,column=0)
    button5.grid(row=4,column=1)
    button6.grid(row=4,column=2)
    buttonx.grid(row=4,column=3)
    buttonfs.grid(row=4,column=4)
    button1 = tkinter.Button(window, text=' 1 ',width=5,command=key_press('1').jia)
    button2 = tkinter.Button(window, text=' 2 ',width=5,command=key_press('2').jia)
    button3 = tkinter.Button(window, text=' 3 ',width=5,command=key_press('3').jia)
    button_= tkinter.Button(window, text=' - ',width=5,command=key_press('-').operation)
    buttondy= tkinter.Button(window, text=' \n = \n ',width=5,\
        command=key_press('=').operation)
    button1.grid(row=5, column=0)
    button2.grid(row=5, column=1)
    button3.grid(row=5, column=2)
    button_.grid(row=5, column=3)
    buttondy.grid(row=5, column=4,rowspan=2)
    button0=tkinter.Button(window,text=' 0 ',width=11,command=key_press('0').jia)
    buttonjh = tkinter.Button(window,text=' . ',width=5,\
        command=key_press('c').decimal_point)
    buttonjia=tkinter.Button(window,text=' + ',width=5,\
        command=key_press('+').operation)
    button0.grid(row=6,column=0,columnspan=2)
    buttonjh.grid(row=6,column=2)
    buttonjia.grid(row=6,column=3)

layout(window)          #window窗口应用layout布局
window.mainloop()  

treeview、爬虫、下拉选择综合案例

from tkinter import *
import tkinter.messagebox
from tkinter import ttk
import requests
import re

def show_data():
    global data_dict
    the_tpye=value1.get()
    the_year=2019-eval(value2.get()[:-1])
    for i in data_dict:
        if i ==the_tpye:
            tkinter.messagebox.showinfo(title='Hi', message='%s年%s的数据为%s亿元'%(value2.get(),value1.get()[:-4],data_dict[i][the_year]))



def spyder():
    global data_dict
    url = 'http://data.stats.gov.cn/easyquery.htm?m=QueryData&dbcode=hgnd&rowcode=zb&colcode=sj&wds=%5B%5D&dfwds=%5B%7B%22wdcode%22%3A%22zb%22%2C%22valuecode%22%3A%22A0201%22%7D%5D&k1=1592276489221&h=1'
    response = requests.get(url).content.decode()
    data_list = re.findall('"strdata":"(.*?)"}?', response)
    data_dict = {'国民总收入(亿元)': data_list[0:10], '国内生产总值(亿元)': data_list[10:20], '第一产业增加值(亿元)': data_list[20:30],
                 '第二产业增加值(亿元)': data_list[30:40], '第三产业增加值(亿元)': data_list[40:50], '人均国内生产总值(元)': data_list[50:60]}
    for i in data_dict:
        tv.insert('', 'end', values=[i]+data_dict[i])


data_dict={}
win = Tk()
win.title("国内生产总值查询工具")
win.geometry('730x400')

lb1 = Label(win, text="指标类型", font=('tahoma 12 normal', 10))
lb1.grid(column=0, row=2)
lb2 = Label(win, text="查询年份", font=('tahoma 12 normal', 10))
lb2.grid(column=0, row=4)

b1 = Button(win, text='点击爬取信息',font=('tahoma 12 normal', 10),height=2, command=spyder)
b1.grid(column=0, row=1)
b2 = Button(win, text='点击查询',font=('tahoma 12 normal', 10),height=2, command=show_data)
b2.grid(column=0, row=6)


# Define tkinter data type
value1 = StringVar()
cbx_1 = ttk.Combobox(win, width=16, height=8, textvariable=value1)
cbx_1.grid(column=0, row=3)
cbx_1["values"] = ['国民总收入(亿元)','国内生产总值(亿元)','第一产业增加值(亿元)','第二产业增加值(亿元)','第三产业增加值(亿元)','人均国内生产总值(元)']
cbx_1.current(0)

value2 = StringVar()
cbx_2 = ttk.Combobox(win, width=16, height=8,textvariable=value2)
cbx_2.grid(column=0, row=5)
cbx_2["values"] = ["2019年","2018年","2017年","2016年","2015年","2014年","2013年","2012年","2011年","2010年"]
cbx_2.current(0)


area = ('指标', "2019年","2018年","2017年","2016年","2015年","2014年","2013年","2012年","2011年","2010年")
ac=('指标', "2019年","2018年","2017年","2016年","2015年","2014年","2013年","2012年","2011年","2010年")
dc=('指标', "2019年","2018年","2017年","2016年","2015年","2014年","2013年","2012年","2011年","2010年")
tv = ttk.Treeview(win, columns=ac, show='headings',height=7, displaycolumns=dc)
tv.column(ac[0], width=130, anchor='c')
tv.heading(ac[0], text='指标')
for i in range(1,11):
    tv.column(ac[i], width=60, anchor='c')
    tv.heading(ac[i], text=area[i])
tv.grid(column=0, row=7)

win.mainloop()
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

笼中小夜莺

嘿嘿嘿,请用金钱尽情地蹂躏我吧

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值