Menu

Problème très curieux avec askopenfilename()

Messages postés
6
Date d'inscription
samedi 29 décembre 2012
Dernière intervention
15 mars 2019
-
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.
Afficher la suite 

Votre réponse

1 réponse

0
Merci
Bonjour,

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és
6
Date d'inscription
samedi 29 décembre 2012
Dernière intervention
15 mars 2019
-
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.
Commenter la réponse de globi