• Tkinterr制作520惊喜小程序


    为了520能够博得女友欢心,我设计了一个用来表白的程序,主要用到了tkinter的画布和各种鼠标事件,今天就来分享给大家。(借鉴要谨慎,可不要只用它来糊弄女盆友哦)

    程序的设计是用tkinter模拟手机操作,实现手机桌面的展示、滑动和下拉,然后点击指定位置,可以弹出新的内容。其原理是用canvas显示图片,所谓的滑动和点击等等,其实就是图片的更换;下拉则是利用鼠标事件来移动图片,实现和手机下拉相同的效果(不到半屏自动回位,超过半屏自动落下,落下后拖动底端回位)。

    桌面是犯罪嫌疑人——偷心贼

    下拉的效果:

    部分效果如上所示,点击信息、拨号和相册,可以分别弹出新的图片(把表白的内容放在这里);点击home键则是返回(home键是一个显示了图片的button按钮);桌面还可以滑动,滑动后切换成另一张背景图(我本人),然后对应绑定了不同的鼠标事件,点击后会显示与之前不同的图片。(所有图片都是我用自己的手机截图的)

    程序逻辑里,最重要的部分就是几个模式的区分,我用flag来定义,具体如下:flag=0是初始状态、点击屏幕其他位置和下拉未到半屏回位后的状态;flag=1是点击屏幕顶端下拉;flag=2是下拉超过半屏后自动落下,和此时再点击其他位置;flag=3是落下后点击屏幕底端回位;flag=5是切换屏幕。

    程序中创建了两个canvas,一个用来显示外壳(固定不动),另一个用来显示屏幕(触发各种事件)。在这两个画布中,获取鼠标位置event.x和event.y是分开计的,所以我们只需要用到显示屏幕的画布中的位置。根据信息、拨号和相册的位置,在点击时设置对应的flag值,触发各自的事件(其实就是显示新的图片)。

    另外,所有屏幕图片的大小都是400*700,所以桌面的初始位置在(200,350)附近,而下拉图片的初始位置是(200,-350),此时是在画布外的,不会显示出来。触发下拉事件时,它就会跟随鼠标移动。(这也是创建两个canvas的原因,如果只用一个,由于屏幕不是在画布的顶端,因此下拉图片不会被隐藏起来;而如果它属于其中一个画布,但初始位置在画布外,那么就会隐藏)

    下面是完整代码和简单注释:

    from tkinter import *
    import tkinter as tk
    from PIL  import Image, ImageTk
    import time
    import cv2
    
    flag=0  #状态标志
    root = Tk()
    root.title("手机")
    root.geometry("450x840+500+0")
    root.overrideredirect(True)
    canvas2 = Canvas(root,width=450, height=840,bg='white',highlightthickness=0)
    canvas = Canvas(root,width=400, height=700,bg='black',highlightthickness=0)
    f=0 #记录之前的flag,当前事件结束后返回前一个状态
    canvas2.place(x=0,y=0)  #手机壳
    canvas.place(x=24,y=80)  #屏幕
    
    #左键点击home键,清除刚才显示的图片(即返回桌面),同时开始计时
    def onLeftButton(event):
        global start
        start=time.time()
        canvas.delete('c')
        
    #鼠标左键抬起home键,结束计时,超过3秒则退出程序(关机),否则退回之前的flag
    def ButtonUp(event):
        global end,start,flag
        end=time.time()
        flag=f  
        if end-start>=3:
            root.destroy()
    #获得鼠标位置,并设置相应的flag
    def callback(event):
        global x,y,flag
        
        x = event.x
        y = event.y
        if flag!=2 and 0<y<10:
            flag=1
        if flag==2 and y>680:
            flag=3
    
    #双击“信息”、“拨号”或“相册”的位置,显示新的图片
    #两个桌面对应不同的图片,用flag来区分
    def DoubleButton(event):
        if flag==5:
            if 30<x<90 and 30<y<90:
                canvas.create_image(200,350,image=var7,tags="c")
            elif 120<x<180 and 600<y<660:
                canvas.create_image(200,350,image=var8,tags="c")
        else:
            if 30<x<90 and 30<y<90:
                canvas.create_image(200,350,image=var3,tags="c")
            elif 120<x<180 and 600<y<660:
                canvas.create_image(200,350,image=var4,tags="c")
            elif 220<x<270 and 600<y<660:
                canvas.create_image(200,350,image=var5,tags="c")
    
    #按住左键并拖动鼠标,显示下拉图片
    def onLeftButtonMove(event):
        global a,flag,f   
        if flag==2:
            return
        if flag==0:
            f=5-flag #这里要么是0,要么是5
            return
        if flag==5:
            f=5-flag
            return
        #下拉栏落下后,拖动底端回位
        if flag==3:
            if event.y<=702:
                canvas.delete('a')
                canvas.create_image(200,event.y-350,image=var1,tags="a")       
                return
        #跟随鼠标下拉
        if flag==1 and event.y<=702:
            canvas.delete('a')
            canvas.create_image(200,event.y-350,image=var1,tags="a")
            return
        
    #释放左键,触发下拉的动态效果(自动下落或回位)以及两个桌面的切换      
    def onLeftButtonUp(event):
        global a,flag  
        if flag==0:
            if abs(event.x-x)>10:
                canvas.create_image((200,350), image=var6,tags='b')
                flag=5
                return
            else:
                return
        if flag==5:
            if abs(event.x-x)>10:
                canvas.create_image((200,350), image=var2,tags='b')
                flag=0
                return
            else:
                return
        if flag==2:
            return
        yy=event.y
        i=0
        if flag==3:
    		#不到半屏自动回位
            while yy-i>=-350:
                canvas.delete('a')
                canvas.create_image(200,yy-i-350,image=var1,tags="a")
                i+=1
                root.update_idletasks()  #刷新
                root.update()
    
            flag=f
            return
        #超过半屏自动落下
        if yy>350:
                while yy+i<=702:
                    canvas.delete('a')
                    canvas.create_image(200,yy+i-350,image=var1,tags="a")
                    i+=1
                    root.update_idletasks()  #刷新
                    root.update()
    
                flag=2
                return
        #点击底端,自动回位
        while yy-i>=-350:
                    canvas.delete('a')
                    canvas.create_image(200,yy-i-350,image=var1,tags="a")
                    i+=1
                    root.update_idletasks()  #刷新
                    root.update()
    
        flag=f
    
    #存储初始图
    load = Image.open("res/0.jpg") #手机壳图片
    var= ImageTk.PhotoImage(load) 
    load = Image.open("res/1.png")
    var1= ImageTk.PhotoImage(load)  
    load = Image.open("res/2.jpg")
    var2= ImageTk.PhotoImage(load) 
    load = Image.open("res/3.jpg")
    var3= ImageTk.PhotoImage(load)
    load = Image.open("res/4.jpg")
    var4= ImageTk.PhotoImage(load)
    load = Image.open("res/5.jpg")
    var5= ImageTk.PhotoImage(load)
    load = Image.open("res/6.jpg")
    var6= ImageTk.PhotoImage(load)
    load = Image.open("res/7.png")
    var7= ImageTk.PhotoImage(load)
    load = Image.open("res/8.jpg")
    var8= ImageTk.PhotoImage(load)
    load = Image.open("res/bt.png")
    bt= ImageTk.PhotoImage(load)
    
    canvas.create_image((200,-350), image=var1,tags='a')  #下拉图片的初始位置,此时未进入画布当中
    canvas2.create_image((225,430), image=var)  #手机壳
    canvas.create_image((200,352), image=var2,tags='b')  #初始桌面
    b = Button(root, image = bt, bg='black',activebackground='black')
    b.place(x=165,y=800)
    b.bind('<Button-1>', onLeftButton)
    b.bind('<ButtonRelease-1>', ButtonUp)
    canvas.bind('<B1-Motion>', onLeftButtonMove)  #按住并移动左键
    canvas.bind('<ButtonRelease-1>', onLeftButtonUp)  #释放左键
    canvas.bind('<Double-Button-1>', DoubleButton)  #双击左键
    root.bind("<Button-1>",callback)
    root.mainloop()

    P.S.代码中用到的各种位置都经过了微调,达到最佳效果。

    在这篇文章里,我们演示了如何用tkinter实现复杂的鼠标事件,将不同组件的鼠标事件结合起来。赶紧学会这一手,回去哄女朋友吧!

  • 相关阅读:
    401. Binary Watch
    46. Permutations
    61. Rotate List
    142. Linked List Cycle II
    86. Partition List
    234. Palindrome Linked List
    19. Remove Nth Node From End of List
    141. Linked List Cycle
    524. Longest Word in Dictionary through Deleting
    android ListView详解
  • 原文地址:https://www.cnblogs.com/Skypeduty1225/p/16259256.html
Copyright © 2020-2023  润新知