Précédent   Forum du club des développeurs et IT Pro > Autres langages > Python & Zope > GUI > PySide et PyQt
PySide et PyQt Forum d'entraide sur PySide et PyQt
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 22/11/2012, 00h26   #1
rambc
Membre Expert
 
Inscription : décembre 2006
Messages : 2 197
Détails du profil
Informations forums :
Inscription : décembre 2006
Messages : 2 197
Points : 1 221
Points : 1 221
Par défaut Coquille vide pour un sudoku

Bonsoir,
non, non je ne me lance pas dans un concours d'haïku.

Est-ce que quelqu'un a dans ses codes une coquille vide pour afficher
une grille de type Sudoku ? Pour la résolution, pas de souci j'ai un code.

Dans le cas contraire, j'essaierais de trouver un peu de temps pour le
faire mais c'est un peu compliqué côté temps pour moi en ce moment.
rambc est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/11/2012, 08h18   #2
tyrtamos
Expert Confirmé
 
Avatar de tyrtamos
 
Inscription : décembre 2007
Messages : 1 777
Détails du profil
Informations personnelles :
Localisation : France

Informations forums :
Inscription : décembre 2007
Messages : 1 777
Points : 3 049
Points : 3 049
Bonjour rambc,

Sur le web, j'ai au moins trouvé ça: http://lionel.textmalaysia.com/sudok...l#.UK3Dm9fQvwM.

Si ça ne te convient pas et si tu n'as pas d'autres réponses, je te proposerais un échange: je te fabrique ta coquille, et tu me passes tes codes de résolution. La coquille, en PyQt4, ne devrait pas être très compliquée en utilisant QTableWidget, et la structure de données sous forme de liste de listes du genre matrice devrait permettre la recherche récursive dans un arbre.

Il y a une dizaine d'années, je m'étais amusé à coder les algorithmes de résolution en... Lisp (="Lots of Insipid and Stupid Parentheses" ), y compris dans les cas complexes nécessitant des retours en arrière sur des tentatives infructueuses. C'était très amusant à faire, et ça marchait très bien (en console). C'est également intéressant de savoir fabriquer des grilles de sudoku à résoudre selon différents niveaux de complexité.
__________________
Ne rien ranger permet d'observer la loi universelle d'entropie: l'inévitable convergence vers le chaos...
Mes recettes python: http://www.jpvweb.com
tyrtamos est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/11/2012, 21h41   #3
rambc
Membre Expert
 
Inscription : décembre 2006
Messages : 2 197
Détails du profil
Informations forums :
Inscription : décembre 2006
Messages : 2 197
Points : 1 221
Points : 1 221
Merci pour le lien.

Côté résolution, rien de bien original. J'ai des idées pour la création de
grilles. C'est dans le cadre d'une formation dans l'Éducation Nationale.

Je mettrais le code final en ligne en Mars normalement (trop peu de
temps libre cette année). Si d'ici là je ne t'ai pas contacté, relances-moi.

Citation:
Envoyé par tyrtamos Voir le message
Lisp ="Lots of Insipid and Stupid Parentheses"
J'aime beaucoup !
rambc est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/02/2013, 13h46   #4
rambc
Membre Expert
 
Inscription : décembre 2006
Messages : 2 197
Détails du profil
Informations forums :
Inscription : décembre 2006
Messages : 2 197
Points : 1 221
Points : 1 221
Comment pourrait-on faire pour obtenir les fonctionnalités suivantes visibles dans cette page et cette autre ?
  1. Chaque case non renseignée se remplira par un simple clic dessus puis une saisie au clavier.
  2. Chaque case non renseignée pourra, ou non, afficher des possibilités (toutes ou justes certaines).
  3. Chacune des possibilités affichées dans une case pourra avoir une petite mise en forme spécifique : encadrement et couleur de fond.
  4. J'aimerais dessiner des cercles et des traits par dessus la grille pour aider le joueur ou indiquer une résolution pas à pas.
Mes questions sont de pures questions de mise en forme car j'ai presque fini mon "solveur" à quelques détails près.

PS : le lien donné ci-dessus semble mort...
rambc est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/02/2013, 19h55   #5
tyrtamos
Expert Confirmé
 
Avatar de tyrtamos
 
Inscription : décembre 2007
Messages : 1 777
Détails du profil
Informations personnelles :
Localisation : France

Informations forums :
Inscription : décembre 2007
Messages : 1 777
Points : 3 049
Points : 3 049
Bonjour rambc,

Je n'ai pas le temps pour l'instant de te terminer la coquille, je suis assez pris jusqu'à 1/2 mars.

Cependant, je peux te confirmer que tout ce que tu souhaites est parfaitement réalisable. Voilà quelques éléments de principe:

Grille utilisée: QTableWidget.

Petit code de base pour créer la grille 9x9:

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#!/usr/bin/python
# -*- coding: utf-8 -*-
from __future__ import division
# Python 2.7
 
import sys
from copy import deepcopy
from PyQt4 import QtCore, QtGui
 
