tkinter无边框最大化、最小化、关闭按钮(四)

部署运行你感兴趣的模型镜像

当然,可以缩放和移动后总要有最小化、最大化、关闭按钮,还要有图标和标题,这才是完整的窗口嘛~

用到了pillow,记得安装一下

from tkinter import Tk, Frame, Label, Button, Canvas
from ctypes import Structure, c_long, windll, byref
from PIL import Image, ImageTk


class RECT(Structure):
    _fields_ = [("left", c_long), ("top", c_long), ("right", c_long), ("bottom", c_long)]


SPI_GETWORKAREA = 48
GWL_STYLE = -16  # 用于获取窗口样式
WS_CAPTION = 12582912  # 窗口标题栏样式
WS_THICKFRAME = 262144  # 窗口可调整边框样式

WM_SYSCOMMAND = 274
SC_SIZE = 61440
SC_MOVE = 61456
HTCAPTION = 2
WMSZ_LEFT = 1
WMSZ_RIGHT = 2
WMSZ_TOP = 3
WMSZ_TOPLEFT = 4
WMSZ_TOPRIGHT = 5
WMSZ_BOTTOM = 6
WMSZ_BOTTOMLEFT = 7
WMSZ_BOTTOMRIGHT = 8


class WindowTk(Tk):
    def __init__(self, icon='logo.ico', name='TK窗体', width=1000, height=600, min_w=600, min_h=400):
        super().__init__()
        self.margin = 10
        self.bg_color = 'white'
        self.head_height = 30
        '''居中显示'''
        work_rect = RECT()
        windll.user32.SystemParametersInfoW(SPI_GETWORKAREA, 0, byref(work_rect), 0)
        self.ww = work_rect.right - work_rect.left
        self.wh = work_rect.bottom - work_rect.top
        size = '%dx%d+%d+%d' % (width, height, (self.ww - width) / 2, (self.wh - height) / 2)
        self.geometry(size)
        self.iconbitmap(icon)
        self.title(name)
        self.minsize(min_w, min_h)
        self.configure(bg=self.bg_color)
        '''无边框'''
        self.update_idletasks()  # 刷新窗口状态
        self.hwnd = windll.user32.GetParent(self.winfo_id())  # 获取窗口句柄
        style = windll.user32.GetWindowLongPtrW(self.hwnd, GWL_STYLE)
        style &= ~(WS_CAPTION | WS_THICKFRAME)
        windll.user32.SetWindowLongPtrW(self.hwnd, GWL_STYLE, style)
        '''标题栏'''
        title_bar = Frame(self, name='title_bar', bg=self.bg_color, height=self.head_height)
        title_bar.pack(fill='x', padx=self.margin, pady=5)
        icon_canvas = Canvas(title_bar, highlightthickness=0, bg=self.bg_color, width=self.head_height,
                             height=self.head_height)
        icon_canvas.pack(side='left', fill='y')
        title_label = Label(title_bar, bg=self.bg_color, name='name_bar', text=name, font=("Microsoft YaHei", 10))
        title_label.pack(side='left', fill='y')
        button = Button(title_bar, text="关闭", command=self.destroy)
        button.pack(side='right')
        button = Button(title_bar, text="最大化", command=self.max_win)
        button.pack(side='right')
        button = Button(title_bar, text="最小化", command=self.min_win)
        button.pack(side='right')
        ico_h = 24
        ico = Image.open(icon).resize((ico_h, ico_h))
        ico = ImageTk.PhotoImage(ico)
        icon_canvas.create_image((self.head_height - ico_h) / 2, (self.head_height - ico_h) / 2, anchor="nw", image=ico)
        icon_canvas.image = ico  # 防止垃圾回收

        '''窗体事件'''
        self.action = None
        self.direction = None
        self.bind("<Motion>", self.move)
        self.bind("<B1-Motion>", self.on_motion)

    def move(self, e):
        x = e.x_root - self.winfo_x()
        y = e.y_root - self.winfo_y()
        if x <= self.margin and y <= self.margin:
            self.set_cursor('@C:/Windows/Cursors/aero_nwse.cur', SC_SIZE, WMSZ_TOPLEFT)
        elif self.winfo_width() - 1 - self.margin > x > self.margin > y:
            self.set_cursor('sb_v_double_arrow', SC_SIZE, WMSZ_TOP)
        elif self.winfo_width() - 1 - self.margin <= x and y <= self.margin:
            self.set_cursor('@C:/Windows/Cursors/aero_nesw.cur', SC_SIZE, WMSZ_TOPRIGHT)
        elif self.winfo_width() - 1 - self.margin < x and self.margin < y < self.winfo_height() - 1 - self.margin:
            self.set_cursor('sb_h_double_arrow', SC_SIZE, WMSZ_RIGHT)
        elif self.winfo_width() - 1 - self.margin <= x and self.winfo_height() - 1 - self.margin <= y:
            self.set_cursor('@C:/Windows/Cursors/aero_nwse.cur', SC_SIZE, WMSZ_BOTTOMRIGHT)
        elif self.margin < x < self.winfo_width() - 1 - self.margin and self.winfo_height() - 1 - self.margin < y:
            self.set_cursor('sb_v_double_arrow', SC_SIZE, WMSZ_BOTTOM)
        elif x <= self.margin and self.winfo_height() - 1 - self.margin <= y:
            self.set_cursor('@C:/Windows/Cursors/aero_nesw.cur', SC_SIZE, WMSZ_BOTTOMLEFT)
        elif x < self.margin < y < self.winfo_height() - 1 - self.margin:
            self.set_cursor('sb_h_double_arrow', SC_SIZE, WMSZ_LEFT)
        else:
            self.set_cursor('arrow', SC_MOVE, HTCAPTION)

    def set_cursor(self, cursor, action, direction):
        self.configure(cursor=cursor)
        self.action = action
        self.direction = direction

    def on_motion(self, e):
        windll.user32.ReleaseCapture()
        windll.user32.SendMessageW(self.hwnd, WM_SYSCOMMAND, self.action | self.direction, 0)

    def min_win(self):
        self.state("icon")

    def max_win(self):
        if self.wm_state() == 'zoomed':
            self.state('normal')
            return
        self.state('zoomed')


