当前位置:首页 » tkinter » 正文

用tkinter做一个不规则的任意形状的异形窗体

不规则窗体制作的原理

网上常看到用别的编程语言做的不规则的,任意形状的异形窗体,就是提供一个图片作为背景,要透明的部分就要专门设定一个特殊的颜色,比如粉红色,加上相应的代码,就可以做一个图片形状的一个窗体。

其实用tkinter也可以做这种异形窗体的,做异形窗体主要牵涉到2个知识点(只要2行代码):

   root.overrideredirect(True) # 让窗体无标题栏

   root.wm_attributes("-transparentcolor", "white") # 设置窗体某种颜色透明

  上面这行代码,是让窗体的白色部分透明。这第2个参数,可以起用用颜色名,如’red’,’blue’ 等,也可以用颜色的16进制来表示,如白色用16进制表示为’#FFFFFF’   注意,16进制用#开头,同时也要用引号括起来。

  下面我们就用做一个小狗的窗体。下面是小狗的png格式图:

202111151020143304992.png

这个小狗尺寸为 132 X 102  狗周围的颜色为白色。我们编程规划:

1,先创建一个窗体,尺寸为132x102

2, 创建一个标签,用于显示小狗的图片

3,用代码 root.overrideredirect(True) 让窗体无标题栏

4,用代码 root.wm_attributes("-transparentcolor", "white") 让窗体的白色部分透明

5,增加鼠标左键按下标签,移动窗体的代码

6,增加一个弹出菜单,方便退出程序(双击标签退出程序也行)

先创建透明颜色窗体

以下是创建透明小狗窗体的代码,双击小狗可退出窗体:         丶丌皛

from tkinter import *
 
def exit(event):
    root.destroy()  # 鼠标双击小狗退出程序
 
root=Tk() # 源码来自wb98.com
root.geometry('132x103+888+444')  # 窗体的尺寸正好是图片小狗的图片
 
img1=PhotoImage(file='gou1.png') # 创建图片对像
la1=Label(root, image=img1,bd=0)  # 创建标签,标签边框宽度为0
la1.place(x=0,y=0) # 用place定位
 
la1.bind("<Double-Button-1>",exit) # 鼠标双击标签小狗绑定exit函数
 
root.overrideredirect(True) # 让窗体无标题栏
# root.wm_attributes("-transparentcolor", "white") # 设置窗体白色透明
root.wm_attributes("-transparentcolor", "#FFFFFF") # 白色用16进制#FFFFFF代替
 
root.mainloop()

增加可移动小狗窗体的代码

下面我增加移动无标题栏窗体的代码。(移动无标题栏窗体代码的讲解见我的专门文章),增加了标签绑定3个函数,全部代码如下:

from tkinter import *
 
def MouseDown(event):
    global moveYN # 是否可以移动窗体的全局变量
    global mousX  # 全局变量,鼠标在窗体内的x坐标
    global mousY  # 全局变量,鼠标在窗体内的y坐标
 
    moveYN=True    # 打开移动窗体的开关
    mousX=event.x  # 获取鼠标相对于窗体左上角的X坐标
    mousY=event.y  # 获取鼠标相对于窗左上角体的Y坐标
    
def MouseUp(event):
    moveYN=False   # 关闭移动窗体的开关
def MouseMove(event): 
    if moveYN==True: # 如果鼠标按下,就可以移动窗体到新的位置
        root.geometry(f'+{event.x_root - mousX}+{event.y_root - mousY}') 
def exit(event):
    root.destroy()  # 退出程序
 
root=Tk()
root.geometry('132x103+888+444')  # 窗体的尺寸正好是图片小狗的图片
 
img1=PhotoImage(file='gou1.png') # 创建图片对像
la1=Label(root, image=img1,bd=0)  # 创建标签,标签边框宽度为0
la1.place(x=0,y=0) # 用place定位
 
la1.bind("<Double-Button-1>",exit) # 鼠标双击标签小狗绑定exit函数
 
