Skip to content

ttk.Style.element_create using incorrect tk.call syntax #68166

Closed

Description

@jmorgensen
BPO 23978
Nosy @terryjreedy, @roseman, @serhiy-storchaka

Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

Show more details

GitHub fields:

assignee = 'https://github.com/serhiy-storchaka'
closed_at = None
created_at = <Date 2015-04-16.22:49:38.007>
labels = ['type-bug', 'expert-tkinter']
title = 'ttk.Style.element_create using incorrect tk.call syntax'
updated_at = <Date 2015-08-06.21:25:09.278>
user = 'https://bugs.python.org/jmorgensen'

bugs.python.org fields:

activity = <Date 2015-08-06.21:25:09.278>
actor = 'terry.reedy'
assignee = 'serhiy.storchaka'
closed = False
closed_date = None
closer = None
components = ['Tkinter']
creation = <Date 2015-04-16.22:49:38.007>
creator = 'jmorgensen'
dependencies = []
files = []
hgrepos = []
issue_num = 23978
keywords = []
message_count = 3.0
messages = ['241286', '241370', '248149']
nosy_count = 4.0
nosy_names = ['terry.reedy', 'markroseman', 'serhiy.storchaka', 'jmorgensen']
pr_nums = []
priority = 'normal'
resolution = None
stage = 'needs patch'
status = 'open'
superseder = None
type = 'behavior'
url = 'https://bugs.python.org/issue23978'
versions = ['Python 2.7', 'Python 3.4', 'Python 3.5', 'Python 3.6']

Linked PRs

Activity

  1. jmorgensen commented on Apr 16, 2015

    jmorgensenmannequin
    MannequinAuthor

    Style.element_create passes all spec elements as a single string into tk.call rather than breaking up arguments into "words." However, it passes the options properly as a list.

    This causes python to crash with a stacktrace like the one below.

    def element_create(self, elementname, etype, *args, **kw):
    """Create a new element in the current theme of given etype."""
        spec, opts = _format_elemcreate(etype, False, *args, **kw)
        self.tk.call(self._name, "element", "create", elementname, etype,
            spec, *opts)

    And in _format_elemcreate:

        spec = "%s %s" % (iname, imagespec)
        ...
        spec = "%s %s %s" % (class_name, part_id, statemap)

    Reproduction (on win):

    >>> import ttk
    >>> Style().element_create('custom.test', 'vsapi', 'SPIN', 2)
      File "<stdin>", line 1, in <module>
      File "C:\Miniconda\lib\lib-tk\ttk.py", line 466, in element_create
        spec, *opts)
    _tkinter.TclError: missing required arguments 'class' and/or 'partId'

    and, similarly:

    >>> import ttk
    >>> ttk.Style().element_create('custom.test', 'vsapi', 'SPIN', 2, width=5)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "C:\Miniconda\lib\lib-tk\ttk.py", line 466, in element_create
        spec, *opts)
    _tkinter.TclError: expected integer but got "-width"
  2. removed
    type-crashA hard crash of the interpreter, possibly with a core dump
    on Apr 16, 2015
  3. terryjreedy commented on Apr 17, 2015

    @terryjreedy
    Member

    Reproduced on Win7, 3.4.3, with updated import: "from tkinter import ttk". The example should serve as a test.

  4. terryjreedy commented on Aug 6, 2015

    @terryjreedy
    Member

    This looks like it should be an easy for for someone who understands tcl.call syntax. When we add ttk to Idle, I do not expect to use element_create, but maybe someone will want to to create a custom theme.

  5. transferred this issue fromon Apr 10, 2022
  6. added a commit that references this issue on Oct 27, 2023
  7. serhiy-storchaka commented on Oct 28, 2023

    @serhiy-storchaka
    Member

    There are two ways to create new elements in Tkinter. One is by calling the elemnt_create() methods, and the other one by calling the theme_create() or theme_settings() method and using the elemnt_create key in the settings dict. In the former case it calls the ttk:style element create command directly, in the latter case it formats a script containing the ttk:style element create command and passes it as argument to the ttk:style theme create or the ttk:style theme settings command. There are enough differences between these two paths, so I expected that at least the latter works correctly. But it turned out that both ways do not work and never worked since adding this code in the stdlib. So it makes sense to consider it as a new feature rather than a bugfix. It should be documented correspondingly, and older versions should be made to raise more explicit exception when try to use the "vsapi" factory.

    It is also an opportunity to change the Python API (which never worked) to closer match the Tk API. I.e. instead of

            style.element_create('pin', 'vsapi', 'EXPLORERBAR', 3,
                                 ('pressed', '!selected', 3),
                                 ('active', '!selected', 2),
                                 ('pressed', 'selected', 6),
                                 ('active', 'selected', 5),
                                 ('selected', 4),
                                 ('', 1))

    it should be

            style.element_create('pin', 'vsapi', 'EXPLORERBAR', 3, [
                                 ('pressed', '!selected', 3),
                                 ('active', '!selected', 2),
                                 ('pressed', 'selected', 6),
                                 ('active', 'selected', 5),
                                 ('selected', 4),
                                 ('', 1)])

    or

            style.element_create('pin', 'vsapi', 'EXPLORERBAR', 3, [
                                 (('pressed', '!selected'), 3),
                                 (('active', '!selected'), 2),
                                 (('pressed', 'selected'), 6),
                                 (('active', 'selected'), 5),
                                 (('selected',), 4),
                                 ((), 1)])

    or

            style.element_create('pin', 'vsapi', 'EXPLORERBAR', 3, {
                                 ('pressed', '!selected'): 3,
                                 ('active', '!selected'): 2,
                                 ('pressed', 'selected'): 6,
                                 ('active', 'selected'): 5,
                                 ('selected',): 4,
                                 (): 1})
  8. added a commit that references this issue on Oct 29, 2023
  9. added a commit that references this issue on Nov 8, 2023
  10. added 2 commits that reference this issue on Nov 8, 2023
  11. added 3 commits that reference this issue on Nov 27, 2023
  12. added 2 commits that reference this issue on Feb 11, 2024
  13. added 2 commits that reference this issue on Sep 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

3.13only security fixestopic-tkintertype-bugAn unexpected behavior, bug, or errortype-featureA feature request or enhancement

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions