跳至主要内容

tkinter 入门

查看tkinter版本
方法一:
cmd直接输入
python -m tkinter

方法二:
cmd输入python
>>> import tkinter
>>> tkinter._test()
>>> tkinter.Tcl().eval('info patchlevel')




参考资料
https://www.geeksforgeeks.org/python-gui-tkinter/
https://likegeeks.com/python-gui-examples-tkinter-tutorial/
http://www.openbookproject.net/courses/python4fun/tkphone1.html

tkinter框架

#导入(调用)tkinter模块
from tkinter import *

#创建Tk()的对象,它实际上用于创建窗口
my_window = Tk()

#调用mainloop()函数,用于窗口的无限循环。当我们点击关闭按钮或退出应用程序时,mainloop()函数终止
my_window.mainloop()

print(id(my_window), type(my_window),dir(my_window))
输出 53949680
<class 'tkinter.Tk'>
['_Misc__winfo_getint', '_Misc__winfo_parseitem', '__class__',...]

#遍历
for key in root.keys():
    print(key,":",root[key])

设置窗口标题

my_window.title("Demo")

更改左上角图标

my_window.iconbitmap(r'C:\src\dragon-face.ico')

from pathlib import Path
my_window.iconbitmap(Path('img/dragon.ico').absolute())

设置窗口背景颜色

#用16进制红绿蓝表示,共256 x 256 x256 = 16777216种
#颜色网站https://www.color-hex.com/
#https://encycolorpedia.com/
my_window.configure(background='red')
my_window.configure(bg='#ff0000')


设置窗口大小

my_window.configure(width=400, height=200, background='#94d42b')

窗口宽高是否可变

#True:可变  False:不可变
my_window.resizable(width=True, height=False)



设置窗口位置

#widthxheight+x+y
#电脑屏幕左上角坐标位置 x=0,y=0
#geometry(几何图形)的width(宽)、height(高) 优先于 configure(配置)
my_window.geometry("500x300+800+100")


窗口放在屏幕最中间

#窗口宽度、高度
width_of_window = 800
height_of_window = 600

#电脑屏幕宽度、高度,也就是屏幕分辨率
screen_width = my_window.winfo_screenwidth()
screen_height = my_window.winfo_screenheight()

#x、y坐标(coordinate)
x_coordinate = (screen_width/2) - (width_of_window/2)
y_coordinate = (screen_height/2) - (height_of_window/2)

#窗口位于屏幕正中间的三个方法
my_window.geometry("%dx%d+%d+%d" % (width_of_window, height_of_window, x_coordinate, y_coordinate))

my_window.geometry("{}x{}+{}+{}".format(width_of_window, height_of_window, int(x_coordinate), int(y_coordinate)))

my_window.geometry(f"{width_of_window}x{height_of_window}+{int(x_coordinate)}+{int(y_coordinate)}")


首先必须将小部件与所谓的几何管理器(geometry)放在一起。两个最常见的是包(pack)和网格(grid),才能显示在窗口,注意pack和grid不能在一个框架内混用
还有一种place(放置)方法可以将窗口小部件定位在框架或窗口内的精确位置。并不经常使用

使用包或网格时,还有其他常用的关键字参数。我们看到上面的padx和pady。对于网格,有一个sticky(粘性)参数,它采用N,E,S,W,NE等地图坐标。如果网格单元格大于您的小部件,因为较大的小部件位于同一行或列中,粘性有助于您将小部件放在单元格中的所需位置

小部件是对象并具有方法
创建窗口小部件时可以传递的任何关键字参数也可以传递给它的configure(配置)方法

标签(Label)小部件介绍


#用于在Tk()窗口中显示文本或图像#显示文本
label_1 = Label(my_window, text='标签1')
label_2 = Label(my_window, text='标签2')



# 默认按side=TOP顺序自上而下排列标签 还有参数(TOP,LEFT,RIGHT,BOTTOM))
# pack方法告诉Tk使窗口的大小适合给定的文本
#“padx”在左右两侧添加像素,“pady”将像素添加到顶部和底部label_2.pack(side = LEFT , padx=10)
label_1.pack(side = LEFT, padx=10)

