使用tkinter编写好的界面,有时需要改变界面的大小,而拖动改变窗口大小时,代码写好的组件布局不能够自动刷新改变位置和大小,特别是复杂界面,或者使用place布局时,在很长一段时间内我都放弃了对tkinter库写的界面允许改变界面大小,最近偶然发现place的新用法,实现了界面的自动刷新布局,这里记录一下。
养成好习惯,界面代码和逻辑代码分离,创建一个python文件tkUI.py,内容如下:
import tkinter as tk
from tkinter import ttk
import ctypes
ctypes.windll.shcore.SetProcessDpiAwareness(1)
class mytkinter(tk.Tk):
width=800
height=600
ROW=10
COL=10
first_load=True
def setupUi(self):
self.config(bg='#666888', bd=0)
self.title("YOLOv5 检测")
screen_width = self.winfo_screenwidth()
screen_height = self.winfo_screenheight()
print(screen_width, screen_height)
center_geometry = [int(screen_width / 2 - self.width / 2), int(screen_height / 2 - self.height / 2)]
geometry_str = "{}x{}+{}+{}".format(self.width, self.height, center_geometry[0], center_geometry[1])
print(geometry_str)
self.geometry(geometry_str)
self.cv = tk.Canvas(self, bg='snow')
self.tab_main = ttk.Notebook(self.cv)
self.tab1 = tk.Frame(self.tab_main, bg='snow')
self.tab1.place(relx=0.05, rely=0.1, relwidth=0.9, relheight=0.9)
self.tab_main.add(self.tab1, text='图像检测')
self.tab2 = tk.Frame(self.tab_main, bg='ivory')
self.tab2.place(relx=0.05, rely=0.1, relwidth=0.9, relheight=0.9)
self.tab_main.add(self.tab2, text='视频检测')
self.tab3 = tk.Frame(self.tab_main, bg='#eeebbb')
self.tab3.place(relx=0.05, rely=0.1, relwidth=0.9, relheight=0.9)
self.tab_main.add(self.tab3, text='摄像头检测')
self.tab4 = tk.Frame(self.tab_main, bg='#666888')
self.tab4.place(relx=0.05, rely=0.1, relwidth=0.9, relheight=0.9)
self.tab_main.add(self.tab4, text='设置')
self.VLabel1 = self.myViewLabel(self.tab1, 0.005, 0.1, 0.49, 0.9)
self.VLabel2 = self.myViewLabel(self.tab1, 0.505, 0.1, 0.49, 0.9)
self.VLabel3 = self.myViewLabel(self.tab2, 0.005, 0.1, 0.49, 0.9)
self.VLabel4 = self.myViewLabel(self.tab2, 0.505, 0.1, 0.49, 0.9)
self.VLabel5 = self.myViewLabel(self.tab3, 0.005, 0.1, 0.49, 0.9)
self.VLabel6 = self.myViewLabel(self.tab3, 0.505, 0.1, 0.49, 0.9)
self.btn1=tk.Button(self.tab4,text='选择权重',bd=0,bg='black',fg='white')
self.btn1.place(relx=0.01,rely=0.05,width=100,height=30)
self.label1=tk.Label(self.tab4,text="yolov5s.pt")
self.label1.place(relx=0.01,x=105,rely=0.05,relwidth=0.98,width=-105,height=30)
self.label2 = tk.Label(self.tab4, text="图片大小",bd=0,bg='black',fg='white')
self.label2.place(relx=0.01,rely=0.05,y=50,width=100,height=30)
self.var2=tk.StringVar()
self.entry2=tk.Entry(self.tab4,textvariable=self.var2)
self.entry2.place(relx=0.01,x=105,rely=0.05,y=50,relwidth=0.48,width=-105,height=30)
self.var2.set("640")
self.label3 = tk.Label(self.tab4, text="置信度阈值", bd=0, bg='black', fg='white')
self.label3.place(relx=0.51, rely=0.05, y=50, width=100, height=30)
self.var3 = tk.StringVar()
self.entry3 = tk.Entry(self.tab4, textvariable=self.var3)
self.entry3.place(relx=0.51, x=105, rely=0.05, y=50, relwidth=0.48, width=-105, height=30)
self.var3.set("0.25")
self.label4 = tk.Label(self.tab4, text="iou阈值", bd=0, bg='black', fg='white')
self.label4.place(relx=0.01, rely=0.05, y=100, width=100, height=30)
self.var4 = tk.StringVar()
self.entry4 = tk.Entry(self.tab4, textvariable=self.var4)
self.entry4.place(relx=0.01, x=105, rely=0.05, y=100, relwidth=0.48, width=-105, height=30)
self.var4.set("0.45")
self.label5 = tk.Label(self.tab4, text="目标最大数", bd=0, bg='black', fg='white')
self.label5.place(relx=0.51, rely=0.05, y=100, width=100, height=30)
self.var5 = tk.StringVar()
self.entry5 = tk.Entry(self.tab4, textvariable=self.var5)
self.entry5.place(relx=0.51, x=105, rely=0.05, y=100, relwidth=0.48, width=-105, height=30)
self.var5.set("100")
self.label6 = tk.Label(self.tab4, text="检测设备选择", bd=0, bg='black', fg='white')
self.label6.place(relx=0.01, rely=0.05, y=150, width=100, height=30)
self.var6 = tk.StringVar()
self.entry6 = tk.Entry(self.tab4, textvariable=self.var6)
self.entry6.place(relx=0.01, x=105, rely=0.05, y=150, relwidth=0.48, width=-105, height=30)
self.var6.set("0")
self.btn2=tk.Button(self.tab4,text="保存设置", bd=0, bg='black', fg='white')
self.btn2.place(relx=0.51, rely=0.05, y=150, relwidth=0.48, height=30)
def myViewLabel(self,master,relx,rely,relwidth,relheight):
label=tk.Label(master,bg='#666888',bd=0)
label.place(relx=relx,rely=rely,relwidth=relwidth,relheight=relheight)
return label
然后是逻辑代码,命名为main.py吧。重点是窗口绑定事件self.bind(‘’, self.window_resize)和刷新布局函数myplace(),先定义一个Canvas作为GUI的背景,然后所有的组件均在Canvas上布置,使用place布局中的relx,rely,relwidth,relheight四个参数,它们表示相对于父容器的位置和宽高,值在0.0~1.0之间,每次窗口变化时,触发window_resize()函数,修改变量width和height的值,再运行myplace()函数,重新布局Canvas的位置和大小,之后以Canvas为父容器的组件,在Canvas刷新之后自动根据place布局描述的位置大小自动刷新。实现逻辑代码如下:
from TkUI import mytkinter
class MyTk(mytkinter):
def __init__(self):
super().__init__()
self.setupUi()
self.tab_main.place(relx=0, rely=0, relwidth=1, relheight=1)
self.myplace()
self.bind('<Configure>', self.window_resize)
def myplace(self):
self.cv.place(x=0,y=0,width=self.width,height=self.height)
def window_resize(self,event=None):
if event:
if self.winfo_width()==self.width and self.winfo_height()==self.height:
return
if self.first_load:
self.first_load=False
return
self.width=self.winfo_width()
self.height=self.winfo_height()
self.myplace()
lab1 = Label(window, text='one', bg='lightyellow', width=20)
lab2 = Label(window, text='two', bg='lightgreen', width=20)
lab3 = Label(window, text='three', bg='lightblue', width=20
最近正在做一个关于Tkinter的编程,发现Tk虽然通过按键,能实现相关函数的刷新,使得窗口中的数据也实时更新。但我现在冒出这样一个念头,要是我想不通过按键实现某些数据的实时刷新,应该怎么做?
起初我便在Tk编程中加入一个while循环,使数据进行刷新,结果导致程序卡在whlie循环出不来,界面也不好操控。因为Tk是在mian.loop()中进行的实时刷新,在程序中...
今天回答了几个和
tkinter 相关的问题,都是和界面,控件,事件相关,结合这段时间都在手机答题, 题
库查询太麻烦。就做了这个例子。
本例子用到
Tkinter 库。 包含
Tkinter 的 Label , Entry , Button , Text 还有相关事件。 完成题
库的查询显示功能。
控件
大小自适应界面
变化。
数据包含100道学习强国的题目。
python中tkinter的Canvas绘图不显示的解决方法1、如下为绘图不成功的代码2、解决办法3、原因
1、如下为绘图不成功的代码
from tkinter import *
import math
WIDTH, HEIGHT = 510, 210
ORIGIN_X, ORIGIN_Y = 2, HEIGHT/2 #原点
SCALE_X, SCALE_Y = 40, 100 #x轴、y轴缩放倍数
ox, oy = 0, 0
x, y = 0, 0
arc = 0 #弧度
END_ARC = 360