#############################################################################
class Fenetre(QtGui.QWidget):
 
    # =======================================================================
    def __init__(self, parent=None):
        super(Fenetre, self).__init__(parent)
 
        # crée la grille 9x9
        self.table = QtGui.QTableWidget(self)
        self.nbrow, self.nbcol = 9, 9
        self.table.setRowCount(self.nbrow)
        self.table.setColumnCount(self.nbcol)
 
        # cache les entêtes horizontale et verticale
        self.table.horizontalHeader().hide()
        self.table.verticalHeader().hide()
 
        # définit les cases carrées 50 pixels x 50 pixels
        for row in xrange(0, self.nbrow):
            self.table.setRowHeight(row, 50)
            for col in xrange(0, self.nbcol):
                self.table.setColumnWidth(col, 50)
 
        # remplit la grille avec des QTableWidgetItem
        for row in xrange(0, self.nbrow):
            for col in xrange(0, self.nbcol):
                item = QtGui.QTableWidgetItem()
                item.setTextAlignment(QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter)
                self.table.setItem(row, col, item)
 
        # définit la police de caractère par défaut de la table 
        font = QtGui.QFont()
        font.setFamily(u"DejaVu Sans")
        font.setPointSize(16)
        self.table.setFont(font)
 
        # taille de la fenêtre
        self.resize(53*9, 53*9)
 
        # positionne la table dans la fenêtre
        posit = QtGui.QGridLayout()
        posit.addWidget(self.table, 0, 0)
        self.setLayout(posit)
 
        # grille de base
        self.g0 =  [[0,0,0,0,2,0,9,0,1],
                    [0,0,0,0,0,0,0,0,3],
                    [0,8,0,3,0,0,4,5,0],
                    [0,4,7,0,0,5,0,8,0],
                    [0,0,0,0,0,0,0,0,0],
                    [0,2,0,9,0,0,7,4,0],
                    [0,9,5,0,0,2,0,3,0],
                    [6,0,0,0,0,8,0,0,0],
                    [7,0,4,0,6,0,0,0,0]]
 
        # intégre le delegate pour lignes en gras et les cases en couleur
        #self.delegate = MonDelegate(self.table)
        #self.table.setItemDelegate(self.delegate)
 
        # redessine les lignes en gras et les cases de couleur
        #self.delegate.grilleinit(self.g0)
 
        # initialise la grille courante
        self.g = deepcopy(self.g0)
 
        # affiche la grille courante
        self.affiche(self.g)
 
        # place le focus
        self.table.setFocus()
        self.table.setCurrentCell(0, 0)
 
    # =======================================================================
    def affiche(self, g):
 
        for row in xrange(0, len(g[0])):
            for col in xrange(0, len(g)):
                if g[row][col]==0:
                    self.table.item(row, col).setText(u"")
                    self.table.item(row, col).setFlags(QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEditable)
                else:
                    self.table.item(row, col).setText(unicode(g[row][col]))
                    self.table.item(row, col).setFlags(QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable)
 
        couleur = QtGui.QColor(160, 255, 160, 255) # vert clair
        self.table.item(2, 4).setBackgroundColor(couleur)
 
        couleur = QtGui.QColor(255, 160, 160, 255) # rouge clair
        self.table.item(6, 3).setBackgroundColor(couleur)
 
#############################################################################
if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    fen = Fenetre()
    fen.show()
    sys.exit(app.exec_())
Cela donne déjà une grille complète, mais il reste à dessiner les lignes en gras pour séparer visuellement les groupes de cases 3x3. On peut aussi mettre les cases de départ ayant des chiffres en couleur (ici, en gris).

Pour faire ça, je n'ai pas trouvé plus simple que de sous-classer QItemDelegate, et de surcharger sa méthode paint. Voilà comment on peut faire ça:

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#############################################################################
def couleurcase(painter, option, couleur):
    """met le fond de la case dans la couleur demandée"""
    r = option.rect
    x, y, w, h = r.x()+1, r.y()+1, r.width()-2, r.height()-2
    if isinstance(couleur, (str, unicode)):
        coul = QtGui.QColor(couleur)
    elif isinstance(couleur, (list, tuple)):
        if len(couleur) == 3:
            r, g, b = couleur
            t = 255
        else:
            r, g, b, t = couleur
        coul = QtGui.QColor(r, g, b, t)
    painter.fillRect(x, y, w, h, coul)
 
#############################################################################
def bordurecase(painter, option, ligne):
    """met en gras la bordure d'une case d'un QTableWidget dans le paint d'un 
       delegate: ligne 'h'=haute, 'g'=gauche, 'd'=droite, 'b'=basse
    """
    r = option.rect
    x, y, w, h = r.x(), r.y(), r.width(), r.height()
    if ligne=='h':
        x1, y1, x2, y2 = x, y, x+w, y
    elif ligne=='d':
        x1, y1, x2, y2 = x+w, y, x+w, y+h
    elif ligne=='b':
        x1, y1, x2, y2 = x+w, y+h, x, y+h
    elif ligne=='g':
        x1, y1, x2, y2 = x, y+h, x, y
    else:
        return
    pen = QtGui.QPen()
    pen.setWidth(2)
    painter.setPen(pen)
    painter.drawLine(x1, y1, x2, y2)
 
#############################################################################
class MonDelegate(QtGui.QItemDelegate):
 
    #========================================================================
    def __init__(self, parent=None):
        super(MonDelegate, self).__init__(parent)
 
    #========================================================================
    def grilleinit(self, g):
        self.g0 = g
 
    #========================================================================
    def paint(self, painter, option, index):    
        """appelé case par case pour en dessiner le contenu"""        
 
 
        row, col = index.row(), index.column() 
        if row==0 or row==3 or row==6:
            if col in[0,3,6]:
                bordurecase(painter, option, 'g')
                bordurecase(painter, option, 'h')
            elif col==8:
                bordurecase(painter, option, 'd')
                bordurecase(painter, option, 'h')
            else:
                bordurecase(painter, option, 'h')
        elif row in [1,2,4,5,7]:
            if col in [0,3,6]:
                bordurecase(painter, option, 'g')
            elif col==8:
                bordurecase(painter, option, 'd')
        elif row==8:
            if col in[0,3,6]:
                bordurecase(painter, option, 'g')
                bordurecase(painter, option, 'b')
            elif col==8:
                bordurecase(painter, option, 'd')
                bordurecase(painter, option, 'b')
            else:
                bordurecase(painter, option, 'b')    
 
        # mettre la couleur souhaitée dans les cases de départ ayant un numéro 
        if self.g0[row][col]!=0:
            couleurcase(painter, option, [200,200,200])
 
        QtGui.QItemDelegate.paint(self, painter, option, index)
Et dans la classe Fenetre, on fait à l'initialisation (les lignes y sont déjà, il suffit de les dé-commenter):

Code :
1
2
3
4
5
6
        # intégre le delegate pour lignes en gras et les cases en couleur
        self.delegate = MonDelegate(self.table)
        self.table.setItemDelegate(self.delegate)
 
        # redessine les lignes en gras et les cases de couleur
        self.delegate.grilleinit(self.g0)
Et voilà ce que ça donne:



Les cases grises qui ont un chiffre au départ sont sélectionnables, mais en lecture seule.

La case bleue est la case qui a le focus.

J'ai mis à titre d'exemple des cases roses et vertes pour remplacer les dessins fournis (rond vert et croix rouge) parce que c'est plus simple à programmer. Si ça ne va pas, on peut trouver autre chose.

Pour le reste:

Il est possible de mettre dans une case en tout petit les chiffres permis, il suffit de placer à la volée un QTextEdit au lieu du QTableWidgetItem, et d'écrite en "richtext", c'est à dire en html (syntaxe réduite cependant). Ce ne sera peut-être pas facile à mettre au point, mais ça marchera. Et puisqu'il s'agit de html, on devrait pouvoir mettre une image en option.

Voilà le départ! Pour le reste, il faudra attendre un peu...

A+
__________________
Ne rien ranger permet d'observer la loi universelle d'entropie: l'inévitable convergence vers le chaos...
Mes recettes python: http://www.jpvweb.com
tyrtamos est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/02/2013, 23h53   #6
rambc
Membre Expert
 
Inscription : décembre 2006
Messages : 2 197
Détails du profil
Informations forums :
Inscription : décembre 2006
Messages : 2 197
Points : 1 221
Points : 1 221
Merci,
cela fait un bon départ. Je vais étudier cela. Va juste falloir que je me remette à PyQt.

Un grand merci.

PS : je posterais ici mes avancés, s'il y en a...
rambc est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/02/2013, 13h16   #7
wiztricks
Expert Confirmé Sénior
 
Inscription : juin 2008
Messages : 3 719
Détails du profil
Informations forums :
Inscription : juin 2008
Messages : 3 719
Points : 4 559
Points : 4 559
Salut,
Citation:
Envoyé par rambc Voir le message
cela fait un bon départ. Je vais étudier cela. Va juste falloir que je me remette à PyQt.
Vu le type de rendu montré à l'URL mentionnée, il semblerait plus judicieux de passer par des "canvas". Comme je ne vois pas trop l'intérêt d'utiliser Qt quand on a peu de temps, je me suis amusé à faire une "estimation"/"réalisation" de la chose avec Tk.
J'étais parti sur une estimation d'une poignée d'heures en plusieurs itérations.
C'était correct sur la partie réalisation du rendu proposé:

Avec la mise en place d'une API semblable:
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    app = tk.Tk()
    grid = SudokuGrid(app)
    grid.load(initial_values=G)
 
    grid.pack(fill='both')
    grid.update() # update grid to get real position from xxx_bbox
    grid.focus_set()
 
    grid.highlight_cell(2,8)
    grid.highlight_row(8)
    grid.highlight_column(5)
    grid.highlight_rectangle((4,1), (6,3))
    grid.circle_cell(5, 2)
    grid.cross_cell(8,1)
    grid.hint_cell( 1, 1, (3, 4, 6, 7))
Une fois le "joujou" réalisé, j'ai passé autant de temps à y intégrer ce "solveur".
Normal! Découvrir comment "adapter" les sorties avec l'interface et boucher des trous imprévus prend du temps.

Au cas où le code est en PJ.

- W
PS: Le code est assez brouillon, il faut le faire évoluer en fonction des cas d'utilisation à y intégrer. Difficile de savoir "à priori" ce qui doit être factorisé ou pas, les différents objets, leurs relations ne sont pas encore "stables".
Fichiers attachés
Type de fichier : py sudoku_grid.py (11,3 Ko, 14 affichages)
__________________
Architectures Post-Modernes
wiztricks est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 13/02/2013, 16h36   #8
rambc
Membre Expert
 
Inscription : décembre 2006
Messages : 2 197
Détails du profil
Informations forums :
Inscription : décembre 2006
Messages : 2 197
Points : 1 221
Points : 1 221
Je suis allergique à Tk. Pas propre du tout à utiliser. Je n'aime pas
du tout la logique de Tk. Qt a une certaine cohérence de mon point de vue.

De plus, j'ai envie de le faire comme un grand mais étant pressé je suis venu
ici cherché de l'aide pour les points techniques, pour gagner du temps.

J'ai regardé, le rendu est pas mal.
rambc est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/02/2013, 17h28   #9
wiztricks
Expert Confirmé Sénior
 
Inscription : juin 2008
Messages : 3 719
Détails du profil
Informations forums :
Inscription : juin 2008
Messages : 3 719
Points : 4 559
Points : 4 559
Salut,

Citation:
Envoyé par rambc Voir le message
Je suis allergique à Tk. Pas propre du tout à utiliser. Je n'aime pas du tout la logique de Tk. Qt a une certaine cohérence de mon point de vue.
Il est fort dommage que la flexibilité de Tk vous donne des boutons.
J'aime bien Qt aussi mais c'est un peu compliqué à mettre en œuvre.
On se retrouve à programmer en Python avec un background C++ pour comprendre les pièges et les astuces.

Citation:
De plus, j'ai envie de le faire comme un grand mais étant pressé je suis venu ici cherché de l'aide pour les points techniques, pour gagner du temps.

J'ai regardé, le rendu est pas mal.
L'API que vous avez donné était suffisamment claire pour être réalisée rapidement: un Canvas et quelques méthodes pour le décorer. Le canvas sous Qt est construit avec QGraphicsScene, une ou des QGraphicsView et des QGraphicsItems. C'est la même chose, seul l'emballage change.

- W
__________________
Architectures Post-Modernes
wiztricks est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/02/2013, 17h31   #10
rambc
Membre Expert
 
Inscription : décembre 2006
Messages : 2 197
Détails du profil
Informations forums :
Inscription : décembre 2006
Messages : 2 197
Points : 1 221
Points : 1 221
Côté solveur, je pense bientôt mettre mon code en ligne (au plus tard le 14 mars). Il faut que je finalise des trucs.

Bonne nouvelle : le code est assez structuré et scindé pour appréhender au mieux ce que j'ai fait, enfin je l'espère...
rambc est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/03/2013, 19h08   #11
rambc
Membre Expert
 