root.overrideredirect(True) # 让窗体无标题栏
root.wm_attributes("-transparentcolor", "white") # 设置窗体白色透明
 
la1.bind("<Button-1>",MouseDown) # 鼠标按下绑定函数,决定可以移动窗体
la1.bind("<ButtonRelease-1>",MouseUp) # 鼠标抬起绑定函数,决定不能移动窗体
la1.bind("<B1-Motion>",MouseMove) # 鼠标按下并移动绑定函数,决定窗体移动到新的位置
 
root.mainloop()  # 源码来自wb86.com

运行后,就可以用鼠标移动小狗窗体,双击小狗就可以关闭窗体。

为无标题栏窗体增加右键弹出菜单

下面我为窗体增加弹出菜单代码,这样,用鼠标右键弹出菜单方式也可以退出窗体。全部代码如下

from tkinter import *
import webbrowser
def wb98():
    webbrowser.open('http://www.wb98.com',new=1)
 
def MouseDown(event):
    global moveYN # 是否可以移动窗体的全局变量
    global mousX  # 全局变量,鼠标在窗体内的x坐标
    global mousY  # 全局变量,鼠标在窗体内的y坐标
 
    moveYN=True    # 打开移动窗体的开关
    mousX=event.x  # 获取鼠标相对于窗体左上角的X坐标
    mousY=event.y  # 获取鼠标相对于窗左上角体的Y坐标
    
def MouseUp(event):
    moveYN=False   # 关闭移动窗体的开关
def MouseMove(event): 
    if moveYN==True: # 如果鼠标按下,就可以移动窗体到新的位置
        root.geometry(f'+{event.x_root - mousX}+{event.y_root - mousY}') 
def exit(event):
    root.destroy()  # 退出程序
def popup_menu(event):  # 弹出菜单代码
    popup.post(event.x_root,event.y_root) 
 
root=Tk()
root.geometry('132x103+888+444')  # 窗体的尺寸正好是图片小狗的图片
 
img1=PhotoImage(file='gou1.png') # 创建图片对像
la1=Label(root, image=img1,bd=0)  # 创建标签,标签边框宽度为0
la1.place(x=0,y=0) # 用place定位
 
la1.bind("<Double-Button-1>",exit) # 鼠标双击标签小狗绑定exit函数
 
root.overrideredirect(True) # 让窗体无标题栏
root.wm_attributes("-transparentcolor", "white") # 设置窗体白色透明
 
la1.bind("<Button-1>",MouseDown) # 鼠标按下绑定函数,决定可以移动窗体
la1.bind("<ButtonRelease-1>",MouseUp) # 鼠标抬起绑定函数,决定不能移动窗体
la1.bind("<B1-Motion>",MouseMove) # 鼠标按下并移动绑定函数,决定窗体移动到新的位置   
 
popup=Menu(root,tearoff=0) # 为弹出菜单创建菜单popup
popup.add_command(label='作者济亨网',command=wb98) # 创建菜单项
popup.add_command(label='退出',command=root.destroy) # 退出菜单项也可以退出程序
 
root.bind("<Button-3>",popup_menu) # 窗体鼠标右键绑定弹出菜单函数
 
root.mainloop()


运行程序,可以达到规划好的目的,基本上就做好了一个异形窗体的程序。

但我稍有些不满意,因为我是用下面代码设置窗体的尺寸为小狗的尺寸:

root.geometry('132x103+888+444')  # 窗体的尺寸正好是图片小狗的图片

这要先了解图像的尺寸,再来写代码,如果让程序来判断图像的尺寸行不行呢?当然行,我再在代码最后加入判断图像尺寸的代码,并注释掉窗体强形设置尺寸的代码。考虑到程序没有标题栏,在任务栏无法有图标,有时找不到程序界面,在程序开始时,就让程序界面置顶;程序在启动时,界面由默认位置移动到屏幕正中间,有一个闪动的过程,我在程序刚开始加入让窗体隐藏的代码,再到程序最后让隐藏的界面再显示,可以解决界面有闪动的情况。全部代码如下:

from tkinter import *
import webbrowser
def wb98():
    webbrowser.open('http://www.wb98.com',new=1)
 
def MouseDown(event):
    global moveYN # 是否可以移动窗体的全局变量
    global mousX  # 全局变量,鼠标在窗体内的x坐标
    global mousY  # 全局变量,鼠标在窗体内的y坐标
 
    moveYN=True    # 打开移动窗体的开关
    mousX=event.x  # 获取鼠标相对于窗体左上角的X坐标
    mousY=event.y  # 获取鼠标相对于窗左上角体的Y坐标
    
def MouseUp(event):
    moveYN=False   # 关闭移动窗体的开关
def MouseMove(event): 
    if moveYN==True: # 如果鼠标按下,就可以移动窗体到新的位置
        root.geometry(f'+{event.x_root - mousX}+{event.y_root - mousY}') 
def exit(event):
    root.destroy()  # 退出程序
def popup_menu(event):  # 弹出菜单代码
    popup.post(event.x_root,event.y_root) 
 
root=Tk()  # 源码来自wb98.com
root.withdraw()  # 让窗体隐藏一下
root.wm_attributes('-topmost',1)  # 让窗体置顶
 
# root.geometry('132x103+888+444')  # 窗体的尺寸正好是图片小狗的图片
 
img1=PhotoImage(file='gou1.png') # 创建图片对像
la1=Label(root, image=img1,bd=0)  # 创建标签,标签边框宽度为0
la1.place(x=0,y=0) # 用place定位
 
la1.bind("<Double-Button-1>",exit) # 鼠标双击标签小狗绑定exit函数
 
root.overrideredirect(True) # 让窗体无标题栏
root.wm_attributes("-transparentcolor", "white") # 设置窗体白色透明
 
la1.bind("<Button-1>",MouseDown) # 鼠标按下绑定函数,决定可以移动窗体
la1.bind("<ButtonRelease-1>",MouseUp) # 鼠标抬起绑定函数,决定不能移动窗体
la1.bind("<B1-Motion>",MouseMove) # 鼠标按下并移动绑定函数,决定窗体移动到新的位置   
 
popup=Menu(root,tearoff=0) # 为弹出菜单创建菜单popup
popup.add_command(label='作者济亨网',command=wb98) # 创建菜单项
popup.add_command(label='退出',command=root.destroy) # 退出菜单项也可以退出程序
 
root.bind("<Button-3>",popup_menu) # 窗体鼠标右键绑定弹出菜单函数
 
root.update() # 刷新窗体数据
 
a=la1.winfo_width() # 标签1的宽度
b=la1.winfo_height() # 标签1的高度
c=(root.winfo_screenwidth()-a)/2 # 居中显示的左边界
d=(root.winfo_screenheight()-b)/2 # 居中显示的上边界
root.geometry('%dx%d+%d+%d' % (a,b,c,d)) # 在屏幕居中显示
 
root.wm_deiconify()  # 让窗体显现
 
root.mainloop()


运行程序,达到了效果,大家可以反三,做其它形状的窗体界面。如下面的手机图。
sj.PNG

我们只需要改动2处代码就行了,1是把界面白色部分透明的代码,改成粉红(Fuchsia),或者用16进制 #FF00FF,改动代码为:

root.wm_attributes("-transparentcolor", "fuchsia") # 设置窗体粉色透明

或者

root.wm_attributes("-transparentcolor", "#FF00FF") # 设置窗体白色透明

第2处改动代码是创建图片对象代码,改file的文件名

img1=PhotoImage(file='sj.png') # 创建图片对象

 

我把代码改动后,运行结果 ,达到了预期的目的,大家可以试一下。也可以找别的图片来试一下。

此文章来自:wb98.com  网站还有相关的系列课程文章,感兴趣的可以前往。

 

 


来源:济亨网

本文链接:http://wb98.com/post/329.html

    << 上一篇 下一篇 >>

    湘公网安备 43011102000514号 - 湘ICP备08100508号