我需要设法在触摸屏上获取用户签名

Posted

技术标签:

【中文标题】我需要设法在触摸屏上获取用户签名【英文标题】:I need to make a way to take a users signature on a touch screen 【发布时间】:2019-05-11 08:21:57 【问题描述】:

我正在制作一个 POS 系统,并且我想包含一个选项,以便在购买后进行签名。我已经尝试过使用画布的 Tkinter 方法,但是速度很慢,而且非常四四方方,有什么建议吗?

这是我现在正在使用的代码:

from tkinter import *

canvas_width = 500
canvas_height = 150

def paint( event ):
   python_green = "#476042"
   x1, y1 = ( event.x - 1 ), ( event.y - 1 )
   x2, y2 = ( event.x + 1 ), ( event.y + 1 )
   w.create_oval( x1, y1, x2, y2, fill = python_green )

master = Tk()
master.title( "Painting using Ovals" )
w = Canvas(master, 
           width=canvas_width, 
           height=canvas_height)
w.pack(expand = YES, fill = BOTH)
w.bind( "<B1-Motion>", paint )

message = Label( master, text = "Press and Drag the mouse to draw" )
message.pack( side = BOTTOM )

mainloop()

顺便说一句,这段代码不是我的,我是从this 网站获得的

【问题讨论】:

【参考方案1】:

这是一个简单的 tkinter 绘图应用程序。

from tkinter import *


b1 = "up"
xold, yold = None, None
display_width = '500'
display_height = '500'
canvas_width = '500'
canvas_height = '500'
def main():
    root = Tk()
    root.geometry((display_width+"x"+display_height))


    drawing_area = Canvas(root,width=canvas_width,height=canvas_height,bg="white")
    drawing_area.bind("<Motion>", motion)
    drawing_area.bind("<ButtonPress-1>", b1down)
    drawing_area.bind("<ButtonRelease-1>", b1up)
    drawing_area.pack(side=RIGHT)
    root.mainloop()

def b1down(event):
    global b1
    x1, y1 = ( event.x - 4 ), ( event.y - 4 )
    x2, y2 = ( event.x + 4 ), ( event.y + 4 )
    event.widget.create_oval( x1, y1, x2, y2, fill = "black" )
    b1 = "down"           # you only want to draw when the button is down
                          # because "Motion" events happen -all the time-

def b1up(event):
    global b1, xold, yold
    b1 = "up"
    xold = None           # reset the line when you let go of the button
    yold = None

def motion(event):
    if b1 == "down":
        global xold, yold
        x1, y1 = ( event.x - 4 ), ( event.y - 4 )
        x2, y2 = ( event.x + 4 ), ( event.y + 4 )
        event.widget.create_oval( x1, y1, x2, y2, fill = "black" )
        if xold is not None and yold is not None:
            python_green = "#476042"
            x1, y1 = ( event.x - 4 ), ( event.y - 4 )
            x2, y2 = ( event.x + 4 ), ( event.y + 4 )
            event.widget.create_oval( x1, y1, x2, y2, fill = "black" )
            event.widget.create_line(xold,yold,event.x,event.y,smooth=TRUE,width=9)
    # here's where you draw it. smooth. neat.
        xold = event.x
        yold = event.y

if __name__ == "__main__":
    main()

【讨论】:

【参考方案2】:

一个干净的例子:

import tkinter as tk

class Signature(tk.Canvas):
    def __init__(self, *args, **kwargs):
        self.thickness = kwargs.pop('thickness', 4)
        tk.Canvas.__init__(self, *args, **kwargs)
        self._xold = None
        self._yold = None

        self.bind('<B1-Motion>', self._on_motion)

    def _on_motion(self, event):
        x1, y1 = ( event.x - self.thickness ), ( event.y - self.thickness )
        x2, y2 = ( event.x + self.thickness ), ( event.y + self.thickness )
        event.widget.create_oval( x1, y1, x2, y2, fill='black' )
        if self._xold is not None and self._yold is not None:
            self.create_oval( x1, y1, x2, y2, fill='black' )
            self.create_line(self._xold,self._yold,event.x,event.y,smooth=True,width=self.thickness*2+1)
    # here's where you draw it. smooth. neat.
        self._xold = event.x
        self._yold = event.y

if __name__ == '__main__':
    canvas_width = '500'
    canvas_height = '500'

    root = tk.Tk()
    sig = Signature(root, width=canvas_width,height=canvas_height,bg='white', thickness=1)
    sig.pack()

    root.mainloop()

请注意,这会在事件的位置绘制一个椭圆,并用一条线将其与最后一个事件连接起来,这有助于平滑线。

【讨论】:

请注意,如果你真的想保存结果,你需要使用另一个图形库,因为 tk 没有内置的。以前我使用过 PIL 或枕头。 我可以使用 PIL 保存画布,我不必使用其他库 @JamesKent 有没有办法减少绘图的厚度? @Miraj50 我已经编辑了示例以包含厚度参数,请注意,在绘制线条时,偏移量是 + 和 - “厚度”,而在绘制椭圆时,尺寸是厚度的两倍加一像素,这是使其平滑所必需的。这意味着它实际上可以是最薄的 2 像素。 @AviBaruch 确切地说,PIL 不是 tkinter 的一部分,它是另一个工具包。它与 tkinter 集成,使事情变得比以前更容易,但它不是内置的。

以上是关于我需要设法在触摸屏上获取用户签名的主要内容,如果未能解决你的问题,请参考以下文章

Flutter 实现手写签名效果

缩放和翻译后如何获得相对于画布的触摸坐标?

获取触摸 UIView 的手指数

如何在 UIPanGestureRecognizer 方法中获取当前触摸点和上一个触摸点?

如何获取用户触摸的 PDF 对象(字符串、图像等)?

在 iOS 中如何在后台运行状态下获取全局触摸事件通知?