Inscription : décembre 2006
Messages : 2 197
Détails du profil
Informations forums :
Inscription : décembre 2006
Messages : 2 197
Points : 1 221
Points : 1 221
Salut wiztricks tyrtamos.

Je suis en train de compléter un peu ton code. J'arrive à ce qui suit. J'utilise PySide car il s'installe très facilement sous Mac.

Deux soucis.
  1. Les lignes épaisses pour visualiser les carrés sont tracées en dessous des cases. Peut-on utiliser l'équivalent d'un z-index pour pallier à cela ?
  2. J'aimerais garder la dimension de la fenêtre tout en centrant le tableau. Il me semble qu'il faut faire appel à des ressorts. Je ne connais plus le terme exact.

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
#! /usr/bin/env python2.7
# -*- coding: utf-8 -*-
 
from __future__ import division
 
import sys
from copy import deepcopy
 
from PySide import QtCore, QtGui
 
def cellColor(painter, option, color):
    """met le fond de la case dans la color demandée"""
    r = option.rect
    x, y, w, h = r.x()+1, r.y()+1, r.width()-2, r.height()-2
    if isinstance(color, (str, unicode)):
        coul = QtGui.QColor(color)
    elif isinstance(color, (list, tuple)):
        if len(color) == 3:
            r, g, b = color
            t = 255
        else:
            r, g, b, t = color
        coul = QtGui.QColor(r, g, b, t)
    painter.fillRect(x, y, w, h, coul)
 
def bordurecase(painter, option, ligne):
    """met en gras la bordure d'une case d'un QTableWidget dans le paint d'un
       delegate: ligne 'h'=haute, 'g'=gauche, 'd'=droite, 'b'=basse
    """
    r = option.rect
    x, y, w, h = r.x(), r.y(), r.width(), r.height()
    if ligne=='h':
        x1, y1, x2, y2 = x, y, x+w, y
    elif ligne=='d':
        x1, y1, x2, y2 = x+w, y, x+w, y+h
    elif ligne=='b':
        x1, y1, x2, y2 = x+w, y+h, x, y+h
    elif ligne=='g':
        x1, y1, x2, y2 = x, y+h, x, y
    else:
        return
    pen = QtGui.QPen()
    pen.setWidth(4)
    painter.setPen(pen)
    painter.drawLine(x1, y1, x2, y2)
 
class MonDelegate(QtGui.QItemDelegate):
    def __init__(self, parent=None):
        super(MonDelegate, self).__init__(parent)
 
    def grilleinit(self, g):
        self.g0 = g
 
    def paint(self, painter, option, index):
        """appelé case par case pour en dessiner le contenu"""
        row, col = index.row(), index.column()
 
        if row==0 or row==3 or row==6:
            if col in[0,3,6]:
                bordurecase(painter, option, 'g')
                bordurecase(painter, option, 'h')
 
            elif col==8:
                bordurecase(painter, option, 'd')
                bordurecase(painter, option, 'h')
 
            else:
                bordurecase(painter, option, 'h')
 
        elif row in [1,2,4,5,7]:
            if col in [0,3,6]:
                bordurecase(painter, option, 'g')
 
            elif col==8:
                bordurecase(painter, option, 'd')
 
        elif row==8:
            if col in[0,3,6]:
                bordurecase(painter, option, 'g')
                bordurecase(painter, option, 'b')
 
            elif col==8:
                bordurecase(painter, option, 'd')
                bordurecase(painter, option, 'b')
 
            else:
                bordurecase(painter, option, 'b')
 
# mettre la color souhaitée dans les cases de départ ayant un numéro
        if self.g0[row][col]!=0:
            cellColor(painter, option, [200,200,200])
 
        QtGui.QItemDelegate.paint(self, painter, option, index)
 
class MainWindow(QtGui.QWidget):
    def __init__(
        self,
        parent = None
    ):
        super(MainWindow, self).__init__(parent)
 
# General grid
        self.table = QtGui.QTableWidget(self)
        self.nbrow, self.nbcol = 9, 9
        self.table.setRowCount(self.nbrow)
        self.table.setColumnCount(self.nbcol)
 
# Each cell has dimension 50 pixels x 50 pixels
        for row in range(0, self.nbrow):
            self.table.setRowHeight(row, 50)
 
            for col in range(0, self.nbcol):
                self.table.setColumnWidth(col, 50)
 
# Each cell contains one single QTableWidgetItem
        for row in range(0, self.nbrow):
            for col in range(0, self.nbcol):
                item = QtGui.QTableWidgetItem()
                item.setTextAlignment(
                    QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter
                )
 
                self.table.setItem(row, col, item)
 
# header formatting
        font = QtGui.QFont()
        font.setFamily(u"DejaVu Sans")
        font.setPointSize(12)
        self.table.horizontalHeader().setFont(font)
        self.table.verticalHeader().setFont(font)
 
# Font used
        font = QtGui.QFont()
        font.setFamily(u"DejaVu Sans")
        font.setPointSize(20)
        self.table.setFont(font)
 
# Global Size
        self.resize(60*9, 60*9 + 20)
 
# Layout of the table
        layout = QtGui.QGridLayout()
        layout.addWidget(self.table, 0, 0)
        self.setLayout(layout)
 
# Initial grid (to test)
        self.g0 =  [[0,0,0,0,2,0,9,0,1],
                    [0,0,0,0,0,0,0,0,3],
                    [0,8,0,3,0,0,4,5,0],
                    [0,4,7,0,0,5,0,8,0],
                    [0,0,0,0,0,0,0,0,0],
                    [0,2,0,9,0,0,7,4,0],
                    [0,9,5,0,0,2,0,3,0],
                    [6,0,0,0,0,8,0,0,0],
                    [7,0,4,0,6,0,0,0,0]]
 
        # intégre le delegate pour lignes en gras et les cases en color
        self.delegate = MonDelegate(self.table)
        self.table.setItemDelegate(self.delegate)
 
        # redessine les lignes en gras et les cases de color
        self.delegate.grilleinit(self.g0)
 
# Initialization of the actual grid
        self.g = deepcopy(self.g0)
 
