Python tkinter colorchooser保存所选颜色并应用于方格绘图单元格的实现问题
方格绘图程序颜色选择功能修复方案
问题核心
- 现有
color()方法仅获取了颜色选择器的返回值,未将其赋值给Grilla类的类属性,选中的颜色没有被持久存储 Grilla类的colorCelda(填充色)、colorBorde(边框色)为全局类属性,所有单元格绘制时直接读取这两个属性的值,修改属性后后续新绘制的单元格会自动应用新颜色
修改逻辑
- 修正
color()方法的判断逻辑:排除用户点击颜色选择器「取消」的情况,避免空值报错 - 将选中的十六进制色值赋值给
Grilla对应的类属性,即可全局生效
核心修改代码
def color(self): color_result = colorchooser.askcolor() # 用户点击取消时返回(None, None),直接终止逻辑 if not color_result[1]: return selected_color = color_result[1] # 赋值给填充色类属性 Grilla.colorCelda = selected_color # 若需要同步修改单元格边框色,可取消下方注释 # Grilla.colorBorde = selected_color
修改完成后,选中颜色并确认后,后续点击绘制的单元格会自动使用选中的颜色填充
若需要同步更新画布上已绘制完成的填充单元格,可在上述方法末尾添加
self.draw()触发全画布重绘。
完整可运行代码
from tkinter import * from tkinter import colorchooser import tkinter as tk class Grilla: colorCelda = "black" colorDefault = "white" colorBorde = "black" bordeDefault = "black" def __init__(self, root, master, x, y, size): """ Constructor of the object called by Cell(...) """ self.master = master self.abs = x self.ord = y self.size = size self.fill = False def switch(self): """ Switch if the cell is filled or not. """ self.fill = not self.fill def reset(self): """ Clears the cell """ self.fill = False def draw(self): # dibujar en el canvas if self.master is not None: outline = Grilla.colorBorde fill = Grilla.colorCelda if not self.fill: outline = Grilla.bordeDefault fill = Grilla.colorDefault xmin = self.abs * self.size xmax = xmin + self.size ymin = self.ord * self.size ymax = ymin + self.size self.master.create_rectangle(xmin, ymin, xmax, ymax, fill=fill, outline=outline) class CellGrilla(Canvas): def __init__(self, master, numFil, numCol, tamGrid, *args, **kwargs): Canvas.__init__(self, master, width=tamGrid * numCol, height=tamGrid * numFil, *args, **kwargs) self.bind("<Button-1>", self.square_clicked) self.cellSize = tamGrid self.pen = "draw" self._grid = [] for row in range(numFil): line = [] for column in range(numCol): line.append(Grilla(master, self, column, row, tamGrid)) self._grid.append(line) # memorize the cells that have been modified to avoid many switching of state during mouse motion. self.switched = [] self.draw() def square_clicked(self, event): row, column = self._coordenadas(event) cell = self._grid[row][column] if self.pen == "draw": cell.switch() cell.draw() def draw(self): for row in self._grid: for cell in row: cell.draw() def _coordenadas(self, event): # `int(a / b)` is the same as `a // b` row = event.y // self.cellSize column = event.x // self.cellSize return row, column def switch_to_draw(self): self.pen = "draw" def color(self): color_result = colorchooser.askcolor() if not color_result[1]: return selected_color = color_result[1] Grilla.colorCelda = selected_color # 若需要修改边框色可取消下一行注释 # Grilla.colorBorde = selected_color # 若需要同步更新已绘制的单元格可取消下一行注释 # self.draw() def DDA(self): # DDA algorithm pass def clear(self): for row in self._grid: for cell in row: cell.reset() cell.draw() if __name__ == "__main__": app = Tk() # Tamaño de canvas x tamaño de pixeles grid = CellGrilla(app, 75, 75, 10) grid.grid(row=1, column=1, rowspan=4, sticky="news") colorBoton = Button(app, text="Elegir Color", command=grid.color, height=1, width=30) ddaBoton = Button(app, text="DDA", command=grid.DDA, height=1, width=30) zoomInBoton = Button(app, text="Zoom in", command=grid.switch_to_draw, height=1, width=30) zoomOutBoton = Button(app, text="Zoom out", command=grid.switch_to_draw, height=1, width=30) reset_btn = Button(app, text="Borrar", command=grid.clear, height=1, width=30) zoomInBoton.grid(row=1, column=2, sticky="news") zoomOutBoton.grid(row=2, column=2, sticky="news") colorBoton.grid(row=3, column=2, sticky="news") ddaBoton.grid(row=4, column=2, sticky="news") reset_btn.grid(row=5, column=2, sticky="news") app.mainloop()
内容的提问来源于stack exchange,提问作者Paola Vilaseca
相关产品推荐
相关产品推荐

