Phidippides
Messages postés13Date d'inscriptionsamedi 29 décembre 2012StatutMembreDernière intervention19 mars 2021
-
Modifié le 12 mars 2019 à 19:07
Phidippides
Messages postés13Date d'inscriptionsamedi 29 décembre 2012StatutMembreDernière intervention19 mars 2021
-
15 mars 2019 à 11:08
Bonjour
Après bien des vicissitudes, je suis arrivé à écrire une première version d'un programme de Sudoku qui marche bien sur Linux (Ubuntu). Je me suis dit que l'audience serait certainement plus grande sous Windows, donc je me suis attelé à un exécutable qui tourne sur ce dernier.
Là, je suis tombé sur un problème qui me parait très curieux et que je n'arrive pas à résoudre.
En bref, j'ai dans mon programme une grille de Sudoku dans laquelle je peux rentrer des chiffres mais si avant d'arriver à la commande mainloop(), j'insère une ligne de code qui fait appel à askopenfilename(), je n'arrive plus à rentrer quoi que ce soit dans ma grille (le clavier ne répond plus).
Je vous donne ci-dessous, un programme de test que vous pourrez essayer avec et sans la commande askopenfilename().
import tkinter as tk
from tkinter.font import Font
from collections import namedtuple
from tkinter.filedialog import *
RC = namedtuple('RC', 'rows columns')
BBox = namedtuple('BBox', 'x y width height')
class Cell:
_iid = None
_square_cfg = dict(fill='white', width=1, outline='white',
activeoutline='red', activewidth=3, tag='cell')
@property
def iid(self):
return self._square
def __init__(self, canvas, rc, coords, text_color='black'):
self.canvas = canvas
self.rc = rc
self.coords = coords
self.center = (coords[0] + coords[2]) // 2, (coords[1] + coords[3]) // 2
self._square = canvas.create_rectangle( coords, self._square_cfg)
self._label = canvas.create_text(self.center, fill=text_color, text='', font=canvas.font, tag='cell')
self.value = 0
canvas._items[self._label] = canvas._items[self._square] = self
def set_value(self, value):
itemconfig = self.canvas.itemconfigure
s = str(value) if value else ''
itemconfig(self._label, text=s)
self.value = value
class Grid(tk.Canvas):
_cfg = None
cellsize = None
font = None
RC = None
SPACING = None
font_config = None
def __init__(self, parent=None):
self._cfg['width'] = self.RC[0] * (self.cellsize + self.SPACING)
self._cfg['height'] = self.RC[1] * (self.cellsize + self.SPACING)
super().__init__(parent, self._cfg)
self.font = Font(**self.font_config)
self._items = {} # maps items(rectangle, text, window) to cell
self._cells = {} # maps (r, c) to cell
for r in range(self.RC.rows):
y0 = r * (self.cellsize + self.SPACING)
y1 = y0 + self.cellsize
for c in range(self.RC.columns):
x0 = c * (self.cellsize + self.SPACING)
x1 = x0 + self.cellsize
rc = (r+1, c+1)
self._cells[rc] = self.create_cell(rc, (x0, y0, x1, y1))
def cell(self, r, c):
if (r, c) in self._cells:
return self._cells[(r, c)]
def iid_cell(self):
iid = self.find_withtag('current')
if iid: iid = iid[0]
if iid in self._items:
return self._items[iid]
else: return None
class SudokuGrid(Grid):
_cfg = dict(bd=0, highlightthickness=False, background='grey')
cellsize = 63
RC = RC(9, 9)
SPACING = 2
font_config = dict(family='Helvetica', size=(cellsize // 3))
def __init__(self, parent):
self.create_cell = lambda rc, coords: Cell(self, rc, coords)
super().__init__(parent)
self.bind('<KeyPress>', self.on_keyPress)
def on_keyPress(self, event):
cell = self.iid_cell()
if cell is None: return
if event.char in '123456789':
value = int(event.char)
cell.set_value(value)
if __name__ == '__main__':
app = tk.Tk()
app.resizable(False, False)
app.tk_focusFollowsMouse()
grid = SudokuGrid(app)
grid.pack(fill='both')
fich = askopenfilename()
app.mainloop()
Merci d'avance à tous ceux qui peuvent me dépanner.
Les fenêtres de tkinter.filedialog sont modales, c'est à dire qu'il n'est plus possible d'intéragir avec la fenêtre parent tant que les actions requises de la fenêtre modale askopenfilename n'ont pas été finalisées.
Phidippides
Messages postés13Date d'inscriptionsamedi 29 décembre 2012StatutMembreDernière intervention19 mars 2021 15 mars 2019 à 11:08
Merci globi mais je me suis mal fait comprendre.
En fait, mon problème se passe après que j'aie donné un nom de fichier et que je sois sorti de askopenfilename(). En cherchant, j'ai quand même trouvé une solution mais qui ne me satisfait qu'à moitié, c'est de faire après le askopenfilename() un app.focus_force() pour faire en sorte que l'application app (le Sudoku) reprenne la main.
15 mars 2019 à 11:08
En fait, mon problème se passe après que j'aie donné un nom de fichier et que je sois sorti de askopenfilename(). En cherchant, j'ai quand même trouvé une solution mais qui ne me satisfait qu'à moitié, c'est de faire après le askopenfilename() un app.focus_force() pour faire en sorte que l'application app (le Sudoku) reprenne la main.