if __name__ == '__main__':
    root = WindowTk()
    root.mainloop()

ok~

当然 按钮没有美化,还是原生按钮,等后续在美化

您可能感兴趣的与本文相关的镜像

Python3.10

Python3.10

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

PythonTkinter库中,要实现只保留最小化关闭按钮,而删除最大化按钮,可以通过设置窗口的`attributes`方法来实现。具体步骤如下: 1. 创建一个Tkinter窗口。 2. 使用`attributes`方法设置窗口属性,移除最大化按钮。 以下是一个示例代码,展示了如何实现这个功能: ```python import tkinter as tk def create_window(): root = tk.Tk() root.title("示例窗口") # 设置窗口大小 root.geometry("400x300") # 移除最大化按钮 root.attributes("-toolwindow", True) root.resizable(0, 0) # 运行主循环 root.mainloop() if __name__ == "__main__": create_window() ``` 在这个示例中,`root.attributes("-toolwindow", True)`用于创建一个工具窗口,这种窗口通常只有关闭按钮最小化按钮。`root.resizable(0, 0)`用于禁用窗口的大小调整功能。 如果你需要更精确地控制窗口按钮,可以使用`ctypes`库来调用Windows API: ```python import tkinter as tk import ctypes import sys def create_window(): root = tk.Tk() root.title("示例窗口") # 设置窗口大小 root.geometry("400x300") if sys.platform.startswith('win'): # 移除最大化按钮 HWND = ctypes.windll.user32.GetParent(root.winfo_id()) GWL_STYLE = -16 WS_MAXIMIZEBOX = 0x00010000 style = ctypes.windll.user32.GetWindowLongW(HWND, GWL_STYLE) style &= ~WS_MAXIMIZEBOX ctypes.windll.user32.SetWindowLongW(HWND, GWL_STYLE, style) # 运行主循环 root.mainloop() if __name__ == "__main__": create_window() ``` 在这个示例中,`ctypes`库用于调用Windows API来修改窗口样式,从而移除最大化按钮。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值