AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / coding / 问题 / 76919604
Accepted
d'Elbreil Clément
d'Elbreil Clément
Asked: 2023-08-17 16:13:58 +0800 CST2023-08-17 16:13:58 +0800 CST 2023-08-17 16:13:58 +0800 CST

Python tkinter/ ttkboostrap dateentry 在只读状态下不起作用

  • 772

我目前正在使用 ttkbootstrap 库,而不是过去的 ttk 库。我曾经在“只读”状态下使用 ttk DateEntry 小部件,效果非常好。然而,由于某些原因,我需要停止使用 ttk 库,转而使用 ttkbootstrap 库。所以我创建了一个 ttkbootstrap DateEntry 就像文档中所述:https://ttkbootstrap.readthedocs.io/en/latest/styleguide/dateentry/

import ttkbootstrap as tb
from ttkbootstrap import constants

root = tb.Window()
date_entry = tb.DateEntry(root)
date_entry.pack(padx = 10, pady = 10)
date_entry["state"] = "readonly"

root.mainloop()

“只读”状态有效,因为我无法使用条目中的键盘进行写入。然而,当我尝试选择新日期时,日期似乎没有改变,因此条目将永远只在今天的日期。

在此输入图像描述

我知道这种交互与 ttkbootstrap 库特别相关,因为 dateentry 小部件在 ttk 库中工作得非常好。

我尝试搜索 DateEntry 类的源代码,但没有发现任何可以解释这种行为的内容。我仍然确信创建一个只读 DateEntry 并非不可能,因为它是这个库中您需要的最重要的东西之一。

python
  • 3 3 个回答
  • 30 Views

