Introducción
A menudo es necesario escribir algunos scripts, configurar algunos parámetros e iniciar cálculos, y esperar que sea accesible para otros, y lo ejecutará de manera visual.
Utilice principalmente la biblioteca tkinter, en términos de diseño, puede construir un Marco por línea y empaquetarlo en la ventana. Los marcos en cada línea se pueden diseñar por paquete o cuadrícula o lugar. Por analogía, se pueden extender múltiples controles
Flujo de trabajo simple
Cada control de botón de la ventana generará eventos y, por lo general, volverá a llamar a las funciones, pero está bloqueado en el hilo principal para devolver la llamada. Es imposible para nosotros crear hilos para ejecutar de forma asincrónica cada vez, por lo que usamos una cola de mensajes para desacoplar los eventos de los botones. Y la función de procesamiento de devolución de llamada, el consumidor consume el mensaje de la cola original para determinar directamente el consumo del tipo de mensaje, pero en aras de la brevedad del código, se entrega a otra clase para su procesamiento.
efecto
Código fuente
Realice cálculos personalizados en la función start_demo
import queue
import threading
import time
import traceback
from tkinter import Tk, Button, messagebox, Label, Frame, LEFT, Entry, IntVar, Radiobutton, StringVar, Checkbutton, \
BooleanVar, RIGHT, constants, Scale, HORIZONTAL, Variable, filedialog, Text, font, Scrollbar
from tkinter. font import Font, BOLD
from tkinter. messagebox import showinfo, showerror, showwarning
from tkinter. ttk import Combobox, Widget
from enum import Enum
from import GuiTempldate
class MsgEnum ( Enum) :
"""
消息类型枚举
"""
START = 0
STOP = 1
EXIT = 3
def start_demo ( gui: GuiTempldate) :
""" 自定义计算任务
:param gui: gui组件对象
:return:
"""
count = 20
while gui. Cache. RUNING:
count -= 1
gui. text_btn. insert( constants. END, f"cd {count}\n" )
gui. text_btn. see( constants. END)
time. sleep( 1 )
class GuiTempldate :
class Cache :
RUNING = False
def __init__ ( self) - > None :
self. msg_center = MsgCenter( self)
self. root = Tk( )
self. root. title( "xxx工具" )
self. root. geometry( '500x600+500+200' )
self. root. protocol( "WM_DELETE_WINDOW" , self. close_event)
self. url_var = None
self. url_btn = None
self. mode_var = None
self. name_var = None
self. name_btn = None
self. is_xx_btn = None
self. is_xx_var = None
self. level_var = None
self. scale_btn = None
self. start_btn = None
self. stop_btn = None
self. select_file_var = None
self. text_btn = None
self. initGui( )
def initGui ( self) :
text_str = """版本: 2.0.1
#author burukeyou
#说明:
1) 这是关于
2) 请先开始再停止"""
Label( self. root, text= text_str, justify= 'left' , fg= 'red' ) . pack( anchor= constants. W)
Label( self. root, text= '请求接口' ) . pack( anchor= constants. W)
self. url_var = StringVar( value= "http://www.baidu.com" )
self. url_btn = Entry( self. root, width= 60 , textvariable= self. url_var)
self. url_btn. pack( anchor= constants. W)
self. mode_var = IntVar( value= 1 )
fm01 = Frame( self. root)
fm01. pack( anchor= constants. W)
Label( fm01, text= '模式' ) . grid( row= 0 , column= 0 , sticky= 'W' )
Radiobutton( fm01, text= 'a模式' , variable= self. mode_var, value= 1 ) . grid( row= 0 , column= 1 , sticky= 'E' , padx= 40 )
Radiobutton( fm01, text= 'b模式' , variable= self. mode_var, value= 2 ) . grid( row= 0 , column= 2 , sticky= 'E' , padx= 40 )
Radiobutton( fm01, text= 'c模式' , variable= self. mode_var, value= 3 ) . grid( row= 0 , column= 3 , sticky= 'E' , padx= 40 )
fm02 = Frame( self. root)
self. name_var = StringVar( value= 100 )
fm02. pack( anchor= constants. W, fill= constants. X)
Label( fm02, text= '名字 ' ) . pack( side= constants. LEFT)
self. name_btn = Entry( fm02, width= 20 , textvariable= self. name_var)
self. name_btn. pack( side= constants. RIGHT)
self. is_xx_var = BooleanVar( )
self. is_xx_btn = Checkbutton( self. root, variable= self. is_xx_var, text= '是否xxx' , onvalue= True , offvalue= False )
self. is_xx_btn. pack( anchor= constants. W)
fm03 = Frame( self. root)
fm03. pack( anchor= constants. W, fill= constants. X)
self. level_var = StringVar( )
Label( fm03, text= '统计级别 ' ) . pack( side= constants. LEFT)
com = Combobox( fm03, textvariable= self. level_var)
com. pack( side= constants. RIGHT)
com[ "value" ] = ( "级别0" , "级别1" , "级别2" )
com. current( 1 )
fm04 = Frame( self. root)
fm04. pack( anchor= constants. W, fill= constants. X)
Label( fm04, text= '范围: ' ) . pack( side= constants. LEFT)
self. scale_btn = Scale( fm04, from_= 0 , to= 100 , orient= constants. HORIZONTAL, tickinterval= 100 , length= 200 )
self. scale_btn. pack( side= constants. RIGHT)
self. scale_btn. set ( 20 )
fm05 = Frame( self. root)
fm05. pack( anchor= constants. W, fill= constants. X)
self. select_file_var = StringVar( value= "你没有选择任何文件" )
Button( fm05, text= "选择处理的文件" , command= self. click_file_event) . pack( side= constants. LEFT)
Label( fm05, textvariable= self. select_file_var) . pack( side= constants. RIGHT)
fm22 = Frame( self. root)
fm22. pack( anchor= constants. W, fill= constants. X)
scroll = Scrollbar( fm22)
scroll. pack( side= constants. RIGHT, fill= constants. Y)
ft = Font( family= '微软雅黑' , size= 18 , weight= font. BOLD)
self. text_btn = Text( fm22, height= 9 , fg= "green" , font= ft, bg= "black" , insertbackground= "red" )
self. text_btn. pack( side= constants. LEFT)
scroll. config( command= self. text_btn. yview)
self. text_btn. config( yscrollcommand= scroll. set )
fm06 = Frame( self. root)
self. start_btn = Button( fm06, text= "开始" , width= 6 , height= 1 , command= self. start_event)
self. start_btn. grid( row= 0 , column= 0 , sticky= 'W' , padx= 20 , pady= 20 )
self. stop_btn = Button( fm06, text= "停止" , width= 6 , height= 1 , command= self. stop_event)
self. stop_btn. grid( row= 0 , column= 1 , sticky= 'E' , padx= 20 , pady= 20 )
fm06. pack( side= constants. BOTTOM)
def start_event ( self) :
self. msg_center. put( MsgEnum. START)
self. Cache. RUNING = True
threading. Thread( target= start_demo, args= ( self, ) ) . start( )
def stop_event ( self) :
self. msg_center. put( MsgEnum. STOP)
self. Cache. RUNING = False
def click_file_event ( self) :
filename = filedialog. askopenfilename( )
if filename != '' :
self. select_file_var. set ( filename)
print ( self. select_file_var. get( ) )
def close_event ( self) :
if self. Cache. RUNING and not messagebox. askokcancel( "警告" , "任务还在执行中,确定要关闭吗?" ) :
return
self. root. destroy( )
self. msg_center. put( MsgEnum. EXIT)
def showUI ( self) :
threading. Thread( target= self. msg_center. mainloop) . start( )
self. root. mainloop( )
class MsgCenter :
"""
消息队列
主要处理窗口控件消息
"""
def __init__ ( self, obj: GuiTempldate) - > None :
self. queue = queue. Queue( )
self. obj = obj
def put ( self, msg: Enum) :
self. queue. put( msg)
def mainloop ( self) :
while True :
try :
msg = self. queue. get( )
print ( "消费消息: {}" . format ( msg) )
if msg == MsgEnum. START:
MsgStrategy. start_strategy( self. obj)
elif msg == MsgEnum. STOP:
MsgStrategy. stop_strategy( self. obj)
elif msg == MsgEnum. EXIT:
break
else :
pass
except queue. Empty:
traceback. print_exc( )
class MsgStrategy :
@classmethod
def start_strategy ( cls, gui: GuiTempldate) :
gui. start_btn. config( state= constants. DISABLED)
gui. stop_btn. config( state= constants. NORMAL)
gui. is_xx_btn. config( state= constants. DISABLED)
gui. scale_btn. config( state= constants. DISABLED)
gui. url_btn. config( state= constants. DISABLED)
gui. name_btn. config( state= constants. DISABLED)
val = f"""
接口:[{gui.url_var.get()}]
模式:[{gui.mode_var.get()}]
名字:[{gui.name_var.get()}]
是否xx: [{gui.is_xx_var.get()}]
统计级别:[{gui.level_var.get()}]
范围: [{gui.scale_btn.get()}]
文件: [{gui.select_file_var.get()}]
"""
showinfo( "" , val)
@classmethod
def stop_strategy ( cls, gui: GuiTempldate) :
gui. start_btn. config( state= constants. NORMAL)
gui. stop_btn. config( state= constants. DISABLED)
gui. is_xx_btn. config( state= constants. NORMAL)
gui. scale_btn. config( state= constants. NORMAL)
gui. url_btn. config( state= constants. NORMAL)
gui. name_btn. config( state= constants. NORMAL)
if __name__ == '__main__' :
gui = GuiTempldate( )
gui. showUI( )
Recompensa
Si encuentra útil el artículo, puede animar al autor