带有定时按钮的消息框,外观类似messagebox.showwarn()

0 投票
1 回答
24 浏览
提问于 2025-04-13 17:07

我参考了这个链接上最受欢迎的答案:MessageBox pause - Python,想做一个对话框,里面有一个定时的“确定”按钮。不过,这个对话框看起来挺简陋的,我希望它能像标准的messagebox.showwarn()那样好看,还能利用“detail”这个参数。

我遇到的问题是,消息框似乎不太适合被修改或自定义。我还尝试用ttkbootstrap把Icon.warn放进一个标签里,但结果只是把我所有的按钮都变成了蓝色,图标根本没显示出来。而且,我不想再用其他库来显示警告图标,因为我的脚本已经很臃肿了。

有没有什么实际的方法可以:

  1. 对messagebox.Message对象进行子类化,让它的“确定”按钮在可以点击之前有个暂停时间,并且让它看起来像个警告消息框;或者

  2. 继续使用Saad的答案,子类化一个simpledialog,但让它看起来更像一个警告消息框,包括警告图标和详细信息。

1 个回答

0

你可以对Saad的解决方案进行一些修改,这样就能添加一个像MessageBox那样的图标。

下面是修改后的代码:

import tkinter as tk
from tkinter import ttk
from tkinter.simpledialog import Dialog

class MyDialog(Dialog):
    def __init__(self, title, message, icon, pause=None, master=None):
        """
        icon can be "information", "warning", "error" or "question"
        """
        self.message = message
        self.icon = icon
        self.pause = pause
        super().__init__(master, title)

    def body(self, parent):
        # get the system icon image
        self.photo = tk.PhotoImage(master=parent)
        self.tk.call(self.photo, "copy", f"::tk::icons::{self.icon}")
        # create label with the icon image and message
        ttk.Label(parent, image=self.photo, text=self.message, compound="left").pack(padx=50, pady=20)

    def buttonbox(self):
        box = ttk.Frame(self)
        state = tk.DISABLED if self.pause else tk.NORMAL
        self.ok_btn = ttk.Button(box, text="OK", width=20, command=self.ok, default=tk.ACTIVE, state=state)
        self.ok_btn.pack(side=tk.LEFT, padx=5, pady=5)
        self.cancel_btn = ttk.Button(box, text="Cancel", width=20, command=self.cancel, state=state)
        self.cancel_btn.pack(side=tk.LEFT, padx=5, pady=5)
        box.pack()
        if self.pause:
            self._timer()
        else:
            self._bindings()

    def _bindings(self):
        self.bind("<Return>", self.ok)
        self.bind("<Escape>", self.cancel)

    def _timer(self):
        if self.pause > 0:
            self.ok_btn.config(text=self.pause)
            self.pause -= 1
            self.after(1000, self._timer)
        else:
            self.ok_btn.config(text="OK", state=tk.NORMAL)
            self.cancel_btn.config(state=tk.NORMAL)
            self._bindings()

    def apply(self):
        self.result = True

    def cancel(self, event=None):
        if self.pause in (None, 0):
            super().cancel(event)

dlg = MyDialog("Error", "Something wrong!", icon="warning", pause=5)
print(dlg.result)

结果:

在这里输入图片描述 在这里输入图片描述

撰写回答