3 个回答

  • Voted
  1. Best Answer
    Tranbi
    2023-08-17T16:51:08+08:002023-08-17T16:51:08+08:00

    您不应该编辑 ttkbootstrap 的代码。它会在下次更新时被覆盖。

    您可以简单地创建一个继承自 的新类DateEntry,在 init 处定义条目的状态,并仅在按下按钮时启用该字段:

    import ttkbootstrap as tb
    
    class CustomDateEntry(tb.DateEntry):
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            self.entry["state"] = "readonly"
    
        def _on_date_ask(self):
            self.entry["state"] = "normal"
            super()._on_date_ask()
            self.entry["state"] = "readonly"
    
    root = tb.Window()
    date_entry = CustomDateEntry(root)
    date_entry.pack(padx = 10, pady = 10)
    
    root.mainloop()
    

    编辑:super()._on_date_ask()按照@acw1668的建议,调用而不是编写新函数。

    • 1
  2. Trynabal
    2023-08-17T16:33:44+08:002023-08-17T16:33:44+08:00

    只读状态使得日期只能读取而不能更改/编辑,因此它将其设置为当前日期,我认为这是不言自明的,我的问题是为什么不直接删除只读行,因为用户仍然可以通过日历弹出窗口选择日期吗?

    • 0
  3. d'Elbreil Clément
    2023-08-17T16:43:01+08:002023-08-17T16:43:01+08:00

    好的,我刚刚进入 ttkbootstrap DateEntry 的源代码并复制该类以及 Querybox 类。为了避免这个问题,我解释说我发现了一件事,你必须将日期条目与全局文本变量链接起来。然后你可以entry.insert(...) 用切换每个textvariable.set(...)。您还必须转换textvariable.get(...)复制的 Querybox 类中的所有插入内容。

    这里有 DateEntry 类:

    class DateEntry_test(ttk.Frame):
        """A date entry widget combines the `Combobox` and a `Button`
        with a callback attached to the `get_date` function.
    
        When pressed, a date chooser popup is displayed. The returned
        value is inserted into the combobox.
    
        The date chooser popup will use the date in the combobox as the
        date of focus if it is in the format specified by the
        `dateformat` parameter. By default, this format is "%Y-%m-%d".
    
        The bootstyle api may be used to change the style of the widget.
        The available colors include -> primary, secondary, success,
        info, warning, danger, light, dark.
    
        The starting weekday on the date chooser popup can be changed
        with the `firstweekday` parameter. By default this value is
        `6`, which represents "Sunday".
    
        The `Entry` and `Button` widgets are accessible from the
        `DateEntry.Entry` and `DateEntry.Button` properties.
    
        ![](../../assets/widgets/date-entry.png)
        """
    
        def __init__(
            self,
            master=None,
            dateformat=r"%x",
            firstweekday=6,
            startdate=None,
            bootstyle="",
            **kwargs,
        ):
            """
            Parameters:
    
                master (Widget, optional):
                    The parent widget.
    
                dateformat (str, optional):
                    The format string used to render the text in the entry
                    widget. For more information on acceptable formats, see https://strftime.org/
    
                firstweekday (int, optional):
                    Specifies the first day of the week. 0=Monday, 1=Tuesday,
                    etc...
    
                startdate (datetime, optional):
                    The date that is in focus when the widget is displayed. Default is
                    current date.
    
                bootstyle (str, optional):
                    A style keyword used to set the focus color of the entry
                    and the background color of the date button. Available
                    options include -> primary, secondary, success, info,
                    warning, danger, dark, light.
    
                **kwargs (Dict[str, Any], optional):
                    Other keyword arguments passed to the frame containing the
                    entry and date button.
            """
            self._dateformat = dateformat
            self._firstweekday = firstweekday
    
            self._startdate = startdate or datetime.today()
            self._bootstyle = bootstyle
            super().__init__(master, **kwargs)
    
            # add visual components
            entry_kwargs = {"bootstyle": self._bootstyle}
            if "width" in kwargs:
                entry_kwargs["width"] = kwargs.pop("width")
            self.textvariable = tk.StringVar()
            self.entry = ttk.Entry(self, textvariable=self.textvariable, **entry_kwargs)
            
            self.entry.pack(side=tk.LEFT, fill=tk.X, expand=tk.YES)
    
            self.button = ttk.Button(
                master=self,
                command=self._on_date_ask,
                bootstyle=f"{self._bootstyle}-date",
            )
            self.button.pack(side=tk.LEFT)
    
            # starting value
            self.textvariable.set(self._startdate.strftime(self._dateformat))
    
        def __getitem__(self, key: str):
            return self.configure(cnf=key)
    
        def __setitem__(self, key: str, value):
            self.configure(cnf=None, **{key: value})
    
        def _configure_set(self, **kwargs):
            """Override configure method to allow for setting custom
            DateEntry parameters"""
    
            if "state" in kwargs:
                state = kwargs.pop("state")
                if state in ["readonly", "invalid"]:
                    self.entry.configure(state=state)
                elif state in ("disabled", "normal"):
                    self.entry.configure(state=state)
                    self.button.configure(state=state)
                else:
                    kwargs[state] = state
            if "dateformat" in kwargs:
                self._dateformat = kwargs.pop("dateformat")
            if "firstweekday" in kwargs:
                self._firstweekday = kwargs.pop("firstweekday")
            if "startdate" in kwargs:
                self._startdate = kwargs.pop("startdate")
            if "bootstyle" in kwargs:
                self._bootstyle = kwargs.pop("bootstyle")
                self.entry.configure(bootstyle=self._bootstyle)
                self.button.configure(bootstyle=[self._bootstyle, "date"])
            if "width" in kwargs:
                width = kwargs.pop("width")
                self.entry.configure(width=width)
    
            super(ttk.Frame, self).configure(**kwargs)
    
        def _configure_get(self, cnf):
            """Override the configure get method"""
            if cnf == "state":
                entrystate = self.entry.cget("state")
                buttonstate = self.button.cget("state")
                return {"Entry": entrystate, "Button": buttonstate}
            if cnf == "dateformat":
                return self._dateformat
            if cnf == "firstweekday":
                return self._firstweekday
            if cnf == "startdate":
                return self._startdate
            if cnf == "bootstyle":
                return self._bootstyle
            else:
                return super(ttk.Frame, self).configure(cnf=cnf)
    
        def configure(self, cnf=None, **kwargs):
            """Configure the options for this widget.
    
            Parameters:
    
                cnf (Dict[str, Any], optional):
                    A dictionary of configuration options.
    
                **kwargs:
                    Optional keyword arguments.
            """
            if cnf is not None:
                return self._configure_get(cnf)
            else:
                return self._configure_set(**kwargs)
    
        def _on_date_ask(self):
            """Callback for pushing the date button"""
            _val = self.entry.get() or datetime.today().strftime(self._dateformat)
            try:
                self._startdate = datetime.strptime(_val, self._dateformat)
            except Exception as e:
                print("Date entry text does not match", self._dateformat)
                self._startdate = datetime.today()
                self.entry.delete(first=0, last=tk.END)
                self.textvariable.set(self._startdate.strftime(self._dateformat))
    
            old_date = datetime.strptime(_val, self._dateformat)
    
            # get the new date and insert into the entry
            new_date = Querybox_test.get_date(
                parent=self.entry,
                startdate=old_date,
                firstweekday=self._firstweekday,
                bootstyle=self._bootstyle,
            )
            self.entry.delete(first=0, last=tk.END)
            self.textvariable.set(new_date.strftime(self._dateformat))
            self.entry.focus_force()
    

    和查询框类:

    class Querybox_test:
        """This class contains various static methods that request data
        from the end user."""
    
        @staticmethod
        def get_color(
            parent=None, title="Color Chooser", initialcolor=None, **kwargs
        ):
            """Show a color picker and return the select color when the
            user pressed OK.
    
            ![](../../assets/dialogs/querybox-get-color.png)
    
            Parameters:
    
                parent (Widget):
                    The parent widget.
    
                title (str):
                    Optional text that appears on the titlebar.
    
                initialcolor (str):
                    The initial color to display in the 'Current' color
                    frame.
    
            Returns:
    
                Tuple[rgb, hsl, hex]:
                    The selected color in various colors models.
            """
            from ttkbootstrap.dialogs.colorchooser import ColorChooserDialog
    
            dialog = ColorChooserDialog(parent, title, initialcolor)
            if "position" in kwargs:
                position = kwargs.pop("position")
            else:
                position = None
            dialog.show(position)
            return dialog.result
    
        @staticmethod
        def get_date(
            parent=None,
            title=" ",
            firstweekday=6,
            startdate=None,
            bootstyle="primary",
        ):
            """Shows a calendar popup and returns the selection.
    
            ![](../../assets/dialogs/querybox-get-date.png)
    
            Parameters:
    
                parent (Widget):
                    The parent widget; the popup will appear to the
                    bottom-right of the parent widget. If no parent is
                    provided, the widget is centered on the screen.
    
                title (str):
                    The text that appears on the popup titlebar.
    
                firstweekday (int):
                    Specifies the first day of the week. `0` is Monday, `6` is
                    Sunday (the default).
    
                startdate (datetime):
                    The date to be in focus when the widget is displayed;
    
                bootstyle (str):
                    The following colors can be used to change the color of the
                    title and hover / pressed color -> primary, secondary, info,
                    warning, success, danger, light, dark.
    
            Returns:
    
                datetime:
                    The date selected; the current date if no date is selected.
            """
            chooser = DatePickerDialog(
                parent=parent,
                title=title,
                firstweekday=firstweekday,
                startdate=startdate,
                bootstyle=bootstyle,
            )
            return chooser.date_selected
    
        @staticmethod
        def get_string(
            prompt="", title=" ", initialvalue=None, parent=None, **kwargs
        ):
            """Request a string type input from the user.
    
            ![](../../assets/dialogs/querybox-get-string.png)
    
            Parameters:
    
                prompt (str):
                    A message to display in the message box above the entry
                    widget.
    
                title (str):
                    The string displayed as the title of the message box. This
                    option is ignored on Mac OS X, where platform guidelines
                    forbid the use of a title on this kind of dialog.
    
                initialvalue (Any):
                    The initial value in the entry widget.
    
                parent (Widget):
                    Makes the window the logical parent of the message box. The
                    messagebox is displayed on top of its parent window.
    
                **kwargs (Dict):
                    Other optional keyword arguments.
    
            Returns:
    
                str:
                    The string value of the entry widget.
            """
            initialvalue = initialvalue or ""
            if "position" in kwargs:
                position = kwargs.pop("position")
            else:
                position = None
            dialog = QueryDialog(
                prompt, title, initialvalue, parent=parent, **kwargs
            )
            dialog.show(position)
            return dialog._result
    
        @staticmethod
        def get_integer(
            prompt="",
            title=" ",
            initialvalue=None,
            minvalue=None,
            maxvalue=None,
            parent=None,
            **kwargs,
        ):
            """Request an integer type input from the user.
    
            ![](../../assets/dialogs/querybox-get-integer.png)
    
            Parameters:
    
                prompt (str):
                    A message to display in the message box above the entry
                    widget.
    
                title (str):
                    The string displayed as the title of the message box. This
                    option is ignored on Mac OS X, where platform guidelines
                    forbid the use of a title on this kind of dialog.
    
                initialvalue (int):
                    The initial value in the entry widget.
    
                minvalue (int):
                    The minimum allowed value.
    
                maxvalue (int):
                    The maximum allowed value.
    
                parent (Widget):
                    Makes the window the logical parent of the message box. The
                    messagebox is displayed on top of its parent window.
    
                **kwargs (Dict):
                    Other optional keyword arguments.
    
            Returns:
    
                int:
                    The integer value of the entry widget.
            """
            initialvalue = initialvalue or ""
            if "position" in kwargs:
                position = kwargs.pop("position")
            else:
                position = None
            dialog = QueryDialog(
                prompt,
                title,
                initialvalue,
                minvalue,
                maxvalue,
                datatype=int,
                parent=parent,
                **kwargs,
            )
            dialog.show(position)
            return dialog._result
    
        @staticmethod
        def get_float(
            prompt="",
            title=" ",
            initialvalue=None,
            minvalue=None,
            maxvalue=None,
            parent=None,
            **kwargs,
        ):
            """Request a float type input from the user.
    
            ![](../../assets/dialogs/querybox-get-float.png)
    
            Parameters:
    
                prompt (str):
                    A message to display in the message box above the entry
                    widget.
    
                title (str):
                    The string displayed as the title of the message box. This
                    option is ignored on Mac OS X, where platform guidelines
                    forbid the use of a title on this kind of dialog.
    
                initialvalue (float):
                    The initial value in the entry widget.
    
                minvalue (float):
                    The minimum allowed value.
    
                maxvalue (float):
                    The maximum allowed value.
    
                parent (Widget):
                    Makes the window the logical parent of the message box. The
                    messagebox is displayed on top of its parent window.
    
                **kwargs (Dict):
                    Other optional keyword arguments.
    
            Returns:
    
                float:
                    The float value of the entry widget.
            """
            initialvalue = initialvalue or ""
            if "position" in kwargs:
                position = kwargs.pop("position")
            else:
                position = None
            dialog = QueryDialog(
                prompt,
                title,
                initialvalue,
                minvalue,
                maxvalue,
                datatype=float,
                parent=parent,
                **kwargs,
            )
            dialog.show(position)
            return dialog._result
    
        @staticmethod
        def get_font(parent=None, **kwargs):
            """Request a customized font
    
            ![](../../assets/dialogs/querybox-get-font.png)
    
            Parameters:
    
                parent (Widget):
                    Makes the window the logical parent of the dialog box. The
                    dialog is displayed on top of its parent window.
    
                **kwargs (Dict):
                    Other keyword arguments.
    
            Returns:
    
                Font:
                    A font object.
            """
            if "position" in kwargs:
                position = kwargs.pop("position")
            else:
                position = None
            dialog = FontDialog(parent=parent, **kwargs)
            dialog.show(position)
            return dialog.result
    
    • 0