# Display the grid.
        self.update(self.g)
 
# Set the focus in the first cell
        self.table.setFocus()
        self.table.setCurrentCell(0, 0)
 
    def update(self, g):
        for row in range(0, len(g[0])):
            for col in range(0, len(g)):
                if g[row][col]==0:
                    font = QtGui.QFont()
                    font.setFamily(u"DejaVu Sans")
                    font.setPointSize(12)
                    self.table.item(row, col).setFont(font)
 
                    color = QtGui.QColor(0, 0,  255, 255) # bleu
                    self.table.item(row, col).setForeground(color)
 
                    self.table.item(row, col).setText(
                        u"1 2 3\n4 5 6\n7 8 9"
                    )
                    self.table.item(
                        row, col
                    ).setFlags(
                        QtCore.Qt.ItemIsEnabled |
                        QtCore.Qt.ItemIsSelectable |
                        QtCore.Qt.ItemIsEditable
                    )
 
                else:
                    self.table.item(row, col).setText(unicode(g[row][col]))
                    self.table.item(
                        row, col
                    ).setFlags(
                        QtCore.Qt.ItemIsEnabled |
                        QtCore.Qt.ItemIsSelectable
                    )
 
        color = QtGui.QColor(160, 255, 160, 255) # vert clair
        self.table.item(2, 4).setBackground(color)
 
        color = QtGui.QColor(255, 160, 160, 255) # rouge clair
        self.table.item(6, 3).setBackground(color)
 
 
if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    fen = MainWindow()
    fen.show()
    sys.exit(app.exec_())
rambc est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/03/2013, 17h40   #12
tyrtamos
Expert Confirmé
 
Avatar de tyrtamos
 
Inscription : décembre 2007
Messages : 1 777
Détails du profil
Informations personnelles :
Localisation : France

Informations forums :
Inscription : décembre 2007
Messages : 1 777
Points : 3 049
Points : 3 049
Bonjour rambc,

Citation:
Envoyé par rambc Voir le message
Salut wiztricks.

Je suis en train de compléter un peu ton code.
Compte tenu du code que tu montres, tu voulais peut-être dire "Salut Tyrtamos"?
__________________
Ne rien ranger permet d'observer la loi universelle d'entropie: l'inévitable convergence vers le chaos...
Mes recettes python: http://www.jpvweb.com
tyrtamos est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/03/2013, 18h21   #13
rambc
Membre Expert
 
Inscription : décembre 2006
Messages : 2 197
Détails du profil
Informations forums :
Inscription : décembre 2006
Messages : 2 197
Points : 1 221
Points : 1 221
Oh le boulet que je fais !!! Je corrige le message de suite. J'ai confondu avec le code tkinter. J'espère que tu ne vas pas trop m'en vouloir.
rambc est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/03/2013, 18h53   #14
tyrtamos
Expert Confirmé
 
Avatar de tyrtamos
 
Inscription : décembre 2007
Messages : 1 777
Détails du profil
Informations personnelles :
Localisation : France

Informations forums :
Inscription : décembre 2007
Messages : 1 777
Points : 3 049
Points : 3 049
Citation:
Envoyé par rambc Voir le message
J'espère que tu ne vas pas trop m'en vouloir.
Mais non, ne t'inquiète pas, ça me fait plutôt rigoler.

Je regarde si je peux répondre à tes questions.
__________________
Ne rien ranger permet d'observer la loi universelle d'entropie: l'inévitable convergence vers le chaos...
Mes recettes python: http://www.jpvweb.com
tyrtamos est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/03/2013, 19h04   #15
rambc
Membre Expert
 
Inscription : décembre 2006
Messages : 2 197
Détails du profil
Informations forums :
Inscription : décembre 2006
Messages : 2 197
Points : 1 221
Points : 1 221
Cela fait un baille que je n'utilise plus PySide et du coup je pense que j'ai râté un truc important.

Attention ! Sous PySide, je dois utiliser setBackground et non setBackgroundColor.
rambc est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/03/2013, 20h34   #16
rambc
Membre Expert
 
Inscription : décembre 2006
Messages : 2 197
Détails du profil
Informations forums :
Inscription : décembre 2006
Messages : 2 197
Points : 1 221
Points : 1 221
La coquille se remplit. Le code ci-dessous gère en plus le déplacement et la saisie des valeurs là où c'est autorisé. Voici ce que j'aimerais ajouter dans un 1er temps.
  1. (rappel) Les lignes épaisses pour visualiser les carrés sont tracées en dessous des cases. Peut-on utiliser l'équivalent d'un z-index pour pallier à cela ?
  2. (rappel) J'aimerais garder la dimension de la fenêtre tout en centrant le tableau. Il me semble qu'il faut faire appel à des ressorts. Je ne connais plus le terme exact.
  3. (nouveau) J'aimerais faire apparaître une mini-table de 9 sur 9 au-dessus de la case qui a le focus. Pourquoi ? Ce serait pour permettre au joueur de réduire les possibilités dans une case. Concrètement, le joueur choisit une case et taper sur R par exemple et hop la mini-table apparait.
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
#! /usr/bin/env python2.7
# -*- coding: utf-8 -*-
 
# Source : http://www.developpez.net/forums/d1281788/autres-langages/python-zope/gui/pyside-pyqt/coquille-vide-sudoku/#post7181230
 
from __future__ import division
 
import sys
from copy import deepcopy
 
from PySide import QtCore, QtGui
 
 
def cellColor(painter, option, color):
    """
    ???
    """
    r = option.rect
    x, y, w, h = r.x() + 1, r.y() + 1, r.width()-2, r.height()-2
 
    if isinstance(color, (str, unicode)):
        color = QtGui.QColor(color)
 
    elif isinstance(color, (list, tuple)):
        if len(color) == 3:
            r, g, b = color
            alpha   = 255
 
        else:
            r, g, b, alpha = color
 
        color = QtGui.QColor(r, g, b, alpha)
 
    painter.fillRect(x, y, w, h, color)
 
