【问题标题】:How to remove minimize/maximize buttons while preserving the icon?如何在保留图标的同时删除最小化/最大化按钮?
【发布时间】:2018-05-28 08:36:00
【问题描述】:

删除最小化和最大化按钮后是否可以显示我的toplevelroot 窗口的图标?我尝试使用-toolwindow,但之后图标无法显示。有没有其他方法可以在仍然显示图标的同时从窗口中删除最小和最大尺寸按钮?

from tkinter import *


def top():
    tp = Toplevel()
    tp.geometry("300x300")
    tp.attributes("-toolwindow", 1)
    tp.iconbitmap("My icon.ico")


root = Tk()
root.geometry("400x400")

b = Button(root, text="open window with icon", command=top).pack()

root.mainloop()

【问题讨论】:

  • “按原样”这是不可能的,因为工具窗口不使用图标。您需要直接使用窗口管理器和styling,但是,没有适用于所有系统的通用解决方案。
  • @CommonSense 感谢您的回复,我通过执行此“tp.WS_ICONIC()”检查了样式,但出现此错误:AttributeError: 'Toplevel' object has no attribute 'WS_ICONIC'
  • 这比你想象的要复杂,但我发布了我的答案!

标签: python tkinter toplevel


【解决方案1】:

Windows 专用解决方案

第一个选项是为root 窗口设置toplevel 窗口transient,这是really simple 解决方案。
您需要做的就是将行 tp.attributes("-toolwindow", 1) 更改为 tp.transient(root)

第二个选项更复杂,但在 Windows 系统中更通用。
Windows 系统中的每个窗口都有自己的样式,表示为logical disjunctionbit-styles。您可以从头开始构建新样式,或将新样式设置为具有位样式的旧样式的 disjunction(以将其打开)或使用位样式的 negation 设置为旧样式的 conjunction (将其关闭):

  • 要关闭最小化/最大化:
    new style = old style AND NOT Maximize AND NOT Minimize
  • 开启最小化/最大化:
    new style = old style OR Maximize OR Minimize

对于所有这些交互,我们需要ctypes 库(python 附带)和一组 WinAPI 函数:

检查这个例子:

import tkinter as tk
import ctypes

#   shortcuts to the WinAPI functionality
set_window_pos = ctypes.windll.user32.SetWindowPos
set_window_long = ctypes.windll.user32.SetWindowLongPtrW
get_window_long = ctypes.windll.user32.GetWindowLongPtrW
get_parent = ctypes.windll.user32.GetParent

#   some of the WinAPI flags
GWL_STYLE = -16

WS_MINIMIZEBOX = 131072
WS_MAXIMIZEBOX = 65536

SWP_NOZORDER = 4
SWP_NOMOVE = 2
SWP_NOSIZE = 1
SWP_FRAMECHANGED = 32


def hide_minimize_maximize(window):
    hwnd = get_parent(window.winfo_id())
    #   getting the old style
    old_style = get_window_long(hwnd, GWL_STYLE)
    #   building the new style (old style AND NOT Maximize AND NOT Minimize)
    new_style = old_style & ~ WS_MAXIMIZEBOX & ~ WS_MINIMIZEBOX
    #   setting new style
    set_window_long(hwnd, GWL_STYLE, new_style)
    #   updating non-client area
    set_window_pos(hwnd, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED)


def show_minimize_maximize(window):
    hwnd = get_parent(window.winfo_id())
    #   getting the old style
    old_style = get_window_long(hwnd, GWL_STYLE)
    #   building the new style (old style OR Maximize OR Minimize)
    new_style = old_style | WS_MAXIMIZEBOX | WS_MINIMIZEBOX
    #   setting new style
    set_window_long(hwnd, GWL_STYLE, new_style)
    #   updating non-client area
    set_window_pos(hwnd, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED)


def top():
    tp = tk.Toplevel()
    #   tp.geometry('300x300')
    #   tp.iconbitmap('icon.ico')

    hide_minmax = tk.Button(tp, text='hide minimize/maximize', command=lambda: hide_minimize_maximize(tp))
    hide_minmax.pack()

    show_minmax = tk.Button(tp, text='show minimize/maximize', command=lambda: show_minimize_maximize(tp))
    show_minmax.pack()

root = tk.Tk()
root.geometry('400x400')
b = tk.Button(root, text='open window with icon', command=top)
b.pack()

root.mainloop()

【讨论】:

  • 这会创建 2 个窗口。如果我只想要一个怎么办?如何删除主窗口中的最小化/最大化按钮?
【解决方案2】:

我刚刚碰到这个问题,发现root.resizable(False, False)root.geometry之后解决了。

【讨论】:

    【解决方案3】:
    root.protocol("WM_DELETE_WINDOW", False)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-04-06
      • 2015-05-02
      • 2011-02-27
      • 2011-02-09
      • 1970-01-01
      • 1970-01-01
      • 2012-01-10
      相关资源
      最近更新 更多