如何实现Python编写的图形界面可以自由拖动!

如何实现Python编写的图形界面可以自由拖动!

我们使用python中的tkinter进行编程时,往往需要一种功能就是我们可以随意拖动这个界面,放置在任何位置,下面我们就来看看Python如何实现这一效果吧。

一、问题的提出

我们使用python中的tkinter进行编程时,往往需要一种功能就是我们可以随意拖动这个界面,放置在任何位置,而不是只能拖动标题栏,这样使我们的程序用起来更加便捷和丝滑。

二、问题分析

如果要实现这种方法,我们可以定义函数,也可以做一个装饰器,到时相当于给我们的程序添加了一个新的功能一样,这样的逻辑就更好理解了。

三、问题的解决

1. 直接用函数的方法

这种方法是最原始的,我们可以直接把它加入到以函数写法的程序中,通过定义两个函数,包括on_drag_start和on_drag_motion,通过获取鼠标的新位置,来实现界面的位置移动。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import tkinter as tk
def on_drag_start(event):
global x_start, y_start
x_start = event.x_root
y_start = event.y_root
def on_drag_motion(event):
global x_start, y_start
delta_x = event.x_root - x_start
delta_y = event.y_root - y_start
x_new = root.winfo_x() + delta_x
y_new = root.winfo_y() + delta_y
root.geometry(f"+{x_new}+{y_new}")
x_start = event.x_root
y_start = event.y_root
root = tk.Tk()
root.geometry("400x300")
# 仅将事件处理程序绑定到根窗口的背景上
root.bind('<Button-1>', on_drag_start)
root.bind('<B1-Motion>', on_drag_motion)
# 添加一个示例控件
button = tk.Button(root, text="按钮")
button.pack(pady=20)
label = tk.Label(root, text="移动窗口")
label.pack(pady=20)
root.mainloop()

2. 通过装饰器来实现

虽然函数的方法就可以实现,那么我们可以把这两个函数放在装饰器里面,调用时用@函数名就可以了。在下面的代码中,我们定义了一个draggable_window这个装饰器,可以用于为函数添加新的功能。我们create_window()前面添加了@draggable_window,这样就可以为新窗口添加新功能了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import tkinter as tk
def draggable_window(func):
def wrapper(*args, **kwargs):
root = func(*args, **kwargs)
def on_drag_start(event):
root.x_start = event.x_root
root.y_start = event.y_root
def on_drag_motion(event):
delta_x = event.x_root - root.x_start
delta_y = event.y_root - root.y_start
x_new = root.winfo_x() + delta_x
y_new = root.winfo_y() + delta_y
root.geometry(f"+{x_new}+{y_new}")
root.x_start = event.x_root
root.y_start = event.y_root
root.bind('<Button-1>', on_drag_start)
root.bind('<B1-Motion>', on_drag_motion)
return root
return wrapper
@draggable_window
def create_window():
root = tk.Tk()
root.geometry("400x300")
# 添加控件
button = tk.Button(root, text="按钮")
button.pack(pady=20)
label = tk.Label(root, text="移动窗口")
label.pack(pady=20)
return root
# 启动窗口
root = create_window()
root.mainloop()

DraggableWindow 类封装了窗口的创建、拖动功能和控件的添加。

on_drag_start 和 on_drag_motion 方法分别处理拖动的起点和拖动过程。

add_widgets 方法用于向窗口添加按钮和标签。

run 方法启动 mainloop(),以显示窗口。

3. 把装饰器写成类去装饰另一个程序添加新功能

我们还可以定义完装饰器后放入一个类中,直接去修饰另一个类,代码如下,注意装饰器的位置。这样的写法逻辑分明,条理清楚,不想使用这个拖动这个功能,直接删除装饰器的类,就可以了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import tkinter as tk
# 定义拖动功能的装饰器
def draggable(func):
def wrapper(self, *args, **kwargs):
func(self, *args, **kwargs)
def on_drag_start(event):
self.x_start = event.x_root
self.y_start = event.y_root
def on_drag_motion(event):
delta_x = event.x_root - self.x_start
delta_y = event.y_root - self.y_start
x_new = self.root.winfo_x() + delta_x
y_new = self.root.winfo_y() + delta_y
self.root.geometry(f"+{x_new}+{y_new}")
self.x_start = event.x_root
self.y_start = event.y_root
# 将拖动事件绑定到窗口
self.root.bind('<Button-1>', on_drag_start)
self.root.bind('<B1-Motion>', on_drag_motion)
return wrapper
class DraggableWindow:
@draggable
def __init__(self):
self.root = tk.Tk()
self.root.geometry("400x300")
# 添加控件
self.add_widgets()
def add_widgets(self):
button = tk.Button(self.root, text="按钮")
button.pack(pady=20)
label = tk.Label(self.root, text="移动窗口")
label.pack(pady=20)
def run(self):
self.root.mainloop()
# 启动窗口
app = DraggableWindow()
app.run()

上面代码中,draggable 装饰器应用到类的 __init__ 方法上,这样在类实例化时,窗口会自动绑定拖动事件。

装饰器内部通过 self.root.bind 绑定拖动功能。

这样封装后,拖动功能的逻辑被封装在装饰器中,类的代码保持清晰简洁。

三、学后总结

1. 未来在编程中,常用的功能貌似都可以包装成一个装饰器或者一个可以调用的模块的形式,这样实现主程序和一些功能性的组件分离,修改、调试程序就更加方便。

2. 今天的学习中,从单个的函数实现,到简单的装饰器以及类装饰器的实现,复杂程度进一步提升,应用的逻辑也更多加清晰。

3. 学习Python是一个认识不断加深的过程,像装饰器这样难理解的概念,如果单纯从文字上理解比较困难,可以放在小项目中,逐步消化,增进理解。

到此这篇关于如何实现Python编写的图形界面可以自由拖动的文章就介绍到这了。

 

 

学习资料见知识星球。

以上就是今天要分享的技巧,你学会了吗?若有什么问题,欢迎在下方留言。

快来试试吧,小琥 my21ke007。获取 1000个免费 Excel模板福利​​​​!

更多技巧, www.excelbook.cn

欢迎 加入 零售创新 知识星球,知识星球主要以数据分析、报告分享、数据工具讨论为主;

Excelbook.cn Excel技巧 SQL技巧 Python 学习!

你将获得:

1、价值上万元的专业的PPT报告模板。

2、专业案例分析和解读笔记。

3、实用的Excel、Word、PPT技巧。

4、VIP讨论群,共享资源。

5、优惠的会员商品。

6、一次付费只需99元,即可下载本站文章涉及的文件和软件。

文章版权声明 1、本网站名称:Excelbook
2、本站永久网址:http://www.excelbook.cn
3、本网站的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,请联系站长王小琥进行删除处理。
4、本站一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
5、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报。
6、本站资源大多存储在云盘,如发现链接失效,请联系我们我们会第一时间更新。

THE END
分享
二维码
< <上一篇
下一篇>>