Как я могу изменить глобальную переменную при использовании обработчика событий - PullRequest
0 голосов
/ 06 ноября 2019

Я очень плохо знаком с Python, у меня есть некоторый опыт работы с C ++ с подросткового возраста, поэтому, пожалуйста, будьте осторожны.

Что я пытаюсь сделать - щелчок левой кнопкой мыши добавляет точку (к двумерному массиву)и увеличивает переменную pointsCount. Я использую привязку Tkinter следующим образом:

canvas.bind("<Button-1>", lambda event: leftClick(event,pointsCounter,points))

функция левого щелчка определяется следующим образом:

def leftClick(event, numberOfPoints,pointsTable):
print("Left ", event.x ," ", event.y)
x = roundup(event.x, 50)
y = roundup(event.y, 50)
pointsTable.append([x,y])
numberOfPoints = numberOfPoints + 1
print(pointsTable)
print(numberOfPoints)

Хотя добавление точек работает нормально, числоOofPoints увеличивается только послепервый клик. Я понимаю, что Python только передает значение в функцию, поэтому я не могу его изменить. Однако это работает для массива. Можно ли как-нибудь увеличить число очков после щелчка правой кнопкой мыши?

Вот весь код

import array
import math
from tkinter import Canvas


def roundup(x, n=10):
    res = math.ceil(x/n)*n
    if (x%n < n/2)and (x%n>0):
        res-=n
    return res

def middleClick(event):
    print("Middle ", event.x ," ", event.y)

def rightClick(event):
    print("Right ", event.x ," ", event.y)
def leftClick(event, numberOfPoints,pointsTable):
    print("Left ", event.x ," ", event.y)
    x = roundup(event.x, 50)
    y = roundup(event.y, 50)
    pointsTable.append([x,y])
    numberOfPoints = numberOfPoints + 1
    print(pointsTable)
    print(numberOfPoints)
    for i in range(1, 5):
        canvas.create_oval(pointsTable[i][0] - radius, pointsTable[i][1] - radius, pointsTable[i][0] + radius, pointsTable[i][1] + radius, fill="red")
    return numberOfPoints

root = Tk()
canvas = Canvas(root, width = 800, height = 800)

radius = 5
points = [[]]
pointsCounter = 1



canvas.bind("<Button-1>", lambda event: leftClick(event,pointsCounter,points))
canvas.bind("<Button-2>",middleClick)
canvas.bind("<Button-3>",rightClick)





canvas.pack()


root.mainloop()```


I'd be really grateful for some pointers. 


1 Ответ

0 голосов
/ 06 ноября 2019

Разница между pointsCount и pointsTable в качестве параметров функции заключается в том, что pointsCount является неизменным, переменная присваивается новому объекту после его изменения. pointsTable является изменяемым, сам объект изменяется при его изменении. То есть, когда pointsTable изменяется в функции, изменение отражается в исходной переменной. Для pointsCount создается новый объект со значением pointsCount + 1, и pointCount внутри функция теперь указывает на него. pointsCount вне функции по-прежнему указывает на нулевой объект.

Одно из решений - сделать pointsCount глобальной переменной, щелкнув левой кнопкой мыши ниже. Другой способ - не хранить pointsCount вообще, а полагаться на длину pointsTable, оставленную leftClick1 ниже.

from random import randint

pointsTable = []
numberOfPoints = 0

class Event:  # Mock up to test code.
    def __init__(self):
        self.x = randint(0,50)
        self.y = randint(0,50)

# Keeping external counter
def leftClick(event, pointsTable):
    global numberOfPoints
    print("Left ", event.x ," ", event.y)
    x = event.x
    y = event.y
    pointsTable.append([x,y])
    numberOfPoints = numberOfPoints + 1
    print(pointsTable)
    print(numberOfPoints)

def number_of_points(): 
# This may be overkill len(pointsTable) could be used instead
    return len(pointsTable)

# Using len(pointsTable)
def leftClick1(event, pointsTable):
    print("Left ", event.x ," ", event.y)
    x = event.x
    y = event.y
    pointsTable.append([x,y])
    print(pointsTable)
    print(number_of_points())

for _ in range(2):
    leftClick( Event(), pointsTable )

for _ in range(2):
    leftClick1( Event(), pointsTable )

""" Output 
Left  5   4
[[5, 4]]
1
Left  49   6
[[5, 4], [49, 6]]
2
Left  44   20
[[5, 4], [49, 6], [44, 20]]
3
Left  6   30
[[5, 4], [49, 6], [44, 20], [6, 30]]
4
"""

Я бы предпочел полагаться на длину pointsTable как на более простую и надежную

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...