#显示图像
img = PhotoImage(file="python-logo.png")

#这两行代码用于在窗口上创建和显示图像
#第一行创建具有两个参数的Label类的对象,第一个参数是父窗口的对象,第二个参数指定要在标签上显示的图像
label_1 = Label(my_window, image=img)
#第二行控制窗口中Label的表示,grid()指定屏幕上的行号和列号。row = 0和column = 0引导tkinter在屏幕的最左上角显示标签
label_1.grid(row=0, column=0)

设置标签背景颜色、字体类型、字体颜色、大小

label_1 = Label(my_window, text="标签1", bg="blue", fg="white", font="Times 30 italic bold")

#设置鼠标接近和离开标签时,text字体变色
#绑定(bind)事件(event)
from functools import partial
def color_config(widget, color, event):
    widget.configure(foreground=color)

label_1.bind("<Enter>", partial(color_config, label_1, "red"))
label_1.bind("<Leave>", partial(color_config, label_1, "#daa520"))

label_1.pack()
#参考https://stackoverflow.com/questions/29594019/italicize-tkinter-label-text-on-focus


设置标签宽度

#width是标签宽度,不是text宽度
label_1 = Label(my_window, text="标签1", bg="blue", fg="white", font="Times 30 italic bold", width=20)
label_2 = Label(my_window, text="标签2", bg="red", fg="white", font="Times 30 italic bold", width=30)
label_1.pack()
label_2.pack()


设置标签高度

#text两行,height=3代表3个字符高度,则text放中间位置
label_1 = Label(my_window,
                text="标签1\nsolid",
                bd=1,
                relief="solid",
                height=3)


标签中多行内容展示

#换行用\n,换n行用n个\n
label_1 = Label(my_window, text="标签1\n换一行\n\n换两行\n", bg="blue", fg="white", font="Times 30 italic bold", width=20)

设置标签边框宽度(borderwidth或者bd)

#浮雕(relief[flat,groove,raised,sunken,ridge,solid])
label_1 = Label(my_window, text="标签1 flat", borderwidth=12, relief="flat")
label_2 = Label(my_window, text="标签2 groove", bd=12, relief="groove")
label_3 = Label(my_window, text="标签3 raised", bd=12, relief="raised")
label_4 = Label(my_window, text="标签4 sunken", bd=12, relief="sunken")
label_5 = Label(my_window, text="标签5 ridge", bd=12, relief="ridge")
label_6 = Label(my_window, text="标签6 solid", bd=16, relief="solid")


定义标签中text内容的位置

#锚(anchor)可以确定text在标签中的位置,要求大写
#N、NE、E、SE、S、SW、W、NW、CENTER
#北、东北、东、东南、南、西南、西、西北、中心
my_window.geometry("400x250")
label_1 = Label(my_window,
                text="标题")
label_2 = Label(my_window,
                text="这是\n内容",
                bd=1,
                relief="solid",
                width=15,
                height=4,
                anchor=CENTER)

标签中内容对齐方式

#justify:text中的内容对齐,LEFT、RIGHT、CENTER
label_1 = Label(my_window,
                text="这\n是内\n容展示",
                bd=1,
                relief="solid",
                font="Times 20",
                anchor=CENTER,
                justify=LEFT)

定义标签中内容位置及对齐方式

#anchor代表在标签label中的位置
#justify代表文本text对齐方式
label_2 = Label(my_window,
                text="这\n是内\n容展示",
                bd=1,
                relief="solid",
                font="Times 20",
                width=15,
                height=6,
                anchor=SW,
                justify=LEFT)

填充标签内容周围的空间

#用padx、pady填充标签文本周围的空间
label_1 = Label(my_window,
                text="标题",
                bd=1,
                relief="solid",
                padx=20,
                pady=20)
         

查找标签值

print(label_1['text'])

更改标签值

label_1['text']=“新的内容”

访问标签键值

#健列表
print(label_1.keys())
#键:值
for item in label_1.keys():
    print(item, ":", label_1[item])


