专栏导读
🌸 欢迎来到Python办公自动化专栏—Python处理办公问题,解放您的双手 📕 此外还有python基础专栏:请点击——>Python基础学习专栏 求订阅 文章作者技术和水平有限,如果文中出现错误,希望大家能指正🙏 ❤️ 欢迎各位佬关注! ❤️
简介
tkinter(Tk interface)是Python的标准GUI(图形用户界面)库,它是Python内置的图形界面开发工具包。tkinter基于Tk GUI工具包,提供了创建桌面应用程序的简单而强大的方法。 ## 什么是tkinter
tkinter是Python的标准GUI库 跨平台支持(Windows、macOS、Linux) 无需额外安装,Python自带 基于Tcl/Tk图形工具包
基本架构
import tkinter as tk
root = tk. Tk( )
root. title( "我的第一个tkinter程序" )
root. geometry( "400x300" )
root. mainloop( )
核心组件详解
1. 窗口(Window)
import tkinter as tk
root = tk. Tk( )
root. title( "窗口标题" )
root. geometry( "宽度x高度+x偏移+y偏移" )
root. resizable( width= True , height= True )
root. mainloop( )
root. title( "标题" )
root. geometry( "800x600" )
root. minsize( 400 , 300 )
root. maxsize( 1200 , 800 )
root. iconbitmap( "icon.ico" )
2. 标签(Label)
import tkinter as tk
root = tk. Tk( )
label = tk. Label( root,
text= "这是一个标签" ,
font= ( "Arial" , 12 ) ,
fg= "blue" ,
bg= "yellow" )
label. pack( )
root. mainloop( )
Label常用参数
text: 显示的文本 font: 字体设置 fg: 前景色(文字颜色) bg: 背景色 width/height: 宽度和高度 anchor: 文本对齐方式
3. 按钮(Button)
import tkinter as tk
from tkinter import messagebox
def button_click ( ) :
messagebox. showinfo( "提示" , "按钮被点击了!" )
root = tk. Tk( )
button = tk. Button( root,
text= "点击我" ,
command= button_click,
width= 10 ,
height= 2 ,
bg= "lightblue" )
button. pack( )
root. mainloop( )
4. 输入框(Entry)
import tkinter as tk
def get_input ( ) :
user_input = entry. get( )
print ( f"用户输入: { user_input} " )
root = tk. Tk( )
entry = tk. Entry( root, width= 30 )
entry. pack( )
get_button = tk. Button( root, text= "获取输入" , command= get_input)
get_button. pack( )
root. mainloop( )
5. 文本框(Text)
import tkinter as tk
root = tk. Tk( )
text_widget = tk. Text( root, width= 40 , height= 10 )
text_widget. pack( )
text_widget. insert( tk. END, "这是多行文本框\n" )
text_widget. insert( tk. END, "可以输入多行文本" )
root. mainloop( )
6. 列表框(Listbox)
import tkinter as tk
def on_select ( event) :
selection = listbox. curselection( )
if selection:
value = listbox. get( selection[ 0 ] )
print ( f"选中: { value} " )
root = tk. Tk( )
listbox = tk. Listbox( root)
listbox. pack( )
items = [ "选项1" , "选项2" , "选项3" , "选项4" ]
for item in items:
listbox. insert( tk. END, item)
listbox. bind( '<<ListboxSelect>>' , on_select)
root. mainloop( )
布局管理器
1. pack布局
import tkinter as tk
root = tk. Tk( )
label1 = tk. Label( root, text= "顶部" , bg= "red" )
label1. pack( side= tk. TOP, fill= tk. X)
label2 = tk. Label( root, text= "底部" , bg= "blue" )
label2. pack( side= tk. BOTTOM, fill= tk. X)
label3 = tk. Label( root, text= "左侧" , bg= "green" )
label3. pack( side= tk. LEFT, fill= tk. Y)
label4 = tk. Label( root, text= "右侧" , bg= "yellow" )
label4. pack( side= tk. RIGHT, fill= tk. Y)
root. mainloop( )
2. grid布局
import tkinter as tk
root = tk. Tk( )
for i in range ( 3 ) :
for j in range ( 3 ) :
label = tk. Label( root, text= f"( { i} , { j} )" ,
relief= tk. RAISED, width= 10 )
label. grid( row= i, column= j, padx= 5 , pady= 5 )
root. mainloop( )
3. place布局
import tkinter as tk
root = tk. Tk( )
root. geometry( "400x300" )
label1 = tk. Label( root, text= "绝对定位" , bg= "red" )
label1. place( x= 50 , y= 50 )
label2 = tk. Label( root, text= "相对定位" , bg= "blue" )
label2. place( relx= 0.5 , rely= 0.5 , anchor= tk. CENTER)
root. mainloop( )
事件处理
鼠标事件
import tkinter as tk
def on_click ( event) :
print ( f"鼠标点击位置:( { event. x} , { event. y} )" )
def on_double_click ( event) :
print ( "双击事件" )
root = tk. Tk( )
label = tk. Label( root, text= "点击我" , bg= "lightblue" , width= 20 , height= 10 )
label. pack( )
label. bind( "<Button-1>" , on_click)
label. bind( "<Double-Button-1>" , on_double_click)
root. mainloop( )
键盘事件
import tkinter as tk
def on_key_press ( event) :
print ( f"按下键: { event. keysym} " )
root = tk. Tk( )
entry = tk. Entry( root)
entry. pack( )
entry. focus( )
entry. bind( "<KeyPress>" , on_key_press)
root. mainloop( )
菜单系统
import tkinter as tk
from tkinter import messagebox
def new_file ( ) :
messagebox. showinfo( "新建" , "新建文件" )
def open_file ( ) :
messagebox. showinfo( "打开" , "打开文件" )
def about ( ) :
messagebox. showinfo( "关于" , "这是一个tkinter示例程序" )
root = tk. Tk( )
root. title( "菜单示例" )
menubar = tk. Menu( root)
root. config( menu= menubar)
file_menu = tk. Menu( menubar, tearoff= 0 )
menubar. add_cascade( label= "文件" , menu= file_menu)
file_menu. add_command( label= "新建" , command= new_file)
file_menu. add_command( label= "打开" , command= open_file)
file_menu. add_separator( )
file_menu. add_command( label= "退出" , command= root. quit)
help_menu = tk. Menu( menubar, tearoff= 0 )
menubar. add_cascade( label= "帮助" , menu= help_menu)
help_menu. add_command( label= "关于" , command= about)
root. mainloop( )
对话框
消息对话框
import tkinter as tk
from tkinter import messagebox
root = tk. Tk( )
def show_info ( ) :
messagebox. showinfo( "信息" , "这是信息对话框" )
def show_warning ( ) :
messagebox. showwarning( "警告" , "这是警告对话框" )
def show_error ( ) :
messagebox. showerror( "错误" , "这是错误对话框" )
def ask_question ( ) :
result = messagebox. askyesno( "确认" , "你确定要继续吗?" )
print ( f"用户选择: { result} " )
tk. Button( root, text= "信息" , command= show_info) . pack( pady= 5 )
tk. Button( root, text= "警告" , command= show_warning) . pack( pady= 5 )
tk. Button( root, text= "错误" , command= show_error) . pack( pady= 5 )
tk. Button( root, text= "询问" , command= ask_question) . pack( pady= 5 )
root. mainloop( )
文件对话框
import tkinter as tk
from tkinter import filedialog
root = tk. Tk( )
def open_file ( ) :
filename = filedialog. askopenfilename(
title= "选择文件" ,
filetypes= [ ( "文本文件" , "*.txt" ) , ( "所有文件" , "*.*" ) ]
)
if filename:
print ( f"选择的文件: { filename} " )
def save_file ( ) :
filename = filedialog. asksaveasfilename(
title= "保存文件" ,
defaultextension= ".txt" ,
filetypes= [ ( "文本文件" , "*.txt" ) , ( "所有文件" , "*.*" ) ]
)
if filename:
print ( f"保存到: { filename} " )
tk. Button( root, text= "打开文件" , command= open_file) . pack( pady= 10 )
tk. Button( root, text= "保存文件" , command= save_file) . pack( pady= 10 )
root. mainloop( )
高级组件
Frame框架
import tkinter as tk
root = tk. Tk( )
root. title( "Frame示例" )
main_frame = tk. Frame( root, bg= "lightgray" , relief= tk. RAISED, bd= 2 )
main_frame. pack( fill= tk. BOTH, expand= True , padx= 10 , pady= 10 )
left_frame = tk. Frame( main_frame, bg= "lightblue" , width= 200 )
left_frame. pack( side= tk. LEFT, fill= tk. Y, padx= 5 , pady= 5 )
right_frame = tk. Frame( main_frame, bg= "lightgreen" )
right_frame. pack( side= tk. RIGHT, fill= tk. BOTH, expand= True , padx= 5 , pady= 5 )
tk. Label( left_frame, text= "左侧面板" , bg= "lightblue" ) . pack( pady= 10 )
tk. Button( left_frame, text= "按钮1" ) . pack( pady= 5 )
tk. Button( left_frame, text= "按钮2" ) . pack( pady= 5 )
tk. Label( right_frame, text= "右侧面板" , bg= "lightgreen" ) . pack( pady= 10 )
tk. Text( right_frame, width= 30 , height= 10 ) . pack( pady= 10 )
root. mainloop( )
Canvas画布
import tkinter as tk
root = tk. Tk( )
root. title( "Canvas示例" )
canvas = tk. Canvas( root, width= 400 , height= 300 , bg= "white" )
canvas. pack( )
canvas. create_line( 0 , 0 , 400 , 300 , fill= "red" , width= 2 )
canvas. create_rectangle( 50 , 50 , 150 , 100 , fill= "blue" , outline= "black" )
canvas. create_oval( 200 , 50 , 300 , 150 , fill= "green" , outline= "black" )
canvas. create_text( 200 , 200 , text= "Canvas文本" , font= ( "Arial" , 16 ) )
points = [ 100 , 250 , 150 , 200 , 200 , 250 , 175 , 280 , 125 , 280 ]
canvas. create_polygon( points, fill= "yellow" , outline= "black" )
root. mainloop( )
实战项目:简单计算器
import tkinter as tk
from tkinter import messagebox
class Calculator :
def __init__ ( self, root) :
self. root = root
self. root. title( "简单计算器" )
self. root. geometry( "300x400" )
self. root. resizable( False , False )
self. result_var = tk. StringVar( )
self. result_var. set ( "0" )
self. create_widgets( )
def create_widgets ( self) :
display_frame = tk. Frame( self. root)
display_frame. pack( fill= tk. X, padx= 10 , pady= 10 )
display = tk. Entry( display_frame,
textvariable= self. result_var,
font= ( "Arial" , 16 ) ,
justify= tk. RIGHT,
state= "readonly" )
display. pack( fill= tk. X)
button_frame = tk. Frame( self. root)
button_frame. pack( fill= tk. BOTH, expand= True , padx= 10 , pady= 10 )
buttons = [
[ 'C' , '±' , '%' , '÷' ] ,
[ '7' , '8' , '9' , '×' ] ,
[ '4' , '5' , '6' , '-' ] ,
[ '1' , '2' , '3' , '+' ] ,
[ '0' , '.' , '=' , '=' ]
]
for i, row in enumerate ( buttons) :
for j, text in enumerate ( row) :
if text == '=' :
if j == 2 :
continue
btn = tk. Button( button_frame, text= text,
font= ( "Arial" , 14 ) ,
command= lambda : self. calculate( ) )
btn. grid( row= i, column= j, columnspan= 2 ,
sticky= "nsew" , padx= 2 , pady= 2 )
else :
btn = tk. Button( button_frame, text= text,
font= ( "Arial" , 14 ) ,
command= lambda t= text: self. button_click( t) )
btn. grid( row= i, column= j, sticky= "nsew" , padx= 2 , pady= 2 )
for i in range ( 5 ) :
button_frame. grid_rowconfigure( i, weight= 1 )
for j in range ( 4 ) :
button_frame. grid_columnconfigure( j, weight= 1 )
def button_click ( self, char) :
current = self. result_var. get( )
if char == 'C' :
self. result_var. set ( "0" )
elif char == '±' :
if current != "0" :
if current. startswith( '-' ) :
self. result_var. set ( current[ 1 : ] )
else :
self. result_var. set ( '-' + current)
elif char in '0123456789.' :
if current == "0" and char != '.' :
self. result_var. set ( char)
else :
self. result_var. set ( current + char)
elif char in '÷×-+%' :
if not current. endswith( ( '÷' , '×' , '-' , '+' , '%' ) ) :
self. result_var. set ( current + char)
def calculate ( self) :
try :
expression = self. result_var. get( )
expression = expression. replace( '÷' , '/' )
expression = expression. replace( '×' , '*' )
result = eval ( expression)
self. result_var. set ( str ( result) )
except :
messagebox. showerror( "错误" , "计算错误" )
self. result_var. set ( "0" )
if __name__ == "__main__" :
root = tk. Tk( )
calculator = Calculator( root)
root. mainloop( )
最佳实践
1. 代码组织
import tkinter as tk
from tkinter import ttk, messagebox
class MyApplication :
def __init__ ( self, root) :
self. root = root
self. setup_window( )
self. create_variables( )
self. create_widgets( )
self. setup_layout( )
self. bind_events( )
def setup_window ( self) :
self. root. title( "我的应用" )
self. root. geometry( "800x600" )
def create_variables ( self) :
self. name_var = tk. StringVar( )
self. age_var = tk. IntVar( )
def create_widgets ( self) :
pass
def setup_layout ( self) :
pass
def bind_events ( self) :
pass
2. 错误处理
import tkinter as tk
from tkinter import messagebox
def safe_operation ( ) :
try :
result = int ( entry. get( ) )
label. config( text= f"结果: { result} " )
except ValueError:
messagebox. showerror( "错误" , "请输入有效的数字" )
except Exception as e:
messagebox. showerror( "错误" , f"发生未知错误: { str ( e) } " )
3. 响应式设计
import tkinter as tk
root = tk. Tk( )
root. grid_rowconfigure( 0 , weight= 1 )
root. grid_columnconfigure( 0 , weight= 1 )
frame = tk. Frame( root)
frame. grid( row= 0 , column= 0 , sticky= "nsew" , padx= 10 , pady= 10 )
frame. grid_rowconfigure( 1 , weight= 1 )
frame. grid_columnconfigure( 0 , weight= 1 )
label = tk. Label( frame, text= "标题" )
label. grid( row= 0 , column= 0 , sticky= "ew" )
text_widget = tk. Text( frame)
text_widget. grid( row= 1 , column= 0 , sticky= "nsew" )
root. mainloop( )
常见问题与解决方案
1. 中文显示问题
import tkinter as tk
root = tk. Tk( )
font = ( "Microsoft YaHei" , 12 )
label = tk. Label( root, text= "中文显示" , font= font)
label. pack( )
root. mainloop( )
2. 窗口居中显示
import tkinter as tk
def center_window ( root, width, height) :
screen_width = root. winfo_screenwidth( )
screen_height = root. winfo_screenheight( )
x = ( screen_width - width) // 2
y = ( screen_height - height) // 2
root. geometry( f" { width} x { height} + { x} + { y} " )
root = tk. Tk( )
center_window( root, 800 , 600 )
root. mainloop( )
3. 防止窗口重复创建
import tkinter as tk
class SingletonWindow :
_instance = None
def __new__ ( cls) :
if cls. _instance is None :
cls. _instance = super ( ) . __new__( cls)
cls. _instance. root = tk. Tk( )
return cls. _instance
def show ( self) :
self. root. deiconify( )
self. root. lift( )
总结
tkinter作为Python的标准GUI库,具有以下优势:
内置支持 :无需额外安装,Python自带跨平台 :支持Windows、macOS、Linux简单易学 :API设计简洁,容易上手功能完整 :提供了构建桌面应用的基本组件文档丰富 :官方文档和社区资源充足
通过本文的详细介绍,你应该已经掌握了tkinter的核心概念和常用组件。建议多动手实践,从简单的程序开始,逐步构建更复杂的应用程序。
记住,GUI编程的关键在于:
合理的布局设计 良好的用户体验 适当的错误处理 清晰的代码结构
结尾
希望对初学者有帮助;致力于办公自动化的小小程序员一枚 希望能得到大家的【❤️一个免费关注❤️】感谢! 求个 🤞 关注 🤞 +❤️ 喜欢 ❤️ +👍 收藏 👍