2017-10-19 3 views
1

Je développe un jeu de tuile hexagone de base dans python3 tkinter (juste pour le plaisir et l'apprentissage). Cependant, je ne trouve pas le moyen d'analyser une valeur d'attribut (self.att_coord) à partir d'un objet (Hexagon) vers une option de widget tkinter (Label) appelée textvariable. L'idée est de montrer ces valeurs dans le widget du bas, similaire à montrer les coordonnées de n'importe quel jeu de société.Analyse de la valeur de l'attribut d'objet au widget textvariable

Jusqu'ici, je peux imprimer() ces valeurs dans le IDLE. Le code suivant montre l'atteinte jusqu'à présent (il suffit de copier/coller/exécuter).

Toute aide est appréciée.

import tkinter 
import math 
import random 

class Hexagon: 
    """ 
    This class return the Geometric calculations to draw the hexagons 
    """ 
    def __init__(self, center_x, center_y, fit, size): 
     self.att_center_x = math.sqrt(3)*(fit+center_x*size) 
     self.att_center_y = (center_y*size)*(6/4) 
     self.att_size = size 
     self.att_coord = (center_x, center_y) #<--- Here the attribute values to parsing 
     self.att_polygone = self.met_polygon() 
    def __getitem__(self, x): 
     return getattr(self, x) 
    def met_polygon(self): 
     result = [] 
     for i in range(0, 6): 
      angle_deg = 60*i+30 
      angle_rad = math.pi/180*angle_deg 
      result.append((self.att_center_x+self.att_size*math.cos(angle_rad), 
          self.att_center_y+self.att_size*math.sin(angle_rad))) 
     return result 

class EofCanvas(tkinter.Canvas): 
    def __init__(self, master, *args, **kwargs): 
     tkinter.Canvas.__init__(self, master=master, *args, **kwargs) 
     self.att_current_coord = "" 
    def met_make_hexagon(self, hex_size): 
     hexa = Hexagon(1, 1, 0, hex_size) 
     x = self.create_polygon(hexa.att_polygone) #<--- Here hexagons are created 
     self.tag_bind(x, '<Enter>', lambda x, hexa = hexa:self.met_print_hexcoord(hexa)) 
    def met_print_hexcoord(self, hexa=None): 
     self.att_current_coord = hexa.att_coord 
     print(self.att_current_coord) #<--- This print the attribute values to the IDLE 
     return hexa.att_coord 

class UserInfoGame(tkinter.Frame): 
    def __init__(self, master, coord, *args, **kwargs): 
     tkinter.Frame.__init__(self, master=master, *args, **kwargs) 
     self.current = self.met_get_current_coord(coord) 
     self.att_coord_label = self.met_make_coord_label(coord) 
    def met_make_coord_label(self, coord): 
     label = tkinter.Label(self, width=10, textvariable=self.current) #<--- Here the textvariable 
     label.pack() 
    def met_get_current_coord(self, coord): 
     return coord.att_current_coord 

class GameGUI: 
    def __init__(self): 
     self.root = tkinter.Tk() 
     self.root.attributes('-fullscreen', True) 
     screen_width = self.root.winfo_screenwidth() 
     screen_height = self.root.winfo_screenheight() 

     canvas_game = EofCanvas(self.root, width=int(0.8*screen_width), height=(0.9*screen_height)) 
     canvas_game.met_make_hexagon(40) 

     user_info_game = UserInfoGame(self.root, width=int(0.8*screen_width), height=int(0.1*screen_height), bd=1, relief='ridge', coord=canvas_game) 

     canvas_game.grid(column=1, row=1) 
     user_info_game.grid(column=1, rows=2) 

    def start(self): 
     self.root.mainloop() 

if __name__ == '__main__': 
    appstart = GameGUI() 
    appstart.start() 
+0

C'est énormément de code. S'il vous plaît essayez de le condenser jusqu'à un [mcve]. –

+0

@BrianOakley essayant ... –

Répondre

1

Normalement, nous faire une variable dans le maître commun, qui est ensuite transmis aux widgets. Cependant, vous passez la racine en tant qu'attribut séparé. Vous devez changer cette situation afin que votre classe principale est une sous-classe de tkinter.Tk:

Voici un petit exemple:

import tkinter 

class EofCanvas(tkinter.Canvas): 
    def __init__(self, master, *args, **kwargs): 
     tkinter.Canvas.__init__(self, master=master, *args, **kwargs) 

     self.bind("<ButtonPress-1>", self.on_click) 

    def on_click(self, event): 
     self.master.status.set("CLICKED: {0.x}, {0.y}".format(event)) 

class UserInfoGame(tkinter.Frame): 
    def __init__(self, master, coord, *args, **kwargs): 
     tkinter.Frame.__init__(self, master=master, *args, **kwargs) 

     label = tkinter.Label(self, width=50, textvariable=self.master.status) #<--- Here the textvariable 
     label.pack() 

class GameGUI(tkinter.Tk): 
    def __init__(self, map_size, *args, **kwargs): 
     tkinter.Tk.__init__(self, *args, **kwargs) 

     self.status = tkinter.StringVar() # we make the variable in a place where all widgets can reach it 

     canvas_game = EofCanvas(self, width=200, height=200, bg='white') # We pass "self", which includes all the instance variables 
     user_info_game = UserInfoGame(self, bd=1, relief='ridge', coord=canvas_game) 

     canvas_game.grid(column=1, row=1) 
     user_info_game.grid(column=1, row=2) 

if __name__ == '__main__': 
    appstart = GameGUI(30) #the int spcifies the size of the board (int x int) 
    appstart.mainloop() 

Nous vous serions reconnaissants si vous faites de petits exemples comme celui-ci à l'avenir, au lieu de nous demander pour choisir à travers votre code massif.

Il existe d'autres façons, mais je pense que c'est le plus propre.

+0

Ouais! Je vous remercie! –