相关问题

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    使用 <font color="#xxx"> 突出显示 html 中的代码

    • 2 个回答
  • Marko Smith

    为什么在传递 {} 时重载解析更喜欢 std::nullptr_t 而不是类?

    • 1 个回答
  • Marko Smith

    您可以使用花括号初始化列表作为(默认)模板参数吗?

    • 2 个回答
  • Marko Smith

    为什么列表推导式在内部创建一个函数?

    • 1 个回答
  • Marko Smith

    我正在尝试仅使用海龟随机和数学模块来制作吃豆人游戏

    • 1 个回答
  • Marko Smith

    java.lang.NoSuchMethodError: 'void org.openqa.selenium.remote.http.ClientConfig.<init>(java.net.URI, java.time.Duration, java.time.Duratio

    • 3 个回答
  • Marko Smith

    为什么 'char -> int' 是提升,而 'char -> Short' 是转换(但不是提升)?

    • 4 个回答
  • Marko Smith

    为什么库中不调用全局变量的构造函数?

    • 1 个回答
  • Marko Smith

    std::common_reference_with 在元组上的行为不一致。哪个是对的?

    • 1 个回答
  • Marko Smith

    C++17 中 std::byte 只能按位运算?

    • 1 个回答
  • Martin Hope
    fbrereto 为什么在传递 {} 时重载解析更喜欢 std::nullptr_t 而不是类? 2023-12-21 00:31:04 +0800 CST
  • Martin Hope
    比尔盖子 您可以使用花括号初始化列表作为(默认)模板参数吗? 2023-12-17 10:02:06 +0800 CST
  • Martin Hope
    Amir reza Riahi 为什么列表推导式在内部创建一个函数? 2023-11-16 20:53:19 +0800 CST
  • Martin Hope
    Michael A fmt 格式 %H:%M:%S 不带小数 2023-11-11 01:13:05 +0800 CST
  • Martin Hope
    God I Hate Python C++20 的 std::views::filter 未正确过滤视图 2023-08-27 18:40:35 +0800 CST
  • Martin Hope
    LiDa Cute 为什么 'char -> int' 是提升,而 'char -> Short' 是转换(但不是提升)? 2023-08-24 20:46:59 +0800 CST
  • Martin Hope
    jabaa 为什么库中不调用全局变量的构造函数? 2023-08-18 07:15:20 +0800 CST
  • Martin Hope
    Panagiotis Syskakis std::common_reference_with 在元组上的行为不一致。哪个是对的? 2023-08-17 21:24:06 +0800 CST
  • Martin Hope
    Alex Guteniev 为什么编译器在这里错过矢量化? 2023-08-17 18:58:07 +0800 CST
  • Martin Hope
    wimalopaan C++17 中 std::byte 只能按位运算? 2023-08-17 17:13:58 +0800 CST

热门标签

python javascript c++ c# java typescript sql reactjs html

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve