2016-11-21 2 views
0

Comment faire pour que la souris fasse quelque chose quand elle clique à un certain point dans les graphiques de Zelle? Ce que j'essaie de faire, c'est de faire démarrer mon chronomètre quand je clique sur l'image "startbutton". Cependant, je fais évidemment quelque chose de mal parce que mon programme se bloque ou ne fait rien.Comment faire un clic de souris faire quelque chose à un point précis?

from graphics import * 
import time 
#from tkinter import * 

win = GraphWin('Stopwatch', 600, 600) 
win.yUp() 

#Assigning images 
stopWatchImage = Image(Point (300, 300), "stopwatch.png") 
startImage = Image(Point (210, 170), "startbutton.png") 
stopImage = Image(Point (390, 170), "stopbutton.png") 
lapImage = Image(Point (300, 110), "lapbutton.png") 


stopWatchImage.draw(win) 
startImage.draw(win) 
stopImage.draw(win) 
lapImage.draw(win) 


sec = 0 
minute = 0 
hour = 0 

def isBetween(x, end1, end2): 
'''Return True if x is between the ends or equal to either. 
The ends do not need to be in increasing order.''' 

    return end1 <= x <= end2 or end2 <= x <= end1 

def isInside(point, startImage): 
'''Return True if the point is inside the Rectangle rect.''' 

    pt1 = startImage.getP1() 
    pt2 = startImage.getP2() 
    return isBetween(point.getX(), pt1.getX(), pt2.getX()) and \ 
      isBetween(point.getY(), pt1.getY(), pt2.getY()) 


def getChoice(win):  #NEW 
'''Given a list choicePairs of tuples with each tuple in the form 
(rectangle, choice), return the choice that goes with the rectangle 
in win where the mouse gets clicked, or return default if the click 
is in none of the rectangles.''' 

    point = win.getMouse() 
    if isInside(point, startImage): 
     time.sleep(1) 
     sec += 1 
     timeText.setText(sec) 
     timeText.setText('') 


     while sec >= 0 and sec < 61: 

     #Displaying Time 
      timeText = Text(Point (300,260), str(hour) + ":" + str(minute) + ":" + str(sec)) 
      timeText.setSize(30) 
      timeText.draw(win) 
      time.sleep(1) 
      sec += 1 
      timeText.setText(sec) 
      timeText.setText('') 
      #Incrementing minutes,hours 
      if sec == 60: 
       sec = 0   
       minute += 1 

      if minute == 60: 
       sec = 0 
       minute = 0 
       hour += 1 


return default 


def layout() 
    getChoice(win) 

layout() 

Je n'arrive pas à l'obtenir.

Modifier: ajouté le reste de mon code pour clarification.

+0

question de modifier, le code de mise en surbrillance et utilisez le bouton '{}' pour formater correctement le code. Maintenant vous avez tort indentions. – furas

+0

J'ai modifié le code en conséquence. – Sammy

Répondre

0

Vous pouvez utiliser setMouseHandler pour affecter une fonction qui sera appelée lorsque vous cliquez dans la fenêtre. Par exemple, si vous cliquez dans la partie gauche de la fenêtre, elle dessine un rectangle, si vous cliquez dans la partie droite de la fenêtre, elle dessine un cercle.

Vous pouvez ouvrir le fichier graphics.py et voir tout le code. C'est la méthode la plus rapide pour voir quelles fonctions vous pouvez utiliser.

from graphics import * 

# --- functions --- 

def on_click(point): 
    # inform function to use global variable 
    global win 

    if point.x > win.width//2: 
     c = Circle(point, 10) 
     c.draw(win) 
    else: 
     a = Point(point.x - 10, point.y - 10) 
     b = Point(point.x + 10, point.y + 10) 
     r = Rectangle(a, b) 
     r.draw(win) 

def main(): 
    # inform function to use global variable 
    global win 

    win = GraphWin("My Circle", 500, 500) 

    win.setMouseHandler(on_click) 

    win.getKey() 
    win.close() 

# --- start --- 

# create global variable 
win = None 

main() 

BTW:graphics utilise Tkinter qui a des widgets Button, Label, Text, etc. Il peut utiliser canvas.create_window() pour ajouter un widget sur la toile.

Tkinter a également la fonction after(miliseconds, function_name) qui vous permet d'exécuter la fonction périodiquement - ie. pour mettre à jour l'heure.

Exemple

from graphics import * 
import datetime 

# --- classes --- 

class _Widget(): 
    def __init__(self, x, y, w, h, **options): 
     self.x = x 
     self.y = y 
     self.w = w 
     self.h = h 
     self.options = options 

    def draw(self, canvas, **options): 
     return None 

    def set(self, **options): 
     self.widget.config(options) 

    def get(self, **options): 
     self.widget.cget(options) 

class Button(_Widget): 

    def draw(self, canvas, **options): 
     x, y = canvas.toScreen(self.x, self.y) # ??? 

     self.widget = tk.Button(canvas, self.options) 

     return canvas.create_window((x, y), options, width=self.w, height=self.h, window=self.widget, anchor='nw') 