def cellBorder(painter, option, where):
    """
    ???
    """
    r = option.rect
    x, y, w, h = r.x(), r.y(), r.width(), r.height()
 
    if where == 'up':
        x1, y1, x2, y2 = x, y, x + w, y
 
    elif where == 'bottom':
        x1, y1, x2, y2 = x + w, y + h, x, y + h
 
    elif where == 'right':
        x1, y1, x2, y2 = x + w, y, x + w, y + h
 
    elif where == 'left':
        x1, y1, x2, y2 = x, y + h, x, y
 
    else:
        return None
 
    pen = QtGui.QPen()
    pen.setWidth(4)
    painter.setPen(pen)
    painter.drawLine(x1, y1, x2, y2)
 
 
class SudokuDelegate(QtGui.QItemDelegate):
    def __init__(self, parent=None):
        super(SudokuDelegate, self).__init__(parent)
 
    def initGrid(self, grid):
        self.grid_0 = grid
 
    def paint(self, painter, option, index):
        """
        ???
        """
        row, col = index.row(), index.column()
 
        if row == 0 or row == 3 or row == 6:
            if col in[0,3,6]:
                cellBorder(painter, option, 'left')
                cellBorder(painter, option, 'up')
 
            elif col == 8:
                cellBorder(painter, option, 'right')
                cellBorder(painter, option, 'up')
 
            else:
                cellBorder(painter, option, 'up')
 
        elif row in [1,2,4,5,7]:
            if col in [0,3,6]:
                cellBorder(painter, option, 'left')
 
            elif col == 8:
                cellBorder(painter, option, 'right')
 
        elif row == 8:
            if col in[0,3,6]:
                cellBorder(painter, option, 'left')
                cellBorder(painter, option, 'bottom')
 
            elif col == 8:
                cellBorder(painter, option, 'right')
                cellBorder(painter, option, 'bottom')
 
            else:
                cellBorder(painter, option, 'bottom')
 
# Background color for initial known cells
        if self.grid_0[row][col]!=0:
            cellColor(painter, option, [200,200,200])
 
        QtGui.QItemDelegate.paint(self, painter, option, index)
 
class MainWindow(QtGui.QWidget):
    def __init__(
        self,
        parent = None
    ):
        super(MainWindow, self).__init__(parent)
 
# General grid
        self.table = QtGui.QTableWidget(self)
        self.nbrow, self.nbcol = 9, 9
        self.table.setRowCount(self.nbrow)
        self.table.setColumnCount(self.nbcol)
 
# Each cell has dimension 50 pixels x 50 pixels
        for row in range(0, self.nbrow):
            self.table.setRowHeight(row, 50)
 
            for col in range(0, self.nbcol):
                self.table.setColumnWidth(col, 50)
 
# Each cell contains one single QTableWidgetItem
        for row in range(0, self.nbrow):
            for col in range(0, self.nbcol):
                item = QtGui.QTableWidgetItem()
                item.setTextAlignment(
                    QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter
                )
 
                self.table.setItem(row, col, item)
 
# Header formatting
        font = QtGui.QFont()
        font.setFamily(u"DejaVu Sans")
        font.setPointSize(12)
        self.table.horizontalHeader().setFont(font)
        self.table.verticalHeader().setFont(font)
 
# Font used
        font = QtGui.QFont()
        font.setFamily(u"DejaVu Sans")
        font.setPointSize(20)
        self.table.setFont(font)
 
# Global Size
        self.resize(60*9, 60*9 + 20)
 
# Layout of the table
        layout = QtGui.QGridLayout()
        layout.addWidget(self.table, 0, 0)
        self.setLayout(layout)
 
# Initial grid (to test)
        self.grid_0 =  [
            [0,0,0, 0,2,0, 9,0,1],
            [0,0,0, 0,0,0, 0,0,3],
            [0,8,0, 3,0,0, 4,5,0],
#
            [0,4,7, 0,0,5, 0,8,0],
            [0,0,0, 0,0,0, 0,0,0],
            [0,2,0, 9,0,0, 7,4,0],
#
            [0,9,5, 0,0,2, 0,3,0],
            [6,0,0, 0,0,8, 0,0,0],
            [7,0,4, 0,6,0, 0,0,0]
        ]
 
# Use of the delegate so to use thicker lines.
        self.delegate = SudokuDelegate(self.table)
        self.table.setItemDelegate(self.delegate)
        self.delegate.initGrid(self.grid_0)
 
# Initialization of the actual grid
        self.grid = deepcopy(self.grid_0)
 
# Display the grid.
        self.update(self.grid)
 
# ??
        self.cellToFill = []
 
        for row in range(9):
            for col in range(9):
                if self.grid_0[row][col] == 0:
                    self.cellToFill.append((row, col))
 
# Set the focus in the first cell
        self.table.setFocus()
        self.table.setCurrentCell(0, 0)
        self.table.keyPressEvent = self.keyPressEvent
 
    def keyPressEvent(self, event):
        row, col = self.table.currentRow(), self.table.currentColumn()
 
# One digit
        if ord('1') <= event.key() <= ord('9'):
            if (row, col) in self.cellToFill:
                font = QtGui.QFont()
                font.setFamily(u"DejaVu Sans")
                font.setPointSize(20)
                self.table.item(row, col).setFont(font)
 
                color = QtGui.QColor(0, 0, 0)
                self.table.item(row, col).setForeground(color)
 
                self.table.item(row, col).setText(chr(event.key()))
