如何使tkinter< Enter> < button-1>被按下? [英] how to make tkinter <Enter> event work when <button-1> is pressed?

查看:86
本文介绍了如何使tkinter< Enter> < button-1>被按下?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想像在油漆中一样填充矩形。按下鼠标按钮时,我希望每个输入的矩形都被填充,否则我不希望发生任何事件。



这是我的代码:

 从tkinter导入画布
导入tkinter

_width = 50
_height = 50
_size = 8

root = tkinter.Tk()
root.title(画出一个可爱的矩阵)
canv = Canvas(root ,width = _width * _size,height = _height * _size)


class包装器:
btn1d = False


def set_btn1d( value):
print(值)
Wrapper.btn1d = value


def toggle_color(rect):
print('调用')
,如果Wrapper.btn1d:
color = canv.itemcget(rect,'fill')
canv.itemconfig(rect,fill =(#aaa if color =='#fff'else' #fff'))


rects = []
canv.bind('< ButtonPress-1>',lambda e,value = True:set_btn1d(value))
canv.bind('< ButtonRelease-1>',lambda e,value = False:set_btn1d(va lue))
for i in range(_size):
for j in range(_size):
rect = canv.create_rectangle(_width * j,_height * i,_width *(j + 1),_ height *(i + 1),fill =#fff,width = 0)
rects.append(rect)
canv.tag_bind(rect,'< Enter>',lambda e,rect = rect:toggle_color(rect))

canv.pack()
root.mainloop()

问题是,当我按下鼠标按钮时,只有按下鼠标的单元格才能检测到鼠标指针的进入(最后一个鼠标将被释放的单元格) )



关于我的代码的任何有益的一般建议当然都会受到赞赏。

解决方案

根本不需要使用< Enter> 。尝试:

 从tkinter导入画布
导入tkinter

_width = 50
_height = 50
_size = 8

root = tkinter.Tk()
root.title(画出一个可爱的矩阵)
canv = Canvas( root,width = _width * _size,height = _height * _size)
rects = []

#每次按住1号按钮移动鼠标时B1-Motion都会激活
#参见https://effbot.org/tkinterbook/tkinter-events-and-bindings.htm
#我们在按住按钮1的同时填充了鼠标所接触的每个项目
#标签被绑指向事件被调用的项目当前,指向按下按钮时指针下方的
#项,即第一个框。
#仅更改x和y属性,因此我们配置最接近的那些。
def运动(事件):
canv.itemconfig(canv.find_closest(event.x,event.y),fill =#aaa)
canv.bind(< B1 -Motion>,运动)

for i在范围(_size)中:
for j在范围(_size)中:
rects.append(canv.create_rectangle(_width * j ,_height * i,_width *(j + 1),_height *(i + 1),fill =#fff,width = 0))
#不需要将任何东西绑定到< Enter>

canv.pack()
root.mainloop()

很遗憾,使用< Enter> 没有解决方案。如果< Enter> 按照您希望的方式工作,则以下无效代码在理论上是正确的。

 导入tkinter 

_width = 50
_height = 50
_size = 8

根= tkinter.Tk ()
root.title(给我画一个可爱的矩阵)
canv = tkinter.Canvas(root,width = _width * _size,height = _height * _size)
rects = []

#这种类似javascript的方法在tkinter中不起作用,因为
#< Enter>和< Leave>按住任何鼠标按钮
#时都不会调用事件。
def fill(tag):
canv.itemconfig(tag,fill =#aaa)
def enter(event):
fill( current)
def mousedown(事件):
fill( current)
canv.tag_bind( all,< Enter>,输入,添加= +)
def mouseup (事件):
canv.tag_unbind( all,< Enter>)
canv.bind(< Button-1>,鼠标按下)
canv.bind( < ButtonRelease-1>,鼠标悬停)

for i在范围(_size):
for j在范围(_size):
rects.append(canv.create_rectangle (_width * j,_height * i,_width *(j + 1),_height *(i + 1),fill =#fff,width = 0))

canv.pack()
root.mainloop()

在python 3.8.2,tkinter 8.6中测试>

I want to fill rectangles just like in paint. When mouse button is pressed I want every rectangle I enter to be filled and otherwise I want no event to take place.

Here Is my code:

from tkinter import Canvas
import tkinter

_width = 50
_height = 50
_size = 8

root = tkinter.Tk()
root.title("draw me a lovely matrix")
canv = Canvas(root, width=_width * _size, height=_height * _size)


class Wrapper:
    btn1d = False


def set_btn1d(value):
    print(value)
    Wrapper.btn1d = value


def toggle_color(rect):
    print('called')
    if Wrapper.btn1d:
        color = canv.itemcget(rect, 'fill')
        canv.itemconfig(rect, fill=("#aaa" if color == '#fff' else '#fff'))


rects = []
canv.bind('<ButtonPress-1>', lambda e, value=True: set_btn1d(value))
canv.bind('<ButtonRelease-1>', lambda e, value=False: set_btn1d(value))
for i in range(_size):
    for j in range(_size):
        rect = canv.create_rectangle(_width * j, _height * i, _width * (j + 1), _height * (i + 1), fill="#fff", width=0)
        rects.append(rect)
        canv.tag_bind(rect, '<Enter>', lambda e, rect=rect: toggle_color(rect))

canv.pack()
root.mainloop()

The problem is that when I press the mouse button only the cell in which the mouse was pressed detects the entrance of mouse pointer(also the one in which mouse will be released at the end)

Any beneficial general advice about my code would be of course much appreciated.

解决方案

There's no need to use <Enter> at all. Try:

from tkinter import Canvas
import tkinter

_width = 50
_height = 50
_size = 8

root = tkinter.Tk()
root.title("draw me a lovely matrix")
canv = Canvas(root, width=_width * _size, height=_height * _size)
rects = []

# B1-Motion activates every time the mouse is moved with button 1 held down
# See https://effbot.org/tkinterbook/tkinter-events-and-bindings.htm
# We fill every item that the mouse comes in contact with while button 1 is held
# The tag tied to the item the event was called on, "current", points to the
#   item under the pointer when the button was pressed, i.e. the first box.
# Only the x and y properties change, so we configure the item closest to those.
def motion(event):
  canv.itemconfig(canv.find_closest(event.x, event.y), fill="#aaa")
canv.bind("<B1-Motion>", motion)

for i in range(_size):
  for j in range(_size):
    rects.append(canv.create_rectangle(_width * j, _height * i, _width * (j + 1), _height * (i + 1), fill="#fff", width=0))
    # don't need to bind anything to <Enter>

canv.pack()
root.mainloop()

Unfortunately, there's no possible solution using <Enter>. The following non-working code would theoretically be correct if <Enter> worked the way you wanted it to.

import tkinter

_width = 50
_height = 50
_size = 8

root = tkinter.Tk()
root.title("draw me a lovely matrix")
canv = tkinter.Canvas(root, width=_width * _size, height=_height * _size)
rects = []

# This javascript-like approach doesn't work in tkinter because
# <Enter> and <Leave> events aren't called while any mouse buttons
# are held.
def fill(tag):
  canv.itemconfig(tag, fill="#aaa")
def enter(event):
  fill("current")
def mousedown(event):
  fill("current")
  canv.tag_bind("all", "<Enter>", enter, add="+")
def mouseup(event):
  canv.tag_unbind("all", "<Enter>")
canv.bind("<Button-1>", mousedown)
canv.bind("<ButtonRelease-1>", mouseup)

for i in range(_size):
  for j in range(_size):
    rects.append(canv.create_rectangle(_width * j, _height * i, _width * (j + 1), _height * (i + 1), fill="#fff", width=0))

canv.pack()
root.mainloop()

Tested in python 3.8.2, tkinter 8.6

这篇关于如何使tkinter&lt; Enter&gt; &lt; button-1&gt;被按下?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