标签中的textvariable使用

var_1 = StringVar()

label_1 = Label(my_window, textvariable=var_1)
label_2 = Label(my_window)

label_1.pack()
label_2.pack()

var_1.set("你好")
label_2["text"] = "你好"

按钮(Button)小部件介绍

参数:
activebackground:设置按钮按下时的背景颜色
activeforeground:设置按钮按下时的前景色
bg:设置背景颜色
command:调用函数
font:设置按钮标签上的字体
image:在按钮上设置图像
width:设置按钮的宽度
height:设置按钮的高度

def add_label():
    label_1 = Label(my_window, text='你好')
    label_1.pack()

button_1 = Button(my_window,
                  text='添加标签',
                  command=add_label)

button_1.pack()


网格几何图形管理器Grid Geometry Manager

#利用width,height定义宽高
label_1 = Label(my_window,width=20,height=8,bg="red")
button_1 = Button(my_window,text="打开")

label_1.grid(row=0,column=0)
button_1.grid(row=1,column=0)


输入(Entry)小部件


def say_hello():
    var_1.set("hello:" + var_2.get())
    #print(type(var_2.get()))可知返回的是str类型

var_1 = StringVar()
var_2 = StringVar()

label_1 = Label(my_window, text="请输入名字:")
entry_1 = Entry(my_window, textvariable=var_2)
button_1 = Button(my_window, text="问候", command=say_hello)
label_2 = Label(my_window, textvariable=var_1)

label_1.grid(row=0, column=0)
entry_1.grid(row=0, column=1)
button_1.grid(row=1, column=0)
label_2.grid(row=1, column=1)

#聚焦输入方法一、二
entry_1.focus()
entry_1.focus_force()

继承框架(Frame)用法

class RedFrame(Frame):
    def __init__(self,the_window):
        super().__init__()
        self["width"]=150
        self["height"]=150
        self["relief"]=RAISED
        self["bd"]=8
        self["bg"]="red"

frame_1=RedFrame(my_window)
frame_1.grid(row=0,column=0)


画布(Canvas)中用随机颜色画线


参数
bd:设置边框宽度(以像素为单位)
bg:设置正常的背景颜色
cursor:设置画布中使用的光标
highlightcolor:设置focus_force()时高亮显示的颜色
width:设置窗口小部件的宽度
height:设置小部件的高度

from random import *
def random_color_code():
    hex_charx = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f']
    colour_code = '#' + ''.join([choice(hex_charx) for i in range(0,6)])
    return colour_code

my_canvas = Canvas(my_window, width=400, height=400, bg=random_color_code())
my_canvas.grid(row=0, column=0)

for i in range(0, 1000):
    x1 = randint(0, 400)
    y1 = randint(0, 400)
    x2 = randint(0, 400)
    y2 = randint(0, 400)
    width_random = randint(1, 20)

    #create_line用法起点x1,y1 终点x2,y2
    my_canvas.create_line(x1, y1, x2, y2, fill=f'#{randint(0,0xffffff):06x}', width=width_random)
    my_canvas.update()


画布中用线画图形

#多笔画法
my_canvas.create_line(100, 100, 300, 100, fill="blue", width=5)
my_canvas.create_line(300, 100, 350, 300, fill="blue", width=5)
my_canvas.create_line(350, 300, 50, 300, fill="blue", width=5)
my_canvas.create_line(50, 300, 100, 100, fill="blue", width=5)

#一笔画法,连接处闭合
my_canvas.create_line(100, 100, 300, 100, 200, 300, 100, 100, fill="red", width=5)


画布中的箭头arrow

#箭头arrow走向有first,last,both,none默认为nonemy_canvas.create_line(100, 100, 300, 100, fill="blue", arrow="first", width=5)


#箭头形状有arrowshape=(a,b,c)确定
#a水平值,c垂直值的一半,b垂直与水平交点到顶点
my_canvas.create_line(500, 100, 700, 100, fill="red", arrow="last", arrowshape=(30, 45, 28), width=5)



Text小部件

from tkinter import *
from pathlib import Path

my_window = Tk()
text = Text(my_window,height=3)

text.insert(INSERT, "Hello.....")

text.insert(END, "Bye Bye.....")

text.pack(side=TOP)



text.tag_add("here", "1.0", "1.4")

text.tag_add("start", "1.8", "1.13")

text.tag_config("here", background="yellow", foreground="blue")

text.tag_config("start", background="black", foreground="green")

text1 = Text(my_window, height=25, width=30)
photo = PhotoImage(file=Path('guido.gif').absolute())
text1.insert(END, '\n')
text1.image_create(END, image=photo)

text1.pack(side=LEFT)

text2 = Text(my_window, height=25, width=50)
scroll = Scrollbar(my_window, command=text2.yview)
text2.configure(yscrollcommand=scroll.set)
text2.tag_configure('bold_italics', font=('Arial', 12, 'bold', 'italic'))
text2.tag_configure('big', font=('Verdana', 20, 'bold'))
text2.tag_configure('color',
                    foreground='#476042',
                    font=('Tempus Sans ITC', 12, 'bold'))
text2.tag_bind('follow',
               '<1>',
               lambda e, t=text2: t.insert(END, "Not now, maybe later!"))
text2.insert(END,'\nThe Zen of Python\n', 'big')
quote = """
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
"""
text2.insert(END, quote, 'color')
text2.insert(END, 'follow-up\n', 'follow')
text2.pack(side=LEFT)
scroll.pack(side=RIGHT, fill=Y)

my_window.mainloop()


对话框filedialog

try:
    import tk as tk
    import tc as tc
    import tf as tm
except:
    import tkinter as tk
    import tkinter.constants as tc
    import tkinter.filedialog as tf


class tfExample(tk.Frame):
    def __init__(self, root):
        tk.Frame.__init__(self, root)

        # options for buttons
        button_opt = {'fill': tc.BOTH, 'padx': 5, 'pady': 5}

        # define buttons
        tk.Button(self, text='askopenfile', command=self.askopenfile).pack(**button_opt)
        tk.Button(self, text='askopenfilename', command=self.askopenfilename).pack(**button_opt)
        tk.Button(self, text='asksaveasfile', command=self.asksaveasfile).pack(**button_opt)
        tk.Button(self, text='asksaveasfilename', command=self.asksaveasfilename).pack(**button_opt)
        tk.Button(self, text='askdirectory', command=self.askdirectory).pack(**button_opt)

        # define options for opening or saving a file
        self.file_opt = options = {}
        options['defaultextension'] = '.txt'
        options['filetypes'] = [('all files', '.*'), ('text files', '.txt')]
        options['initialdir'] = 'C:\\'
        options['initialfile'] = 'myfile.txt'
        options['parent'] = root
        options['title'] = 'This is a title'

        # This is only available on the Macintosh, and only when Navigation Services are installed.
        # options['message'] = 'message'

        # if you use the multiple file version of the module functions this option is set automatically.
        # options['multiple'] = 1

        # defining options for opening a directory
        self.dir_opt = options = {}
        options['initialdir'] = 'C:\\'
        options['mustexist'] = False
        options['parent'] = root
        options['title'] = 'This is a title'

    def askopenfile(self):

        """Returns an opened file in read mode."""

        return tf.askopenfile(mode='r', **self.file_opt)

    def askopenfilename(self):

        """Returns an opened file in read mode.
        This time the dialog just returns a filename and the file is opened by your own code.
        """

        # get filename
        filename = tf.askopenfilename(**self.file_opt)

        # open file on your own
        if filename:
            return open(filename, 'r')

    def asksaveasfile(self):

        """Returns an opened file in write mode."""

        return tf.asksaveasfile(mode='w', **self.file_opt)

    def asksaveasfilename(self):

        """Returns an opened file in write mode.
        This time the dialog just returns a filename and the file is opened by your own code.
        """

        # get filename
        filename = tf.asksaveasfilename(**self.file_opt)

        # open file on your own
        if filename:
            return open(filename, 'w')

    def askdirectory(self):

        """Returns a selected directoryname."""

        return tf.askdirectory(**self.dir_opt)


