tkinter最大化 的一些小BUG(五)

上一篇有点小BUG,就是最大化时把状态栏给遮挡了,所以在最大化时调整一下窗体大小。

鼠标在按钮上移动时窗体也跟着移动,要过滤一下事件。

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, name='icon_canvas_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):
        if str(e.widget).endswith('.') or str(e.widget).endswith('bar'):
            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)
        else:
            self.configure(cursor='arrow')

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

    def on_motion(self, e):
        if str(e.widget).endswith('.') or str(e.widget).endswith('bar'):
            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')
        windll.user32.MoveWindow(self.hwnd, 0, 0, self.ww + 1, self.wh + 1, True)


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

### 调整CiteSpace界面大小的方法 对于希望调整CiteSpace窗口或视图大小的情况,具体操作取决于操作系统环境以及应用程序本身的特性。 在Mac环境中,如果遇到CiteSpace窗口难以调整的问题,可能是因为应用默认打开了全屏模式或是窗口尺寸被固定。此时可以通过点击屏幕顶部的应用程序名称下拉菜单中的“进入全屏”选项来切换显示模式[^2]。另外,在非全屏状态下,通过拖动窗口四角也可以改变其大小;若发现此方式不起作用,则可能是由于特定版本软件存在的Bug所致。 针对Windows平台下的用户来说,通常情况下只需将鼠标指针移至窗口边缘直至光标变为双向箭头形状后再按住并拖拽即可完成对窗口大小的手动调节。此外,右上角的缩放按钮同样支持快速最大化/还原窗体的操作[^1]。 值得注意的是,当面对图形化界面内的具体内容(如图表、地图等)时,部分区域提供了独立于整体框架之外的放大缩小工具条,利用这些控件能够更精细地控制所关注对象的比例尺效果[^3]。 ```python # Python代码仅作为示例展示,并不适用于实际修改CiteSpace设置 import tkinter as tk root = tk.Tk() frame = tk.Frame(root, width=800, height=600) frame.pack(fill='both', expand=True) def resize_window(): root.geometry('1000x700') # 修改为期望的新尺寸 button = tk.Button(frame, text="Resize Window", command=resize_window) button.place(relx=.5, rely=.5, anchor="center") root.mainloop() ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值