解决方案:好的,我认为这是巨大的!!!!不仅因为我花了好几天的时间来解决它,还因为,嗯......
原始问题:我在单元格中的数独条目编号上单击鼠标似乎没有触发我的 mainCellClickedProc() 函数......除了他们触发它!只是 Tk(inter) 发送的是相对于 Label 小部件的坐标(0 到 23 之间),而不是画布对象(25 到 475 之间,我从中计算了我的数独游戏单元),因此 if 条件(右在我用来定位单元格的按钮事件的主要回调的顶部,它启动了我所有的“海鸥”游戏逻辑,不断失败。特别是 (x >= self.xr1c1 和 (y >= self. yr1c1) 条件,因为 self.xr1c1 和 self.tr1c1 都是 25,所以总是 False!现在,更重要的是这在 Ruby Tcl/Tk 版本的程序中没有发生,所以我什至没有看这个区域完全没有。只有在将程序缩减为 Hello, World-sized 单元后,我才偶然发现发生了什么。真是个大问题!毕竟它与绑定无关!!!
下面是代码。不幸的是,Hello, world!-size 仍然有将近 300 行!
另一件事是“旅程”,其中...
我上网并试图找到一些好的参考资料,让我对我的(咳嗽)“捆绑”(咳嗽)到底发生了什么感到困惑。我偶然发现了 Tcl/Tk 网站。我读到了为一个环境创建的 Tk 代码可以在所有平台上不加修改地运行的断言。我相信炒作。我进一步了解了该系统的背景和历史。维护人员谈论随着时间的推移积极发展。它们暗示随着时间的推移,事情会在幕后发生变化。他们没有说明这对十年前用一种语言(Ruby 1.8.2 w/ Tcl/Tk)编写并在今天运行在另一种语言(Python 2.7.8.10 w/ Tkinter 8.5)上的应用程序有何影响。
我确定我需要可靠的参考资料,而不是在 effbot.org 或什至 tkdocs.com 或 New Mexico Tech 网站上找到的粗略教程资料。并不是他们一定不好,而是他们在示例部门中都很弱。无论如何,我主要选择 Tkinter 8.5 参考:John Shipman 的 Python GUI,因为毕竟这是我要移植到的平台。但是,我仍然使用其他材料,包括 John Grayson 的 Python 和 Tkinter Programming 一书,以及其他一些材料。
日子过去了。在我 (*) 阅读、研究、探索和调试的那些日子里,除了解决方案之外,唯一的事情是我不确定我是在高效地学习还是只是在消磨时间。我离开时在脑海中思考“一点点无知是一件危险的事情!”
(*)“我”包括在这个过程中传递他宝贵知识的仁慈灵魂(是的,你知道你是谁......(咳)“布莱恩”(咳))(:>)
附:我可能会因为这种“诽谤”而受到责骂,但无论如何,这不会比我迄今为止所忍受的更痛苦。我只能说,对不起,主,原谅我!
解决方案代码(在所有相关位置都标有注释“# Binderooney-related Solution Stuff”...
#!/usr/bin/env python
from Tkinter import *
mouseClickNumber = 1
class LabelsAsEventFodderPOC (Frame):
""" Labels as Event Fodder for Proof of Concept class """
def __init__(self, cellSize, xr1c1, yr1c1, master=None):
#Frame.__init__(self, master)
self.cellSize = cellSize
self.xr1c1 = xr1c1
self.yr1c1 = yr1c1
self.button = 0
self.xcoord = 0
self.ycoord = 0
self.sillyNilly = 0
self.gridSize = cellSize * 3;
self.fillColor = 'steelblue'
self.highlightColor = 'steelblue3'
self.outlineColor = 'red'
self.lineColor = 'black'
self.cellLineWidth = 2
self.gridLineWidth = 5
self.rootFont = 'arial 20 bold'
self.timerLabelFont = 'arial 9 bold'
self.msgLabelFont = 'arial 11 bold'
self.buttonTextFont = 'arial 10 bold'
self.numberFont = 'arial 20 bold'
self.numberFontHeight = 23
self.numberFontWidth = 20
self.bgColor = self.fillColor
self.fgColor = self.lineColor
self.hlColor = self.highlightColor
self.olColor = self.outlineColor
self.gridRects = [None] * 9
self.gridL = [None] * 9
self.cell = self.sillyNilly
self.root = Tk()
self.root.option_add('*font', self.rootFont)
self.frame = Frame(self.root)
self.frame.pack(fill=BOTH, expand=True)
self.canvas = Canvas(
self.frame, borderwidth=0, # Set up Canvas
width=200, height=260, relief=GROOVE,
highlightthickness=0, background=self.fillColor)
self.canvas.pack(fill=BOTH, expand=True, padx=0, pady=0)
self.drawCells(cellSize, xr1c1, yr1c1)
self.drawGrid(cellSize, xr1c1, yr1c1)
self.numberLabels = [None] * 9 # Binderooney-related Solution Stuff ...
self.numberLabelsWindow = [None] * 9 # Binderooney-related Solution Stuff ...
self.numberLabelsCellCoords = [] * 9 # Binderooney-related Solution Stuff ...
self.labelID = self.sillyNilly # Binderooney-related Solution Stuff ...
for i in range (3): # Cell Rows # Binderooney-related Solution Stuff ...
xul = self.xr1c1 + (3 * self.cellSize) # Binderooney-related Solution Stuff ...
yul = self.yr1c1 + (i * self.cellSize) + (3 * self.cellSize) # Binderooney-related Solution Stuff ...
xlr = xul + self.cellSize # Binderooney-related Solution Stuff ...
ylr = yul + self.cellSize # Binderooney-related Solution Stuff ...
for j in range(3): # Cell Columns # Binderooney-related Solution Stuff ...
self.numberLabels[(i * 3) + j] = Label(self.numberLabelsWindow[(i * 3) + j]) # Binderooney-related Solution Stuff ...
xul += self.cellSize # Binderooney-related Solution Stuff ...
xlr += self.cellSize # Binderooney-related Solution Stuff ...
# Bind the mouse clicks to the numberLabels # Binderooney-related Solution Stuff ...
self.numberLabels[(i * 3) + j].bind("<Button>", \
lambda e, k=((i * 3) + j): self.binderooney(e.num, e.x, e.y, k), add='+') # !!!!! # Binderooney-related Solution Stuff ...
for i in range (3): # Cell Rows # Binderooney-related Solution Stuff ...
xul = xr1c1 # Binderooney-related Solution Stuff ...
yul = yr1c1 + (i * cellSize) # Binderooney-related Solution Stuff ...
xlr = xul + cellSize # Binderooney-related Solution Stuff ...
ylr = yul + cellSize # Binderooney-related Solution Stuff ...
for j in range(3): # Cell Columns # Binderooney-related Solution Stuff ...
print "In constructor, index is %r!!!!!!!!!!!!!!!!!!!" % ((i * 3) + j) # Binderooney-related Solution Stuff ...
self.numberLabelsCellCoords.append([xul, yul]) # Binderooney-related Solution Stuff ...
xul += cellSize # Binderooney-related Solution Stuff ...
xlr += cellSize # Binderooney-related Solution Stuff ...
print "In constructor, self.numberLabelsCellCoords is %r!!!!!!!!!!!!!!!!" % self.numberLabelsCellCoords # Binderooney-related Solution Stuff ...
self.setupGrid() # Binderooney-related Solution Stuff ...
# Capture the mouse click in the canvas
self.canvas.bind("<Button>", \
lambda e: self.mainCallbackFunction(e.num, e.x, e.y)) # !!!!!
def drawCells(self, cellSize, xr1c1, yr1c1):
""" Draw the grid's 3 by 3 cells """
for i in range (3): # Cell Rows # Binderooney-related Solution Stuff ...
xul = xr1c1
yul = yr1c1 + (i * cellSize)
xlr = xul + cellSize
ylr = yul + cellSize
for j in range(3): # Cell Columns # Binderooney-related Solution Stuff ...
self.gridRects[(i * 3) + j] = \
self.canvas.create_rectangle(\
xul, yul, xlr, ylr, fill=self.fillColor, \
outline=self.lineColor, width=self.cellLineWidth\
) # Binderooney-related Solution Stuff ...
xul += cellSize
xlr += cellSize
self.canvas.pack()
def drawGrid(self, cellSize, xr1c1, yr1c1):
""" Draw a 3 by 3 grid """
gridSize = cellSize * 3 # Grid size
for i in range (1): # Grid Rows # Binderooney-related Solution Stuff ...
xul = xr1c1
yul = yr1c1 + (i * gridSize)
xlr = xul + gridSize
ylr = yul + gridSize
for j in range(1): # Grid Columns # Binderooney-related Solution Stuff ...
self.gridL [(i * 1) + j] = self.canvas.create_rectangle( # Binderooney-related Solution Stuff ...
xul, yul, xlr, ylr,
outline=self.lineColor, width=self.gridLineWidth
)
xul += gridSize
xlr += gridSize
self.canvas.pack()
def setupGrid(self): # Binderooney-related Solution Stuff ...
""" setup the grid """
self.drawCells(self.cellSize, self.xr1c1, self.yr1c1)
self.drawGrid(self.cellSize, self.xr1c1, self.yr1c1)
# Toss in a quit button
pbx = 61
pby = 210
pbw = 75
pbh = 25
pbp = 10
self.quitBtn = Button(
self.frame,
text = 'Quit',
activebackground = self.hlColor,
font = self.buttonTextFont,
bg = self.fillColor,
command = lambda: quit()
)
self.quitBtn.place(
x=pbx,
y=pby,
width=pbw,
height=pbh
)
def cellOutline(self, x1, y1, x2, y2, color):
""" Display an outline around the cell that is clicked """
self.lastCell = self.canvas.create_rectangle(
x1, y1, x2, y2, outline=color, width=self.cellLineWidth
)
self.cellSelectedFlag = True
self.last_x1 = x1
self.last_y1 = y1
self.last_x2 = x2
self.last_y2 = y2
self.canvas.pack()
return self.lastCell
def cellHighlight(self, x1, y1, x2, y2, color):
""" Display an outline around the cell that is clicked """
self.lastCell = self.canvas.create_rectangle(
x1, y1, x2, y2, fill=color, width=self.cellLineWidth
)
self.cellSelectedFlag = True
self.last_x1 = x1
self.last_y1 = y1
self.last_x2 = x2
self.last_y2 = y2
self.canvas.pack()
return self.lastCell
def writeEntryNumber(self, num, x, y, fgCol, bgCol):
""" Write the cell's entry number """
entryNumText = " "
entryNumText = str(num)
self.numberLabels[self.calcCellFromXYCoords(x, y)].configure(
text= entryNumText,
font= self.numberFont,
foreground= fgCol,
background= bgCol
)
self.numberLabels[self.calcCellFromXYCoords(x, y)].place(
x=x + 15,
y=y + 15,
width=self.numberFontWidth,
height=self.numberFontHeight
)
def calcCellFromXYCoords(self, x, y):
""" Calculate the cell from the provided x and y coordinates """
row = ((y - self.yr1c1) / self.cellSize)
col = ((x - self.xr1c1) / self.cellSize)
self.cell = (((row ) * 3) + col) # Binderooney-related Solution Stuff ...
return self.cell
def tell_it(self, btn, x, y):
""" Display the mouse button clicked and its coordinates """
global mouseClickNumber
print "In tell_it(), mouse click number %d, button %d, coordinates (%d, %d)" % \
(mouseClickNumber, btn, x, y)
mouseClickNumber += 1
def binderooney(self, btn, x, y, labelIndex): # Binderooney-related Solution Stuff ...
""" Test-bed for the cell coordinates binding solution! """
print "In binderooney(), labelIndex is %r!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" % labelIndex # Binderooney-related Solution Stuff ...
cx = self.numberLabelsCellCoords[labelIndex] [0] # Binderooney-related Solution Stuff ...
cy = self.numberLabelsCellCoords[labelIndex] [1] # Binderooney-related Solution Stuff ...
self.tell_it(btn, cx, cy) # Binderooney-related Solution Stuff ...
if ((cx >= self.xr1c1) and (cx <= ((self.xr1c1 - 2) + (3 * self.cellSize))) and (cy >= self.yr1c1) and (cy <= ((self.yr1c1 - 2) + (3 * self.cellSize)))): # Binderooney-related Solution Stuff ...
self.button = btn # Binderooney-related Solution Stuff ...
self.xcoord = x # Binderooney-related Solution Stuff ...
self.ycoord - y # Binderooney-related Solution Stuff ...
self.drawCells(self.cellSize, self.xr1c1, self.yr1c1) # Binderooney-related Solution Stuff ...
x1 = ((((x + self.xr1c1) / self.cellSize) - 1) * self.cellSize) + self.xr1c1 # Binderooney-related Solution Stuff ...
y1 = ((((y + self.yr1c1) / self.cellSize) - 1) * self.cellSize) + self.yr1c1 # Binderooney-related Solution Stuff ...
x2 = x1 + self.cellSize # Binderooney-related Solution Stuff ...
y2 = y1 + self.cellSize # Binderooney-related Solution Stuff ...
self.rw = ((y + self.yr1c1) / self.cellSize) # Binderooney-related Solution Stuff ...
self.col = ((x + self.xr1c1) / self.cellSize) # Binderooney-related Solution Stuff ...
self.cel = (((self.rw ) * 3) + self.col) # Binderooney-related Solution Stuff ...
self.grw = ((y + self.yr1c1 + (2 * self.cellSize)) / self.gridSize) # Binderooney-related Solution Stuff ...
self.gcol = ((x + self.xr1c1 + (2 * self.cellSize)) / self.gridSize) # Binderooney-related Solution Stuff ...
self.grid = (((self.grw - 1) * 3) + self.gcol) # Binderooney-related Solution Stuff ...
if btn == 1: # Binderooney-related Solution Stuff ...
self.drawGrid(self.cellSize, self.xr1c1, self.yr1c1) # Binderooney-related Solution Stuff ...
self.cellOutline(cx, cy, cx+self.cellSize, cy+self.cellSize, self.outlineColor) # Binderooney-related Solution Stuff ...
if btn == 1: # Binderooney-related Solution Stuff ...
self.writeEntryNumber(1, cx, cy, self.fgColor, self.bgColor) # Binderooney-related Solution Stuff ...
elif btn == 3: # Binderooney-related Solution Stuff ...
self.cellHighlight(cx, cy, cx+self.cellSize, cy+self.cellSize, self.highlightColor) # Binderooney-related Solution Stuff ...
self.cellOutline(cx, cy, cx+self.cellSize, cy+self.cellSize, self.outlineColor) # Binderooney-related Solution Stuff ...
self.drawGrid(self.cellSize, self.xr1c1, self.yr1c1) # Binderooney-related Solution Stuff ...
self.cellOutline(cx, cy, cx+self.cellSize, cy+self.cellSize, self.outlineColor) # Binderooney-related Solution Stuff ...
return self.cell # Binderooney-related Solution Stuff ...
def mainCallbackFunction(self, btn, x, y):
"""
# On left mouse click, return cell in which it was clicked, drawing a
# red boundary around the cell; on right click, return the cell in which
# it was clicked, removing the red boundary around the clicked cell
"""
if ((x >= self.xr1c1) and (x <= ((self.xr1c1 - 2) + (3 * self.cellSize)))) and \
(y >= (self.yr1c1) and (y <= ((self.yr1c1 - 2) + (3 * self.cellSize)))): # Binderooney-related Solution Stuff ...
print "in mainCallbackFunction(), cell is %r" % (self.calcCellFromXYCoords(x, y)) # Binderooney-related Solution Stuff ...
self.tell_it(btn, x, y)
self.button = btn
self.xcoord = x
self.ycoord - y
self.drawCells(self.cellSize, self.xr1c1, self.yr1c1)
x1 = ((((x + self.xr1c1) / self.cellSize) - 1) * self.cellSize) + self.xr1c1
y1 = ((((y + self.yr1c1) / self.cellSize) - 1) * self.cellSize) + self.yr1c1
x2 = x1 + self.cellSize
y2 = y1 + self.cellSize
self.rw = ((y + self.yr1c1) / self.cellSize)
self.col = ((x + self.xr1c1) / self.cellSize)
self.cel = (((self.rw ) * 3) + self.col) # Binderooney-related Solution Stuff ...
self.grw = ((y + self.yr1c1 + (2 * self.cellSize)) / self.gridSize)
self.gcol = ((x + self.xr1c1 + (2 * self.cellSize)) / self.gridSize)
self.grid = (((self.grw - 1) * 3) + self.gcol) # Binderooney-related Solution Stuff ...
if btn == 1:
self.drawGrid(self.cellSize, self.xr1c1, self.yr1c1)
self.cellOutline(x1, y1, x2, y2, self.outlineColor)
if btn == 1:
self.writeEntryNumber(1, x1, y1, self.fgColor, self.bgColor)
elif btn == 3:
self.cellHighlight(x1, y1, x2, y2, self.highlightColor)
self.cellOutline(x1, y1, x2, y2, self.outlineColor)
self.drawGrid(self.cellSize, self.xr1c1, self.yr1c1)
self.cellOutline(x1, y1, x2, y2, self.outlineColor)
return self.cell
# Cell and Grid sizes, X amd Y Coordinates of Row 1 Col 1 (Upper Left Position)
cellSize = 50; xr1c1 = 25; yr1c1 = 25
# Instantiate the Label POC class
lPOC = LabelsAsEventFodderPOC(cellSize, xr1c1, yr1c1) # Binderooney-related Solution Stuff ...
# Loop-Dee-Doo
if __name__ == '__main__':
lPOC.root.mainloop()