# Arrow moving
        elif event.key() == QtCore.Qt.Key_Up:
            self.table.setCurrentCell((row - 1) % 9, col)
 
        elif event.key() == QtCore.Qt.Key_Down:
            self.table.setCurrentCell((row + 1) % 9, col)
 
        elif event.key() == QtCore.Qt.Key_Left:
            self.table.setCurrentCell(row, (col - 1) % 9)
 
        elif event.key() == QtCore.Qt.Key_Right:
            self.table.setCurrentCell(row, (col + 1) % 9)
 
    def update(self, g):
        for row in range(0, len(g[0])):
            for col in range(0, len(g)):
                if g[row][col] == 0:
                    font = QtGui.QFont()
                    font.setFamily(u"DejaVu Sans")
                    font.setPointSize(12)
                    self.table.item(row, col).setFont(font)
 
                    color = QtGui.QColor(0, 0,  255, 255) # bleu
                    self.table.item(row, col).setForeground(color)
 
                    self.table.item(row, col).setText(
                        u"1 2 3\n4 5 6\n7 8 9"
                    )
                    self.table.item(
                        row, col
                    ).setFlags(
                        QtCore.Qt.ItemIsEnabled
                        | QtCore.Qt.ItemIsSelectable
#                        | QtCore.Qt.ItemIsEditable
                    )
 
                else:
                    self.table.item(row, col).setText(unicode(g[row][col]))
                    self.table.item(
                        row, col
                    ).setFlags(
                        QtCore.Qt.ItemIsEnabled
                        | QtCore.Qt.ItemIsSelectable
                    )
 
# Just for testing !
        color = QtGui.QColor(160, 255, 160, 255) # Light green
        self.table.item(2, 4).setBackground(color)
 
        color = QtGui.QColor(255, 160, 160, 255) # Light red
        self.table.item(6, 3).setBackground(color)
 
 
if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    fen = MainWindow()
    fen.show()
    sys.exit(app.exec_())
rambc est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/03/2013, 18h34   #17
tyrtamos
Expert Confirmé
 
Avatar de tyrtamos
 
Inscription : décembre 2007
Messages : 1 777
Détails du profil
Informations personnelles :
Localisation : France

Informations forums :
Inscription : décembre 2007
Messages : 1 777
Points : 3 049
Points : 3 049
Bonjour rambc,

J'ai quelques solutions à te proposer.

Je n'ai pas repris la totalité de ton code, pour que les solutions que tu cherches ne soient pas noyées.

Je crois avoir amélioré l'esthétique de la grille. Voilà ce que ça donne:



Voilà le code qui fait ça (les commentaires sont à la suite):

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
#!/usr/bin/python
# -*- coding: utf-8 -*-
from __future__ import division
 
import sys, os
 
from PyQt4 import QtCore, QtGui
 
#############################################################################
def cellColor(painter, option, color):
    """ peint la case dans la couleur demandée (appel par le delegate)"""
    r = option.rect
    x, y, w, h = r.x() + 1, r.y() + 1, r.width()-2, r.height()-2
 
    if isinstance(color, (str, unicode)):
        color = QtGui.QColor(color)
    elif isinstance(color, (list, tuple)):
        if len(color) == 3:
            r, g, b = color
            alpha   = 255
        else:
            r, g, b, alpha = color
        color = QtGui.QColor(r, g, b, alpha)
    painter.fillRect(x, y, w, h, color)
 
#############################################################################
class CouleurCase(object):
 
    #========================================================================
    def __init__(self):
        self.cases = []
 
    #========================================================================
    def couleur(self, row, col):
        """si la case existe, retourne la couleur, sinon None"""
        for (r, c, coul) in self.cases:
            if row==r and col==c:
                return coul
        return None
 
    #========================================================================
    def metcouleur(self, row, col, couleur=u"white"):
        """si la case est déjà dans la liste, change sa couleur. 
           sinon, ajoute case et couleur
        """
        for i, (r, c, coul) in enumerate(self.cases):
            if row==r and col==c:
                self.cases[i][2] = couleur
                return
        # la case n'est pas là: on l'ajoute avec sa couleur 
        self.cases.append([row, col, couleur])
 
#############################################################################
# variable globale        
couleurCase = CouleurCase()
 
#############################################################################
class SudokuDelegate(QtGui.QItemDelegate):
    """delegate qui redessine chaque case"""
 
    #========================================================================
    def __init__(self, parent=None):
        super(SudokuDelegate, self).__init__(parent)
 
    #========================================================================
    def paint(self, painter, option, index):
        global couleurCase
 
        # sauvegarde la config de painter
        painter.save() 
 
        # récup des coordonnées de la case en cours
        row, col = index.row(), index.column()
 
        # récup des données (en pixels) du rectangle de la case 
        r = option.rect
        x, y, w, h = r.x()-1, r.y()-1, r.width()+1, r.height()+1
 
        # initialise le crayon gras
        pen = QtGui.QPen(QtCore.Qt.SolidLine)
        pen.setWidth(3)
        painter.setPen(pen)
 
        # dessine le côté gauche en gras
        if col in [3, 6]: 
            x1, y1, x2, y2 = x, y + h, x, y
            painter.drawLine(x1, y1, x2, y2)
 
        #dessine le côté haut en gras
        if row in [3, 6]: 
            x1, y1, x2, y2 = x, y, x + w, y
            painter.drawLine(x1, y1, x2, y2)
 
        # dessine le côté droit en gras
        if col in [2, 5]: 
            x1, y1, x2, y2 = x + w, y, x + w, y + h
            painter.drawLine(x1, y1, x2, y2)
 
        # dessine le côté bas en gras
        if row in [2, 5]: 
            x1, y1, x2, y2 = x + w, y + h, x, y + h
            painter.drawLine(x1, y1, x2, y2)
 
        # essai d'appel pour mettre les cases en couleur
        couleurCase.metcouleur(4, 1, [160, 255, 160]) # vert clair])
        couleurCase.metcouleur(6, 5, [255, 160, 160]) # rouge clair])
        couleur = couleurCase.couleur(row, col)
        if couleur != None:
            cellColor(painter, option, couleur)
 
        # restaure la config initiale de painter
        painter.restore() 
 
        # redonne la main à la méthode normale pour la suite des opérations
        QtGui.QItemDelegate.paint(self, painter, option, index)
 
