簡體   English   中英

Tkinter<enter> 永遠綁定循環</enter>

[英]Tkinter <Enter> bind looping forever

我正在嘗試為事件制作一個可選擇的鍾面。 我有我的 Canvas 對象,並創建了一堆里面有文字的圓圈。

我想在鼠標懸停時反轉圓圈和文本的顏色。

問題是:

  • 在圓圈內輸入文本時檢測到。
  • 移動太快會導致重復進入/離開循環,從而導致程序崩潰。

代碼:

from tkinter import *
from math import sin, cos, pi
root = Tk()

class TimePicker(Canvas):
    def __init__(self, master, **kwargs):
        self.tformat = kwargs.pop('format', 24)
        self.width, self.height, self.radious = kwargs['width'], kwargs['height'], rd = (kwargs.pop('radious', 100)*2, )*3
        self.radious /=4
        assert self.tformat in [12, 24], "Time Format must be '12' or '24'"
        super(TimePicker, self).__init__(master, **kwargs)
        self.active_line = None
        self.create_center_circle(self.width/2, self.height/2, self.radious*2, fill="white", outline="#000", width=1)
        self.circle_numbers(self.width/2, self.height/2, self.radious+5, 10, [12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], 'Helvetica 11 bold', "Hours")
        self.circle_numbers(self.width/2, self.height/2, self.radious*2-15, 10, [0, 15, 30, 45], 'Helvetica 11 bold', "Minutes")

    def create_center_circle(self, x, y, r, **kwargs):
        return super().create_oval(x-r, y-r, x+r, y+r, **kwargs)
    def create_circle_arc(self, x, y, r, **kwargs):
        if "start" in kwargs and "end" in kwargs:
            kwargs["extent"] = kwargs["end"] - kwargs["start"]
            del kwargs["end"]
        return super().create_arc(x-r, y-r, x+r, y+r, **kwargs)
    def circle_numbers(self, x: int, y: int, r: int, cr:int, numbers: list, font: str, tp:str):
        _angle = 360/len(numbers)
        for n in numbers:
            ax =  r * sin(pi * 2 * (360-_angle*n-180) / 360);
            ay = r * cos(pi * 2 * (360-_angle*n-180) / 360);
            tag = f'{tp}:{str(n)}'
            cl = self.create_center_circle(x+ax, y+ay, cr, fill="white", outline="#000", width=1, tag=tag)
            tx = self.create_text(x+ax, y+ay, text=str(n).zfill(2), fill="black", font=(font), tag='tx'+tag )
            self.tag_bind(f'{tp}:{str(n)}', '<Enter>', lambda e=Event(), c=(x+ax, y+ay), t=tag, s=True: self._hover(e, c, s, t))
            self.tag_bind(f'{tp}:{str(n)}', '<Leave>', lambda e=Event(), c=(x+ax, y+ay), t=tag, s=False: self._hover(e, c, s, t))
            self.tag_bind(f'{tp}:{str(n)}', '<Button-1>', lambda e=Event(), c=cl, s=tx, n=n, t=tp,: self._set_number(e, c, s, n, t))

    def _hover(self, event, coords, state, tag):
        print('hover')
        if state: # If hovering inside the object
            print("hovering")
            cl =event.widget.find_withtag(tag) ## for the text and circle with the hovered tag
            tx = event.widget.find_withtag('tx'+tag)
            self.itemconfigure(cl, fill='black')
            self.itemconfigure(tx, fill="white")
            self.active_line = self.create_line(self.width/2, self.height/2, coords[0], coords[1], fill="black", width=2) ##create new line
        else: ##If left the object
            print("exited")
            if self.active_line is not None: ##if there is a line
                cl = event.widget.find_withtag(tag) ## for the text and circle in the tag
                tx = event.widget.find_withtag('tx'+tag)
                self.itemconfigure(cl, fill='white')
                self.itemconfigure(tx, fill="black")
                self.delete(self.active_line)
                self.active_line = None

    def _set_number(self, event, cl, tx, number, tp):
        print('set', cl, tx, number, tp)




if __name__ == '__main__':
    tp=TimePicker(root, format=24, background="red", radious=100)
    tp.pack(side=TOP)
    root.mainloop()

我在測試時意識到,當創建一條線並且該線恰好位於鼠標光標下方時,將為文本觸發<Leave>事件,然后刪除導致<Enter>事件的線再次在光標下繪制線.

對此的解決方案是使線更短並且不允許它進入與鼠標相同的空間。

作為快速修復,我將線縮短了 20%,但是完整的解決方案需要檢查線是否在鼠標下方並觸發標志以防止線被破壞。

    def _hover(self, event, coords, state, tag):
        ...
        self.itemconfigure(tx, fill="white")
        dx = (1 - 0.8) * self.width/2 + 0.8 * coords[0]
        dy = (1 - 0.8) * self.height/2 + 0.8 * coords[1]
        self.active_line = self.create_line(self.width/2, self.height/2, dx, dy, fill="#0797FF", width=2, tag=None) ##create new line

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM