欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

如何實(shí)現(xiàn)Python編寫的圖形界面可以自由拖動(dòng)

 更新時(shí)間:2024年11月15日 08:51:03   作者:PythonFun  
我們使用python中的tkinter進(jìn)行編程時(shí),往往需要一種功能就是我們可以隨意拖動(dòng)這個(gè)界面,放置在任何位置,下面我們就來看看Python如何實(shí)現(xiàn)這一效果吧

一、問題的提出

我們使用python中的tkinter進(jìn)行編程時(shí),往往需要一種功能就是我們可以隨意拖動(dòng)這個(gè)界面,放置在任何位置,而不是只能拖動(dòng)標(biāo)題欄,這樣使我們的程序用起來更加便捷和絲滑。

二、問題分析

如果要實(shí)現(xiàn)這種方法,我們可以定義函數(shù),也可以做一個(gè)裝飾器,到時(shí)相當(dāng)于給我們的程序添加了一個(gè)新的功能一樣,這樣的邏輯就更好理解了。

三、問題的解決

1. 直接用函數(shù)的方法

這種方法是最原始的,我們可以直接把它加入到以函數(shù)寫法的程序中,通過定義兩個(gè)函數(shù),包括on_drag_start和on_drag_motion,通過獲取鼠標(biāo)的新位置,來實(shí)現(xiàn)界面的位置移動(dòng)。

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)
 
# 添加一個(gè)示例控件
button = tk.Button(root, text="按鈕")
button.pack(pady=20)
 
label = tk.Label(root, text="移動(dòng)窗口")
label.pack(pady=20)
 
root.mainloop()

2. 通過裝飾器來實(shí)現(xiàn)

雖然函數(shù)的方法就可以實(shí)現(xiàn),那么我們可以把這兩個(gè)函數(shù)放在裝飾器里面,調(diào)用時(shí)用@函數(shù)名就可以了。在下面的代碼中,我們定義了一個(gè)draggable_window這個(gè)裝飾器,可以用于為函數(shù)添加新的功能。我們create_window()前面添加了@draggable_window,這樣就可以為新窗口添加新功能了。

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="移動(dòng)窗口")
    label.pack(pady=20)
 
    return root
 
# 啟動(dòng)窗口
root = create_window()
root.mainloop()

DraggableWindow 類封裝了窗口的創(chuàng)建、拖動(dòng)功能和控件的添加。

on_drag_start 和 on_drag_motion 方法分別處理拖動(dòng)的起點(diǎn)和拖動(dòng)過程。

add_widgets 方法用于向窗口添加按鈕和標(biāo)簽。

run 方法啟動(dòng) mainloop(),以顯示窗口。

3. 把裝飾器寫成類去裝飾另一個(gè)程序添加新功能

我們還可以定義完裝飾器后放入一個(gè)類中,直接去修飾另一個(gè)類,代碼如下,注意裝飾器的位置。這樣的寫法邏輯分明,條理清楚,不想使用這個(gè)拖動(dòng)這個(gè)功能,直接刪除裝飾器的類,就可以了。

import tkinter as tk
 
# 定義拖動(dòng)功能的裝飾器
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
 
        # 將拖動(dòng)事件綁定到窗口
        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="移動(dòng)窗口")
        label.pack(pady=20)
 
    def run(self):
        self.root.mainloop()
 
# 啟動(dòng)窗口
app = DraggableWindow()
app.run()

上面代碼中,draggable 裝飾器應(yīng)用到類的 __init__ 方法上,這樣在類實(shí)例化時(shí),窗口會(huì)自動(dòng)綁定拖動(dòng)事件。

裝飾器內(nèi)部通過 self.root.bind 綁定拖動(dòng)功能。

這樣封裝后,拖動(dòng)功能的邏輯被封裝在裝飾器中,類的代碼保持清晰簡(jiǎn)潔。

三、學(xué)后總結(jié)

1. 未來在編程中,常用的功能貌似都可以包裝成一個(gè)裝飾器或者一個(gè)可以調(diào)用的模塊的形式,這樣實(shí)現(xiàn)主程序和一些功能性的組件分離,修改、調(diào)試程序就更加方便。

2. 今天的學(xué)習(xí)中,從單個(gè)的函數(shù)實(shí)現(xiàn),到簡(jiǎn)單的裝飾器以及類裝飾器的實(shí)現(xiàn),復(fù)雜程度進(jìn)一步提升,應(yīng)用的邏輯也更多加清晰。

3. 學(xué)習(xí)Python是一個(gè)認(rèn)識(shí)不斷加深的過程,像裝飾器這樣難理解的概念,如果單純從文字上理解比較困難,可以放在小項(xiàng)目中,逐步消化,增進(jìn)理解。