#############################################################################
class MainWindow(QtGui.QWidget):
 
    #========================================================================
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        global couleurCase
 
        # General grid
        self.table = QtGui.QTableWidget(self)
        self.nbrow, self.nbcol = 9, 9
        self.table.setRowCount(self.nbrow)
        self.table.setColumnCount(self.nbcol)
 
        # cache les entêtes horizontale et verticale
        self.table.horizontalHeader().hide()
        self.table.verticalHeader().hide()
 
        # Each cell has dimension 50 pixels x 50 pixels
        for row in range(0, self.nbrow):
            self.table.setRowHeight(row, 50)
            for col in range(0, self.nbcol):
                self.table.setColumnWidth(col, 50)
 
        # Each cell contains one single QTableWidgetItem
        for row in range(0, self.nbrow):
            for col in range(0, self.nbcol):
                item = QtGui.QTableWidgetItem()
                item.setTextAlignment(QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter)
                self.table.setItem(row, col, item)
 
        # Header formatting
        font = QtGui.QFont()
        font.setFamily(u"DejaVu Sans")
        font.setPointSize(12)
        self.table.horizontalHeader().setFont(font)
        self.table.verticalHeader().setFont(font)
 
        # Font used
        font = QtGui.QFont()
        font.setFamily(u"DejaVu Sans")
        font.setPointSize(20)
        self.table.setFont(font)
 
        # Use of the delegate so to use thicker lines.
        self.delegate = SudokuDelegate(self.table)
        self.table.setItemDelegate(self.delegate)
        #self.delegate.initGrid(self.grid_0)
 
        # met un entourage de 3 px pour le widget QTableWidget
        self.table.setStyleSheet("QTableWidget {border: 3px solid black;} ")
 
        # calcule la taille de la grille (6=2*largeur du trait de 3 px)
        w = self.table.horizontalHeader().length()+6
        h = self.table.verticalHeader().length()+6
 
        # redimensionne le widget avec la taille de la grille
        self.table.setMinimumSize(QtCore.QSize(w, h))
        self.table.setMaximumSize(QtCore.QSize(w, h))
 
        # taille de la fenêtre
        self.resize(w+100, h+100)
 
        # placement du QTableWidget dans la fenêtre avec un QGridLayout
        layout = QtGui.QGridLayout()
        layout.addWidget(self.table, 0, 0)
        self.setLayout(layout)
 
        # Set the focus in the first cell
        self.table.setFocus()
        self.table.setCurrentCell(0, 0)
 
        # essai pour mettre les cases en couleur
        #couleurCase.metcouleur(3, 2, u"red")
        couleurCase.metcouleur(3, 5, [200,200,200])
 
        self.table.item(1, 6).setToolTip(u"1  \n45 \n7 9")
        #self.table.item(1, 6).setToolTip(u"")
 
#############################################################################
if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    fen = MainWindow()
    fen.show()
    sys.exit(app.exec_())
Commentaires:

Pour mettre la grille au centre de la fenêtre, y compris avec le redimensionnement, il suffit:
- de fixer les dimensions de la grille en mini et en maxi
- et de la placer dans un QGridLayout

Pour mettre de la couleur dans une case, on peut soit le faire à partir de delegate, soit à partir du QTableWidget. Mais à partir du QTableWidget, la couleur a tendance à "manger" un peu d'encadrement. Alors j'ai essayé de passer systématiquement par le delegate: cela explique la classe "CouleurCase" qui gère une liste de coordonnées comme [ligne, colonne, couleur].

Pour avoir sur demande une petite fenêtre avec les nombres permis dans la case en question, j'ai pensé à 2 solutions:

- utiliser les bulles qui existent dans chaque case. Par exemple:

Code :
self.table.item(1, 6).setToolTip(u"1  \n45 \n7 9")
Pour annuler, il suffit de redonner l'instruction avec une chaine vide.

- utiliser la barre de status en bas de la fenêtre, mais cela demande à prendre la fenêtre QMainWindow au lieu de QWidget.
__________________
Ne rien ranger permet d'observer la loi universelle d'entropie: l'inévitable convergence vers le chaos...
Mes recettes python: http://www.jpvweb.com
tyrtamos est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/03/2013, 18h42   #18
rambc
Membre Expert
 
Inscription : décembre 2006
Messages : 2 197
Détails du profil
Informations forums :
Inscription : décembre 2006
Messages : 2 197
Points : 1 221
Points : 1 221
Cela a l'air zoli !

Je teste cela avec PySide en fin de semaine car je croûle sous le boulot en retard.

Serais-tu partant pour mettre le code sur pypi et github ? Je te mettrais en tant que concepteur associé de l'interface ou sous un autre titre.

On pourrait aussi le mettre bien entendu sur ce site.
rambc est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/03/2013, 19h12   #19
tyrtamos
Expert Confirmé
 
Avatar de tyrtamos
 
Inscription : décembre 2007
Messages : 1 777
Détails du profil
Informations personnelles :
Localisation : France

Informations forums :
Inscription : décembre 2007
Messages : 1 777
Points : 3 049
Points : 3 049
Citation:
Envoyé par rambc Voir le message
Serais-tu partant pour mettre le code sur pypi et github ? Je te mettrais en tant que concepteur associé de l'interface ou sous un autre titre.

On pourrait aussi le mettre bien entendu sur ce site.
Pas de problème pour moi: tu pilotes! Mais avant la publication, j'aimerais simplement vérifier que ma partie est ok sur le produit final.

Je peux te proposer, si ça te manque, une jolie fenêtre pour l'inévitable "à propos" et le copyright.

Je peux aussi essayer d'en faire une version binaire avec cx_freeze, voire avec l'installeur "innosetup" pour Windows.

Je peux aussi te proposer de le mettre dans la barre de notification (tray), pour que les gens qui font le sudoku au boulot puisse le faire discrètement .
__________________
Ne rien ranger permet d'observer la loi universelle d'entropie: l'inévitable convergence vers le chaos...
Mes recettes python: http://www.jpvweb.com
tyrtamos est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/03/2013, 21h31   #20
rambc
Membre Expert
 
Inscription : décembre 2006
Messages : 2 197
Détails du profil
Informations forums :
Inscription : décembre 2006
Messages : 2 197
Points : 1 221
Points : 1 221
Tout ce que tu me proposes est intéressant modulo innosetup car je suis librophile et windophobe...

Je regarde donc ta proposition ce weekend tranquillement.

Merci pour ta collaboration, c'est génial !
rambc est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 00h52.


 
 
 
 
Partenaires

Hébergement Web