英文:
Inconsistent highlighting of default button under tkinter?
问题
以下是翻译好的内容:
以下Python模块旨在从任何基于tkinter的程序中使用,以在父窗口前弹出对话框。特别感兴趣的是askquestion,这是内置消息框版本的替代品,当需要时并不总是出现在顶部。请注意默认为“active”的Yes按钮。在Mac上运行时,这会产生一个漂亮的、类似Mac的蓝色按钮。但在Ubuntu上运行时,绝对没有突出显示,告诉用户它是默认按钮。 Mac版本:
Linux版本:
这是否正确?这是否是一个错误?是否有一些参数我可以在某处更改以改善情况?而且,说到这一点,Linux式的指示默认按钮的方式是什么?
import tkinter as tk
from tkinter import ttk
from tkinter.font import Font
# 此模块的存在是为了解决消息框弹出在子窗口上时通常会在顶级窗口上方弹出的问题,尤其在Linux下会出现这种情况。
messageFont = None
def pop(parent, width, height, title=""):
'''返回一个打开的窗口,位于父窗口中央,等待您添加内容。
当您完成后,使用child.destroy()来关闭它。'''
global messageFont
if not messageFont:
messageFont = Font(root=parent, size=16)
corner = (parent.winfo_x(), parent.winfo_y())
size = (parent.winfo_width(), parent.winfo_height())
popSize = (width, height)
popCorner = sub(add(corner, div(size, 2)), div(popSize, 2))
child= tk.Toplevel(parent)
child.attributes("-topmost", True)
geometry = f"{width}x{height}+{int(popCorner[0])}+{int(popCorner[1])}"
print(popCorner,geometry)
child.geometry(f"{width}x{height}+{int(popCorner[0])}+{int(popCorner[1])}")
child.title(title)
return child
def askquestion(parent, question, action, title=""):
def onPress(yesNo):
child.destroy()
action(yesNo)
child = pop(parent, 500, 250, title=title)
frame = ttk.Frame(child)
frame.pack(fill=tk.BOTH, expand="y")
ttk.Label(frame, text=question, font=messageFont).pack(pady=(80,0))
buttons = ttk.Frame(frame)
buttons.pack()
ttk.Button(buttons, text="No", command=lambda: onPress(False)).pack(side=tk.LEFT)
ttk.Button(buttons, text="Yes", command=lambda: onPress(True),
default="active").pack(side=tk.LEFT)
child.bind("<Escape>", lambda _event: onPress(False))
child.bind("<Return>", lambda _event: onPress(True))
# 基本矢量运算
def add(v1, v2):
return (v1[0] + v2[0], v1[1] + v2[1])
def sub(v1, v2):
return (v1[0] - v2[0], v1[1] - v2[1])
def mul(v1, c):
return (v1[0] * c, v1[1] * c)
def div(v1, c):
return (v1[0] / c, v1[1] / c)
if __name__ == "__main__":
root = tk.Tk()
root.geometry("640x480")
root.update_idletasks()
askquestion(root, "Are you awake?", lambda yesNo: print(yesNo))
root.mainloop()
英文:
The following Python module is designed to be used from any tkinter-based program, to pop up a dialog in front of the parent window. Of particular interest is askquestion, a substitute for the built-in messagebox version which doesn't always appear on top when it needs to. Note the Yes button, which has default="active". When run on Mac, this produces a nice, Mac like blue color to the button. When run on Ubuntu, there is absolutely no highlight to tell the user that it is the default button. Mac version:
Linux version:
Is this right? Is this a bug? Is there some parameter I might change somewhere to improve the situation? And for that matter, what is the Linux-like way to indicate a default button?
import tkinter as tk
from tkinter import ttk
from tkinter.font import Font
# This module exists to solve a problem that messagebox popups
# invoked over a child window tend to pop up over the top-level window
# instead under Linux.
messageFont = None
def pop(parent, width, height, title=""):
'''Returns an open window centered over parent waiting for you to add content.
Use child.destroy() to get rid of it when you are finished with it.'''
global messageFont
if not messageFont:
messageFont = Font(root=parent, size=16)
corner = (parent.winfo_x(), parent.winfo_y())
size = (parent.winfo_width(), parent.winfo_height())
popSize = (width, height)
popCorner = sub(add(corner, div(size, 2)), div(popSize, 2))
child= tk.Toplevel(parent)
child.attributes("-topmost", True)
geometry = f"{width}x{height}+{int(popCorner[0])}+{int(popCorner[1])}"
print(popCorner,geometry)
child.geometry(f"{width}x{height}+{int(popCorner[0])}+{int(popCorner[1])}")
child.title(title)
return child
def askquestion(parent, question, action, title=""):
def onPress(yesNo):
child.destroy()
action(yesNo)
child = pop(parent, 500, 250, title=title)
frame = ttk.Frame(child)
frame.pack(fill=tk.BOTH, expand="y")
ttk.Label(frame, text=question, font=messageFont).pack(pady=(80,0))
buttons = ttk.Frame(frame)
buttons.pack()
ttk.Button(buttons, text="No", command=lambda: onPress(False)).pack(side=tk.LEFT)
ttk.Button(buttons, text="Yes", command=lambda: onPress(True),
default="active").pack(side=tk.LEFT)
child.bind("<Escape>", lambda _event: onPress(False))
child.bind("<Return>", lambda _event: onPress(True))
# basic vector arithmetic
def add(v1, v2):
return (v1[0] + v2[0], v1[1] + v2[1])
def sub(v1, v2):
return (v1[0] - v2[0], v1[1] - v2[1])
def mul(v1, c):
return (v1[0] * c, v1[1] * c)
def div(v1, c):
return (v1[0] / c, v1[1] / c)
if __name__ == "__main__":
root = tk.Tk()
root.geometry("640x480")
root.update_idletasks()
askquestion(root, "Are you awake?", lambda yesNo: print(yesNo))
root.mainloop()
答案1
得分: 2
default
受 tkinter 按钮支持,但不受 ttk.Button
支持。它在 macOS 上运行的事实是偶然的。
您可以尝试返回使用 tkinter.Button
,或以不同方式样式化您的按钮。
链接:https://anzeljg.github.io/rin2/book2/2405/docs/tkinter/ttk-Button.html
英文:
default
is supported by tkinter Buttons, but not by ttk.Button
. The fact that it works in MacOS is an accident.
You can try going back to tkinter.Button
, or you can styling your button in a different way.
https://anzeljg.github.io/rin2/book2/2405/docs/tkinter/ttk-Button.html
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论