到此這篇關(guān)于如何實(shí)現(xiàn)Python編寫的圖形界面可以自由拖動(dòng)的文章就介紹到這了,更多相關(guān)Python圖形界面自由拖動(dòng)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Python3從零開始搭建一個(gè)語音對(duì)話機(jī)器人的實(shí)現(xiàn)

    Python3從零開始搭建一個(gè)語音對(duì)話機(jī)器人的實(shí)現(xiàn)

    這篇文章主要介紹了Python3從零開始搭建一個(gè)語音對(duì)話機(jī)器人的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • Python登錄QQ郵箱發(fā)送郵件的實(shí)現(xiàn)示例

    Python登錄QQ郵箱發(fā)送郵件的實(shí)現(xiàn)示例

    本文主要介紹了Python登錄QQ郵箱發(fā)送郵件的實(shí)現(xiàn)示例,主要就是三步,登錄郵件、寫郵件內(nèi)容、發(fā)送,文中通過示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧<BR>
    2023-08-08
  • Python+Socket實(shí)現(xiàn)基于TCP協(xié)議的客戶與服務(wù)端中文自動(dòng)回復(fù)聊天功能示例

    Python+Socket實(shí)現(xiàn)基于TCP協(xié)議的客戶與服務(wù)端中文自動(dòng)回復(fù)聊天功能示例

    這篇文章主要介紹了Python+Socket實(shí)現(xiàn)基于TCP協(xié)議的客戶與服務(wù)端中文自動(dòng)回復(fù)聊天功能,結(jié)合實(shí)例形式分析了Python+Socket實(shí)現(xiàn)帶自動(dòng)回復(fù)功能的TCP聊天程序相關(guān)操作方法與注意事項(xiàng),需要的朋友可以參考下
    2017-08-08
  • 詳細(xì)一文帶你分清Python中的模塊、包和庫

    詳細(xì)一文帶你分清Python中的模塊、包和庫

    這篇文章主要介紹了詳細(xì)一文帶你分清Python中的模塊、包和庫,Python?模塊(Module),是一個(gè)?Python?文件,以?.py?結(jié)尾,包含了?Python?對(duì)象定義和Python語句,模塊能定義函數(shù),類和變量,模塊也能包含可執(zhí)行的代碼,需要的朋友可以參考下
    2023-08-08
  • 淺談python圖片處理Image和skimage的區(qū)別

    淺談python圖片處理Image和skimage的區(qū)別

    這篇文章主要介紹了淺談python圖片處理Image和skimage的區(qū)別,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • Python實(shí)現(xiàn)的NN神經(jīng)網(wǎng)絡(luò)算法完整示例

    Python實(shí)現(xiàn)的NN神經(jīng)網(wǎng)絡(luò)算法完整示例

    這篇文章主要介紹了Python實(shí)現(xiàn)的NN神經(jīng)網(wǎng)絡(luò)算法,結(jié)合完整實(shí)例形式分析了Python使用numpy、matplotlib及sklearn模塊實(shí)現(xiàn)NN神經(jīng)網(wǎng)絡(luò)相關(guān)算法實(shí)現(xiàn)技巧與操作注意事項(xiàng),需要的朋友可以參考下
    2018-06-06
  • python線程啟動(dòng)的四種方式總結(jié)

    python線程啟動(dòng)的四種方式總結(jié)

    這篇文章主要給大家介紹了關(guān)于python線程啟動(dòng)的四種方式,線程可以完成一定任務(wù),可以和其它線程共享父進(jìn)程的共享變量和部分環(huán)境,相互協(xié)作來完成任務(wù),需要的朋友可以參考下
    2024-01-01
  • django站點(diǎn)管理詳解

    django站點(diǎn)管理詳解

    這篇文章主要介紹了django站點(diǎn)管理詳解,具有一定借鑒價(jià)值,需要的朋友可以參考下。
    2017-12-12
  • 深人了解Python上下文管理器

    深人了解Python上下文管理器

    這篇文章主要為大家介紹了Python上下文管理器,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助<BR>
    2021-12-12
  • Python中基礎(chǔ)數(shù)據(jù)類型 set集合知識(shí)點(diǎn)總結(jié)

    Python中基礎(chǔ)數(shù)據(jù)類型 set集合知識(shí)點(diǎn)總結(jié)

    在本篇文章里小編給大家總結(jié)了一篇關(guān)于Python中基礎(chǔ)數(shù)據(jù)類型 set集合知識(shí)點(diǎn)總結(jié)內(nèi)容,有需要的朋友們可以學(xué)習(xí)下。
    2021-08-08

最新評(píng)論