Python Tkinter:在画布上测量我的线条的大小,单位为毫米

Python Tkinter:在画布上测量我的线条的大小,单位为毫米,python,tkinter,Python,Tkinter,我第一次用canvas和tkinter做这个项目,我只知道基本教程 我有一个Tkinter的应用程序。我想用毫米来测量我的线的大小 我试图修改所发布的代码,但效果不太好:文本不在中间,文本以粗体显示,未擦除。 我怎样才能解决这个问题 from math import hypot import tkinter as tk from tkinter.constants import * class Example(tk.Frame): def __init__(self, master,

我第一次用canvas和tkinter做这个项目,我只知道基本教程

我有一个Tkinter的应用程序。我想用毫米来测量我的线的大小

我试图修改所发布的代码,但效果不太好:文本不在中间,文本以粗体显示,未擦除。

我怎样才能解决这个问题

from math import hypot
import tkinter as tk
from tkinter.constants import *

class Example(tk.Frame):
    def __init__(self, master, dpu, units, *args, **kwargs):
        super().__init__(master, *args, **kwargs)
        self.dpu = dpu
        self.units = units
        self.initUI()

    def initUI(self):
        self.master.title("Lines")
        self.pack(fill=BOTH, expand=1)

        self.canvas = tk.Canvas(self)
        self.canvas.pack(fill=BOTH, expand=1)
        self.canvas.bind('<ButtonPress-1>', self.xy) #xy
        self.canvas.bind('<B1-Motion>', self.addLine) #addline
        self.canvas.bind('<ButtonRelease-1>', self.doneStroke) #donestrok
        self.canvas.bind('<Double-Button-1>', self.on_double_click)

        self.coords = {"x": 0, "y": 0, "x2": 0, "y2": 0}
        self.point_count = 0
        self.lines = []

    def on_double_click(self, event):
        self.canvas.delete('all')  # Clear screen.

    def xy(self, event):
            self.coords["x"] = self.canvas.canvasx(event.x)
            self.coords["y"] = self.canvas.canvasy(event.y)
            self.lines.append(self.canvas.create_line(self.coords["x"], self.coords["y"], self.coords["x"], self.coords["y"], width=2, tags='temp'))
    
    def addLine(self, event):
            self.coords["x2"] = self.canvas.canvasx(event.x)
            self.coords["y2"] = self.canvas.canvasy(event.y)
            self.canvas.coords(self.lines[-1], self.coords["x"], self.coords["y"], self.coords["x2"], self.coords["y2"])
            self.length = hypot(self.coords["x"] - self.coords["x2"],
            self.coords["y"] - self.coords["y2"]) / self.dpu
            self.midpoint = ((self.coords["x"] + self.coords["x"]) / 2,(self.coords["y"] + self.coords["y"]) / 2)
            self.canvas.create_text(*self.midpoint, justify='center', tags='temp',
            text=f'{self.length:.1f} {self.units}')
            
        
    def doneStroke(self, event):
            self.coords["x2"] = self.canvas.canvasx(event.x)
            self.coords["y2"] = self.canvas.canvasy(event.y)
            self.canvas.create_line(*self.coords.values(), width=2, tags='line')
            self.canvas.itemconfigure('currentline', width=5) # What happens if you set this to another number? 
            self.canvas.delete('temp')

def main():
    root = tk.Tk()
    scaling_factor = root.tk.call('tk', 'scaling', '-displayof', '.')
    ppi = scaling_factor * 72  # Pixels per inch.
    dpm = ppi * 0.0394  # Dots per millimeter.

    ex = Example(root, dpm, 'mm')
    root.geometry("400x250+300+300")
    root.mainloop()

if __name__ == '__main__':
    main()
从数学导入hypot
将tkinter作为tk导入
从tkinter.constants导入*
类示例(tk.Frame):
定义初始值(自身、主控、dpu、单位、*args、**kwargs):
super()。\uuuuu init\uuuuu(主参数,*args,**kwargs)
self.dpu=dpu
self.units=单位
self.initUI()
def initUI(self):
self.master.title(“行”)
self.pack(填充=两者,扩展=1)
self.canvas=tk.canvas(self)
self.canvas.pack(fill=BOTH,expand=1)
self.canvas.bind(“”,self.xy)#xy
self.canvas.bind(“”,self.addLine)#addLine
self.canvas.bind(“”,self.doneStroke)#donestrok
self.canvas.bind(“”,self.on_双击)
self.coords={x:0,y:0,x2:0,y2:0}
self.point\u count=0
self.lines=[]
双击def(自身,事件):
self.canvas.delete('all')#清除屏幕。
def xy(自身,事件):
self.coords[“x”]=self.canvas.canvasx(event.x)
self.coords[“y”]=self.canvas.canvasy(event.y)
self.lines.append(self.canvas.create_行(self.coords[“x”]、self.coords[“y”]、self.coords[“x”]、self.coords[“y”]、width=2、tags='temp'))
def addLine(自身、事件):
self.coords[“x2”]=self.canvas.canvasx(event.x)
self.coords[“y2”]=self.canvas.canvasy(event.y)
self.canvas.coords(self.lines[-1]、self.coords[“x”]、self.coords[“y”]、self.coords[“x2”]、self.coords[“y2”])
self.length=hypot(self.coords[“x”]-self.coords[“x2”],
self.coords[“y”]-self.coords[“y2”])/self.dpu
self.middpoint=((self.coords[“x”]+self.coords[“x”])/2,(self.coords[“y”]+self.coords[“y”])/2)
self.canvas.create_text(*self.midpoint,justify='center',tags='temp',
text=f'{self.length:.1f}{self.units}')
def doneStroke(自身、事件):
self.coords[“x2”]=self.canvas.canvasx(event.x)
self.coords[“y2”]=self.canvas.canvasy(event.y)
self.canvas.create_line(*self.coords.values(),width=2,tags='line'))
self.canvas.itemconfigure('currentline',width=5)#如果将其设置为另一个数字会发生什么?
self.canvas.delete('temp')
def main():
root=tk.tk()
scaling_factor=root.tk.call('tk','scaling','-displayof','
ppi=缩放系数*每英寸72像素。
dpm=ppi*0.0394#点/毫米。
ex=示例(根,dpm,'mm')
根几何(“400x250+300+300”)
root.mainloop()
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
main()

我已更改了您的部分代码。使用self.canvas.bbox()


你所说的线的大小——它的总长度到底是什么意思?无论如何,当您将坐标指定为数字时,它们被假定为屏幕像素值,并且这些值的大小取决于当前使用的硬件。您还可以将它们指定为绝对距离字符串值,后缀为该值表示的几个预定义单位之一的字符。看,是的,我想要总长度,但当我自己画一条以毫米为单位的线时,我更新了我的问题,你可以通过函数简单地计算出给定端点坐标的线的长度。问题是距离是以屏幕像素为单位的,而不是毫米,所以你需要处理这个问题——这就是为什么我在前面的评论中提到了另一个问题的链接。谢谢。但是我们在hypot中输入什么值来获得长度呢?来自
self.coords
self.lines
的(x,y)坐标对-我不确定,因为你问题中的代码无法运行。如果有多条线段,您需要多次这样做。我不知道距离是用什么格式表示的?毫米?我更新了我的问题对不起,是像素。这是更新代码。您是如何确定“1像素为0.26458333”的?在Web上看到的我认为这可能是一个问题,因为它在其他系统上可能不同,因此需要在运行时为代码当前运行的计算机确定这一点。
from tkinter import *

class Example:
    def __init__(self,root):
        self.master=root

        
        self.master.title("Lines")
        

        self.canvas = Canvas(self.master,bg="white")
        self.coords = {"x": 10, "y": 10, "x2": 100, "y2": 200}
        #self.lines = []
        x=self.canvas.create_line(self.coords.get("x"), self.coords.get("y"), self.coords.get("x2"), self.coords.get("y2"))
        bounds = self.canvas.bbox(x)  # returns a tuple like (x1, y1, x2, y2)
        width = bounds[2] - bounds[0]
        height = bounds[3] - bounds[1]
        print(round(height*0.2645833333,2)) #===1 pixel is 0.2645833333
        self.canvas.pack(fill=BOTH, expand=1)


def main():
    
     root = Tk()
     ex = Example(root)
     root.geometry("400x250+300+300")
     root.mainloop()
    
    
if __name__ == '__main__':
      main()