if __name__ == '__main__':
    root = tk.Tk()
    tfExample(root).pack()
    root.mainloop()








评论

此博客中的热门博文

Chrome浏览器

谷歌搜索 双引号——精确搜索 冒号后加文件类型——搜索特定类型的结果 关键词 后 site:**——搜索特定网站的关键词 +、-关键词——实现特定需求筛选 Google中/——快捷键入浏览·搜索框 关键词后..——搜索特定范围(地点)关键词 intitle:关键词——搜索特定标题 用 puppeteer 直接运行 chrome 爬 https://github.com/puppeteer/puppeteer Puppeteer 是一个 Node 库,它提供了一个高级 API 来通过 DevTools 协议 控制 Chrome 或 Chromium 。Puppeteer默认 无头 运行,但可以配置为运行完整(非无头)Chrome 或 Chromium。 了解如何为 Chrome 开发扩展程序 https://developer.chrome.com/docs/extensions/mv3/ 什么是Chrome插件 https://github.com/sxei/chrome-plugin-demo Google Workspace 状态信息中心 https://www.google.com/appsstatus#hl=zh&v=status 此页面提供属于“Google Workspace”的服务的状态信息 谷歌浏览器离线下载 https://support.google.com/chrome/answer/95346?co=GENIE.Platform%3DDesktop&hl=zh-Hans 企业版 https://cloud.google.com/chrome-enterprise/browser/download 也可以在谷歌浏览器 帮助中心 中搜索chrome https://www.google.com/intl/zh-CN/chrome/?standalone=1 chrome 打开新网页时不要覆盖 鼠标 中键(滚轮)点击超链接 ,或者右击超链接,选择新标签页打开, 还有点链接的同时按下 Ctrl 键也可以 谷歌在线翻译网页 http://translate.google.com/translate?u= http://www.dropitproject.com/index.php 打开chrome浏览器按 F6 ,等同于按 ...

python 之 configparser、configobj(ini配置文件)

ini 即 Initialize 初始化之意,通常由节(Section)、键(key)和值(value)组成 ini修改工具 https://visionlore.com/lab/ini_editor.php https://www.horstmuc.de/wbat32.htm#inifile 语法      INIFILE filename.ini [section] item=string # db.ini 中的内容 # ********************* # [localdb] # host     = 127.0.0.1 # user     = root # password = 123456 # port     = 3306 # database = mysql # *********************   import pymysql from configparser import ConfigParser   cfg = ConfigParser ( ) cfg. read ( "db.ini" )   print ( cfg. items ( "localdb" ) ) db_cfg = dict ( cfg. items ( "localdb" ) ) print ( db_cfg )   # 端口port类型str转为int db_cfg [ 'port' ] = int ( db_cfg [ 'port' ] ) con = pymysql. connect ( **db_cfg )   from pprint import pprint lst = [ line. strip ( ) for line in open ( 'db.ini' ) ] pprint ( lst ) http://www.voidspace.org.uk/python/articles/configobj.shtml https://configobj.readthedocs.io/en/latest/configobj.html https://pythonhosted.or...

python 代码示例

  加密软件 谷歌搜registration codes python和license keys python https://www.nuvovis.com/python-software-licensing.html https://build-system.fman.io/generating-license-keys https://codereview.stackexchange.com/questions/95499/register-login-and-authentication-through-terminal 获取MAC地址并生成序列号,从序列号生成激活密钥 secrets模块资料 https://blog.miguelgrinberg.com/post/the-new-way-to-generate-secure-tokens-in-python # 不足十位左边加零 while True:     num = input('Enter a number : ')     print('The zero-padded number is : ', str(num).rjust(10, '0')) 查找n个自然数的和 # Sum of natural numbers up to num   num = 16   if num < 0 :     print ( "Enter a positive number" ) else :     sum = 0     # use while loop to iterate until zero     while ( num > 0 ) :         sum + = num        num - = 1     print ( "The sum is" , sum )   使用匿名函数显示整数2的幂 # Display the powers of 2 using anonymous function ...