Python - tkinter中面向对象的函数,具有单击事件

时间:2017-12-29 21:35:27

标签: python events tkinter self

我的程序应该在点击滚动骰子后 - 它使用六个骰子图像,一个,两个,三个,四个,五个和六个点。首先显示带有一个点的图像,然后点击图像后应随机更改8​​次。最后,最后一张随机图像应保留在屏幕上,但它不起作用,我无法解决它。知道如何解决它吗? (我知道这不需要3个课程,但是当我解决这个问题时我会继续学习) 感谢

import tkinter, random

class Main:
    def __init__(self, area, dice):
        dice.throw(area)

class Area:

    def __init__(self):
        self.canvas = tkinter.Canvas(width=1000, height=600)
        self.canvas.pack()
        self.dice1 = tkinter.PhotoImage(file='numberOne.png')
        self.canvas.create_image(680,540,image=self.dice1)
        self.canvas.bind('<Button-1>', Dice.throw)

class Dice:

    def throw(event):
        if event.x < 730 and event.x > 630 and event.y < 590 and event.y > 490:
            dice1 = tkinter.PhotoImage(file='numberOne.png')
            dice2 = tkinter.PhotoImage(file='numberTwo.png')
            dice3 = tkinter.PhotoImage(file='numberThree.png')
            dice4 = tkinter.PhotoImage(file='numberFour.png')
            dice5 = tkinter.PhotoImage(file='numberFive.png')
            dice6 = tkinter.PhotoImage(file='numberSix.png')
            for i in range(8):
                number = random.randrange(6) + 1
                if number == 1:
                    area.canvas.create_image(680,540,image=dice1)
                elif number == 2:
                    area.canvas.create_image(680,540,image=dice2)
                elif number == 3:
                    area.canvas.create_image(680,540,image=dice3)               
                elif number == 4:
                    area.canvas.create_image(680,540,image=dice4)       
                elif number == 5:
                    area.canvas.create_image(680,540,image=dice5)
                elif number == 6:
                    area.canvas.create_image(680,540,image=dice6)
                area.canvas.after(100)
                area.canvas.update()

pl = Area()
dice = Dice()
main = Main(pl, dice)

2 个答案:

答案 0 :(得分:0)

问题是Area实例(pl)需要访问Dive实例(dive)和Dive实例需要访问Area实例

dice = Dice(root)
area = Area(root, dice) # `Area` gets access to `Dive` instace
dice.area = area        # `Dive` gets access to `Area` instace

之后Dive可以使用dive.throwDive可以使用area.canvas或其他元素。

为了简单起见,我将标签分配给画布上的图像,然后我可以使用tag_bind分配<Button-1>,而不必检查event.xevent.y

我没有使用create_image创建新图像,而是在cavas上的现有元素中更改图像。

create_image()提供元素ID

self.image_id = self.canvas.create_image(...)

所以稍后我可以更改此元素中的图像

self.canvas.itemconfig(self.image_id, image=image)

我将所有图片保留在列表中,因此我不需要所有变量dice1dice2等等。我可以使用索引而不是if/elif来获取图像。我也可以使用random.choice(self.images)从列表中获取随机元素。

image = random.choice(self.images)

完整代码:

import tkinter
import random

class Main:

    def __init__(self, area, dice):
        dice.throw(area)

class Area:

    def __init__(self, master, dice):
        self.master = master

        self.canvas = tkinter.Canvas(master, width=1000, height=600)
        self.canvas.pack()

        self.image = tkinter.PhotoImage(file='numberOne.png')
        self.image_id = self.canvas.create_image(680, 540, image=self.image, tags='tag_image')

        self.canvas.tag_bind('tag_image', '<Button-1>', dice.throw)

    def change_image(self, image):
        print('changing image')
        self.canvas.itemconfig(self.image_id, image=image)

class Dice:

    def __init__(self, master):
        self.master = master
        self.area = None # assign later

        self.images = [        
            tkinter.PhotoImage(file='numberOne.png')
            tkinter.PhotoImage(file='numberTwo.png')
            tkinter.PhotoImage(file='numberThree.png')
            tkinter.PhotoImage(file='numberFour.png')
            tkinter.PhotoImage(file='numberFive.png')
            tkinter.PhotoImage(file='numberSix.png')
        ]

    def throw(self, event):
        if self.area:
            for i in range(8):
                image = random.choice(self.images)

                self.area.change_image(image)

                self.master.update()
                self.master.after(100)

# --- main ---

root = tkinter.Tk()

dice = Dice(root)
area = Area(root, dice)
dice.area = area

root.mainloop()

答案 1 :(得分:0)

from tkinter import *