class Label(_Widget): 

    def draw(self, canvas, **options): 
     x, y = canvas.toScreen(self.x, self.y) # ??? 

     self.widget = tk.Label(canvas, self.options) 

     return canvas.create_window((x, y), options, width=self.w, height=self.h, window=self.widget, anchor='nw') 

# --- functions --- 

def on_start(): 
    #global b1, b2 
    global running 

    b1.set(state='disabled') 
    b2.set(state='normal') 

    running = True 

    # run first time 
    update_time() 

    print("START") 

def on_stop(): 
    #global b1, b2 
    global running 

    b1.set(state='normal') 
    b2.set(state='disabled') 
    l.set(text="Controls:") 

    running = False 

    print("STOP") 

def update_time(): 
    #global l 
    #global running 

    if running: 

     l.set(text=datetime.datetime.now().strftime("%H:%M:%S")) 

     # run again after 1000ms (1s) 
     win.after(1000, update_time) 

# --- main --- 

def main(): 
    global win, l, b1, b2 

    win = GraphWin("My Buttons", 500, 500) 

    l = Label(0, 0, 100, 50, text="Controls:") 
    l.draw(win) 

    b1 = Button(100, 0, 100, 50, text="START", command=on_start) 
    b1.draw(win) 

    b2 = Button(200, 0, 100, 50, text="STOP", command=on_stop, state='disabled') 
    b2.draw(win) 

    win.getKey() 
    win.close() 

# --- global variable to access in functions --- 

win = None 
l = None 
b1 = None 
b2 = None 

running = False 

# --- start --- 

main() 

Tkinter: Canvas, Button, other


EDIT: exemple de travail

from graphics import * 


def isBetween(x, end1, end2): 
    return end1 <= x <= end2 or end2 <= x <= end1 

def isInside(point, startImage): 
    x = startImage.getAnchor().getX() 
    y = startImage.getAnchor().getY() 
    w = startImage.getWidth()/2 
    h = startImage.getHeight()/2 

    pt1_x = x - w 
    pt1_y = y - h 

    pt2_x = x + w 
    pt2_y = y + h 

    return isBetween(point.getX(), pt1_x, pt2_x) and \ 
      isBetween(point.getY(), pt1_y, pt2_y) 


def getChoice(event): 
    global hour, minute, sec 
    global running 

    point = Point(round(event.x), round(event.y)) 

    if isInside(point, startImage): 
     sec = 0 
     minute = 0 
     hour = 0 
     running = True 
     update_time() 

    if isInside(point, stopImage): 
     running = False 


def update_time(): 
    global hour, minute, sec 
    #global timeText 
    #global win 

    sec += 1 

    if sec == 60: 
     sec = 0   
     minute += 1 
     if minute == 60: 
      minute = 0 
      hour += 1 

    timeText.setText('{}:{}:{}'.format(hour, minute, sec)) 

    if running: 
     win.after(1000, update_time) 
    else: 
     timeText.setText('') 


def layout(): 
    global win 
    global stopWatchImage 
    global startImage 
    global stopImage 
    global lapImage 
    global timeText 

    win = GraphWin('Stopwatch', 600, 600) 
    #win.yUp() 

    #Assigning images 
    stopWatchImage = Image(Point(300, 300), "stopwatch.png") 
    startImage = Image(Point(210, 170), "startbutton.png") 
    stopImage = Image(Point(390, 170), "stopbutton.png") 
    lapImage = Image(Point(300, 110), "lapbutton.png") 

    #Drawing images 
    stopWatchImage.draw(win) 
    startImage.draw(win) 
    stopImage.draw(win) 
    lapImage.draw(win) 

    timeText = Text(Point(300,260), '') 
    timeText.setSize(30) 
    timeText.draw(win) 

    win.setMouseHandler(getChoice) 

    win.getKey() 

# --- global variable --- 

win = None 

stopWatchImage = None 
startImage = None 
stopImage = None 
lapImage = None 

timeText = None 

running = False 

# --- start --- 

layout() 
+0

Bonjour @furas, j'ai édité ma question pour montrer le reste de mon code. Je ne comprends pas très bien ce que tu m'as montré. Je suis un débutant donc je ne suis pas très au courant de setMouseHandler ect .. Merci – Sammy

+0

'setMouseHandler (nom_fonction)' assigne la fonction qu'il exécutera chaque fois que vous cliquez sur la souris. BTW: 'nom_fonction' signifie un nom sans'() 'et arguments. – furas

+0

Je l'ai, donc je peux configurer MouseHandler pour démarrer le minuteur par exemple, mais comment puis-je le faire quand vous avez une zone spécifique, comme un bouton? J'ai un bouton de démarrage, d'arrêt et de tour pour le chronomètre et chacun doit faire une chose différente, respectivement. Voulez-vous que je poste le reste de mon code? Merci pour la réponse. – Sammy