添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
相关文章推荐
阳刚的火腿肠  ·  Can't connect via SSH ...·  6 天前    · 
纯真的领结  ·  AVAide DVD Ripper – ...·  1 月前    · 
重感情的汉堡包  ·  GitHub - ...·  1 年前    · 
有腹肌的玉米  ·  Java Runtime not ...·  1 年前    · 

使用tkinter编写好的界面,有时需要改变界面的大小,而拖动改变窗口大小时,代码写好的组件布局不能够自动刷新改变位置和大小,特别是复杂界面,或者使用place布局时,在很长一段时间内我都放弃了对tkinter库写的界面允许改变界面大小,最近偶然发现place的新用法,实现了界面的自动刷新布局,这里记录一下。

一、place布局

tkinter的布局方式有三种,pack布局、grid布局以及place布局,我比较喜欢的、也使用的最多的是place布局,因为它可以准确的将控件放置在任何想要的位置,参数是x,y,width,height,分别表示控件的左上角点在父容器中的x、y坐标,和控件的宽、高。
一直以来我都只任务place只有这4个参数,因为定义死了它的位置和大小,当改变窗口大小时,想改变控件位置大小则需要重新计算相应的位置与宽高,当控件数量很多时是很麻烦是事情,代码量也增加很多,故很多次想实现自动刷新控件位置大小的功能都放弃了,最近仔细了解了一下place布局,发现它还有4个参数,配合之前4个参数使用,是真香啊。

二、直接上代码

养成好习惯,界面代码和逻辑代码分离,创建一个python文件tkUI.py,内容如下:

import tkinter as tk
from tkinter import ttk
# from PIL import Image,ImageTk
import ctypes                   #可让python与C语言混合使用
#告诉操作系统使用程序自身的dpi适配
ctypes.windll.shcore.SetProcessDpiAwareness(1)
class mytkinter(tk.Tk):
    width=800
    height=600
    ROW=10
    COL=10
    first_load=True
    # def __init__(self):
    #     super().__init__()
    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.style_1=ttk.Style()
        # self.style_1.configure("TLabel",foreground='black',background='ivory')
        self.tab_main = ttk.Notebook(self.cv)
        # self.tab_main.pack(expand=1,fill='both')#这段代码很重要
        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='设置')
        #tab1
        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)
        # tab2
        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)
        # tab3
        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)
        # tab4
        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)
        # self.label.bind("<Double-Button-1>",lambda a:mytkinter().show_toplevel(self))
        return label
# top=mytkinter()
# # top.config(bg='red')
# top.mainloop()

然后是逻辑代码,命名为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):#place布局,self.cv作为父控件,其尺寸改变,其子控件大小相应刷新
        self.cv.place(x=0,y=0,width=self.width,height=self.height)
    def window_resize(self,event=None):
        if event:
            # print(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()
            # print(self.place_slaves(),self.place_slaves()[0].place_info())
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道学习强国的题目。
pythontkinter的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