class GUI(Tk):
    def __init__(self):
        super().__init__()
        self.geometry("600x750")
        self.title("Calculator")

        self.scvalue = StringVar()
        self.scvalue.set("")
        self.screen = Entry(textvar=self.scvalue,font=("Impact",30,"bold"),relief="groove")
        self.screen.pack(fill=X,ipadx=8, pady=10, padx=10)

        self.frame = Frame(self, bg="grey")
        self.frame.pack()
        # First row
        self.button = Button(self.frame,text="9", padx="15",font=("Impact",30,"bold"),bd=10,relief="groove")
        self.button.pack(side=LEFT,padx=5,pady=3)
        self.button.bind("<Button-1>",self.click)
        
        self.button = Button(self.frame,text="8", padx="15",font=("Impact",30,"bold"),bd=10,relief="groove")
        self.button.pack(side=LEFT,padx=5,pady=3)
        self.button.bind("<Button-1>",self.click)
        
        self.button = Button(self.frame,text="7", padx="15",font=("Impact",30,"bold"),bd=10,relief="groove")
        self.button.pack(side=LEFT,padx=5,pady=3)
        self.button.bind("<Button-1>",self.click)
      
        self.frame = Frame(self, bg="grey")
        self.frame.pack()
        #second row
        self.button = Button(self.frame,text="6", padx="15",font=("Impact",30,"bold"),bd=10,relief="groove")
        self.button.pack(side=LEFT,padx=5,pady=3)
        self.button.bind("<Button-1>",self.click)

        self.button = Button(self.frame,text="5", padx="15",font=("Impact",30,"bold"),bd=10,relief="groove")
        self.button.pack(side=LEFT,padx=5,pady=3)
        self.button.bind("<Button-1>",self.click)

        self.button = Button(self.frame,text="4", padx="15",font=("Impact",30,"bold"),bd=10,relief="groove")
        self.button.pack(side=LEFT,padx=5,pady=3)
        self.button.bind("<Button-1>",self.click)

        self.frame = Frame(self, bg="grey")
        self.frame.pack()
        #third row
        self.button = Button(self.frame,text="3", padx="15",font=("Impact",30,"bold"),bd=10,relief="groove")
        self.button.pack(side=LEFT,padx=7,pady=3)
        self.button.bind("<Button-1>",self.click)
        
        self.button = Button(self.frame,text="2", padx="15",font=("Impact",30,"bold"),bd=10,relief="groove")
        self.button.pack(side=LEFT,padx=7,pady=3)
        self.button.bind("<Button-1>",self.click)
        
        self.button = Button(self.frame,text="1", padx="15",font=("Impact",30,"bold"),bd=10,relief="groove")
        self.button.pack(side=LEFT,padx=7,pady=3)
        self.button.bind("<Button-1>",self.click)
        
        self.frame = Frame(self, bg="grey")
        self.frame.pack()
        #fourth row
        self.button = Button(self.frame,text="0", padx="15",font=("Impact",30,"bold"),bd=10,relief="groove")
        self.button.pack(side=LEFT,padx=5,pady=3)
        self.button.bind("<Button-1>",self.click)
       
        self.button = Button(self.frame,text="00", padx="15",font=("Impact",30,"bold"),bd=10,relief="groove")
        self.button.pack(side=LEFT,padx=5,pady=3)
        self.button.bind("<Button-1>",self.click)
        
        self.button = Button(self.frame,text=".", padx="15",font=("Impact",30,"bold"),bd=10,relief="groove")
        self.button.pack(side=LEFT,padx=5,pady=3)
        self.button.bind("<Button-1>",self.click)
        
        self.frame = Frame(self, bg="grey")
        self.frame.pack()
        #fifth row
        self.button = Button(self.frame,text="+", padx="15",font=("Impact",30,"bold"),bd=10,relief="groove")
        self.button.pack(side=LEFT,padx=10,pady=3)
        self.button.bind("<Button-1>",self.click)
        
        self.button = Button(self.frame,text="-", padx="15",font=("Impact",30,"bold"),bd=10,relief="groove")
        self.button.pack(side=LEFT,padx=10,pady=3)
        self.button.bind("<Button-1>",self.click)
        
        self.button = Button(self.frame,text="*", padx="15",font=("Impact",30,"bold"),bd=10,relief="groove")
        self.button.pack(side=LEFT,padx=10,pady=3)
        self.button.bind("<Button-1>",self.click)
        
        self.frame = Frame(self, bg="grey")
        self.frame.pack()
        #sixth row
        self.button = Button(self.frame,text="%", padx="15",font=("Impact",30,"bold"),bd=10,relief="groove")
        self.button.pack(side=LEFT,padx=5,pady=3)
        self.button.bind("<Button-1>",self.click)
        
        self.button = Button(self.frame,text="C", padx="15",font=("Impact",30,"bold"),bd=10,relief="groove")
        self.button.pack(side=LEFT,padx=5,pady=3)
        self.button.bind("<Button-1>",self.click)
        
        self.button = Button(self.frame,text="=", padx="15",font=("Impact",30,"bold"),bd=10,relief="groove")
        self.button.pack(side=LEFT,padx=5,pady=3)
        self.button.bind("<Button-1>",self.click)
        

    def click(self,event):
        self.text = event.widget.cget("text")
        if self.text == '=':
            if self.scvalue.get().isdigit():
                self.value=self.scvalue.get()
            else:
                try:
                    #eval => evauluate expression
                    self.value = eval(self.screen.get())
                    self.scvalue.set(self.value)
                    self.screen.update()
                except Exception as e:
                    self.scvalue.set("Error....")
                    self.screen.update()
            pass
        elif self.text=='C':
            self.scvalue.set("")
            self.screen.update()

        else:
            self.scvalue.set(self.scvalue.get()+self.text)
            self.screen.update()

root = GUI()
root.mainloop()