Repository: Andereoo/TkinterWeb Branch: main Commit: 4a317a4c5d88 Files: 43 Total size: 535.1 KB Directory structure: gitextract_67ltj4rn/ ├── .github/ │ └── FUNDING.yml ├── .gitignore ├── .readthedocs.yaml ├── LICENSE.md ├── MANIFEST.in ├── README.md ├── docs/ │ ├── Makefile │ ├── make.bat │ ├── requirements.txt │ └── source/ │ ├── _static/ │ │ ├── banner.png~ │ │ └── custom.css │ ├── api/ │ │ ├── extensions.rst │ │ ├── htmldocument.rst │ │ ├── htmlframe.rst │ │ ├── jsengine.rst │ │ ├── notebook.rst │ │ ├── tkinterweb.rst │ │ └── tkinterweb_api.rst │ ├── api.rst │ ├── caret.rst │ ├── compatibility.rst │ ├── conf.py │ ├── dom.rst │ ├── faq.rst │ ├── geometry.rst │ ├── index.rst │ ├── javascript.rst │ ├── shrink.rst │ ├── upgrading.rst │ └── usage.rst ├── examples/ │ └── TkinterWebBrowser.py ├── setup.py ├── tkinterweb/ │ ├── __init__.py │ ├── bindings.py │ ├── dom.py │ ├── extensions.py │ ├── handlers.py │ ├── htmlwidgets.py │ ├── imageutils.py │ ├── js.py │ ├── subwidgets.py │ └── utilities.py └── tools/ └── preparewheels.py ================================================ FILE CONTENTS ================================================ ================================================ FILE: .github/FUNDING.yml ================================================ # These are supported funding model platforms buy_me_a_coffee: andereoo ================================================ FILE: .gitignore ================================================ build/ tkinterweb/__pycache__/ tkinterweb/resources/ tkinterweb.egg-info ================================================ FILE: .readthedocs.yaml ================================================ version: "2" build: os: "ubuntu-22.04" tools: python: "3.10" python: install: - requirements: docs/requirements.txt sphinx: configuration: docs/source/conf.py ================================================ FILE: LICENSE.md ================================================ MIT License Copyright (c) 2021-2025 Andrew Clarke Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: MANIFEST.in ================================================ recursive-include tkinterweb/resources * ================================================ FILE: README.md ================================================ ![PyPi Downloads](https://static.pepy.tech/badge/tkinterweb/month) ![MIT Licence](https://img.shields.io/pypi/l/tkinterweb) ![Python 3](https://img.shields.io/pypi/pyversions/tkinterweb) ![Made in Canada](https://img.shields.io/badge/%F0%9F%87%A8%F0%9F%87%A6%20made%20in%20Canada-grey)
Buy Me A Coffee

**

Fast and lightweight web browser, rich text, and app design widgets for Tkinter.

** ## Overview **TkinterWeb adds HTML and CSS rendering capabilities to Tkinter widgets.** Common use cases include displaying help files, documentation, and other HTML content, rendering images (including SVG), building rich-text editors, designing apps with HTML templates, and creating more modern-looking interfaces, with advanced styling and even round buttons! All [major operating systems](https://tkinterweb.readthedocs.io/en/latest/compatibility.html#a-note-on-tkhtml-binaries) running Python 3.2+ are supported. ## Usage **TkinterWeb provides:** * A [frame widget](https://tkinterweb.readthedocs.io/en/latest/api/htmlframe.html) to display and edit websites, help files, RSS feeds, and any other styled HTML in Tkinter. * A [label widget](https://tkinterweb.readthedocs.io/en/latest/api/htmlframe.html#tkinterweb.HtmlLabel) that can display styled HTML. * A [text widget](https://tkinterweb.readthedocs.io/en/latest/api/htmlframe.html#tkinterweb.HtmlText) that allows the user to edit styled HTML. **TkinterWeb can be used in any Tkinter application to display and edit websites, help pages, documentation, and much more! Here is an example:** ``` import tkinter as tk from tkinterweb import HtmlFrame # import the HtmlFrame widget root = tk.Tk() # create the Tkinter window frame = HtmlFrame(root, messages_enabled=True) # create the HtmlFrame widget frame.load_website("https://tkinterweb.readthedocs.io/en/latest/index.html") # load a website frame.pack(fill="both", expand=True) # attach the HtmlFrame widget to the window root.mainloop() ``` ![TkinterWeb](/images/tkinterweb-demo.png) See [Getting Started](https://tkinterweb.readthedocs.io/en/latest/usage.html) for more tips and tricks. ## Installation To install TkinterWeb, simply type `pip install tkinterweb[recommended]` in the command prompt or terminal. That's it! Or, you can also choose from the following extras: `pip install tkinterweb[html,images,svg,javascript,requests]`. You can also use `pip install tkinterweb[full]` to install all optional dependencies or ``pip install tkinterweb`` to install the bare minimum. ## Dependencies **TkinterWeb offers bindings and extensions to a modified version of the Tkhtml3 widget from [http://tkhtml.tcl.tk](https://web.archive.org/web/20250219233338/http://tkhtml.tcl.tk/). Tkinter and the [TkinterWeb-Tkhtml](https://pypi.org/project/tkinterweb-tkhtml/) package are required.** I also **strongly** recommended installing the following: * [TkinterWeb-Tkhtml-Extras](https://pypi.org/project/tkinterweb-tkhtml-extras/) (for better HTML/CSS support and bug fixes) * [PIL](https://pillow.readthedocs.io/) (for better image support) * [PIL.ImageTk](https://pillow.readthedocs.io/en/stable/reference/ImageTk.html) You can also choose from the following list for extra functionality: * [Brotli](https://github.com/google/brotli) (for faster page loads on some sites) * [PythonMonkey](http://pythonmonkey.io/) (for basic JavaScript support) * [CairoSVG](https://cairosvg.org/) or [PyGObject](https://pygobject.gnome.org/) (for SVG support) Pip will automatically install dependencies when installing TkinterWeb. PIL.ImageTk should be automatically installed with PIL but might need to installed separately on some systems. ## API Documentation > [!WARNING] > The API changed significantly in version 4.0.0. See [the changelog](https://tkinterweb.readthedocs.io/en/latest/upgrading.html) for details. **Documentation and additional information on built-in classes can be found in the corresponding API reference pages:** * [`tkinterweb.Demo`](https://tkinterweb.readthedocs.io/en/latest/usage.html#installation) * [`tkinterweb.HtmlFrame`](https://tkinterweb.readthedocs.io/en/latest/api/htmlframe.html) * [`tkinterweb.HtmlLabel`](https://tkinterweb.readthedocs.io/en/latest/api/htmlframe.html#tkinterweb.HtmlLabel) * [`tkinterweb.HtmlText`](https://tkinterweb.readthedocs.io/en/latest/api/htmlframe.html#tkinterweb.HtmlText) * [`tkinterweb.HtmlParse`](https://tkinterweb.readthedocs.io/en/latest/api/htmlframe.html#tkinterweb.HtmlParse) * [`tkinterweb.TkinterWeb`](https://tkinterweb.readthedocs.io/en/latest/api/tkinterweb.html) * [`tkinterweb.Notebook`](https://tkinterweb.readthedocs.io/en/latest/api/notebook.html) (a Tkhtml-compatible drop-in replacement for `ttk.Notebook`) ## FAQs See [Frequently Asked Questions](https://tkinterweb.readthedocs.io/en/latest/faq.html). ## Webpage Compatability **HTML & CSS:** * TkinterWeb supports HTML 4.01 and CSS 2.1. A full list of supported CSS declarations can be found at [http://tkhtml.tcl.tk/support.html](https://web.archive.org/web/20250325123206/http://tkhtml.tcl.tk/support.html). * Most CSS pseudo-elements, such as `:hover` and `:active` are also supported. * On 64-bit Windows and Linux, if the [TkinterWeb-Tkhtml-Extras](https://pypi.org/project/tkinterweb-tkhtml-extras/) is installed, HTML5 tags and some extra CSS properties (including `border-radius` and `overflow-x`) and cursors are also supported. To use these features on all other platforms, you will simply need to compile Tkhtml yourself. Visit and clone https://github.com/Andereoo/TkinterWeb-Tkhtml. Then run `python compile.py --install`. **JavaScript:** * Javascript only partly supported at the moment. * To use JavaScript, PythonMonkey must be installed. * It is also possible for the user to connect their own JavaScript interpreter or manipulate the document through Python. * See [Using JavaScript](https://tkinterweb.readthedocs.io/en/latest/javascript.html) for more information and [DOM Manipulation with TkinterWeb](https://tkinterweb.readthedocs.io/en/latest/dom.html) for information on manipulating the document through Python. **Images:** * TkinterWeb supports nearly 50 different image types through PIL. * In order to load Scalable Vector Graphic images, CairoSVG, both PyCairo and PyGObject, or both PyCairo and Rsvg must also be installed. ## Support & Donations **☕ If you’d like to support ongoing development and maintenance, please consider supporting this project by [buying me a coffee](https://buymeacoffee.com/andereoo). Any amount is hugely appreciated!** This project is released under the [MIT License](./LICENSE.md) and is free to use, including for commercial purposes. If you use this project in a commercial product or derive financial benefit from it, please kindly consider supporting its development with a donation. This helps cover maintenance time and ongoing improvements, which in turn will improve your own software! ## Contributing **The best ways to contribute to this project are by submitting a [bug report](https://github.com/Andereoo/TkinterWeb/issues/new) to report bugs or suggest new features, or by submitting a [pull request](https://github.com/Andereoo/TkinterWeb/pulls) to offer fixes. Your help makes TkinterWeb become more stable and full-featured!** Please check the [FAQs](https://tkinterweb.readthedocs.io/en/latest/faq.html) and [closed bugs](https://github.com/Andereoo/TkinterWeb/issues?q=is%3Aissue) before submitting a bug report to see if your question as already been answered. ## Credits **TkinterWeb is powered by the [Tkhtml project](https://web.archive.org/web/20250219233338/http://tkhtml.tcl.tk/).** Special thanks to [Christopher Chavez](https://github.com/chrstphrchvz), [Zamy846692](https://github.com/Zamy846692), [Jośe Fernando Moyano](https://github.com/jofemodo), [Bumshakalaka](https://github.com/Bumshakalaka), [Trov5](https://github.com/TRVRStash), [Mark Mayo](https://github.com/marksmayo), [Jaedson Silva](https://github.com/jaedsonpys), [Nick Moore](https://github.com/nickzoic), [Leonardo Saurwein](https://github.com/Sau1707), and [Hbregalad](https://github.com/hbregalad) for their code suggestions and pull requests. Special thanks to [Christopher Chavez](https://github.com/chrstphrchvz), Jan Nijtmans, and everyone else in the tcl-core mailing list for the help making border rounding work on Windows and MacOSX, and to [Zamy846692](https://github.com/Zamy846692) for spearheading experimental Tkhtml development. Thanks to the [TkinterHtml package](https://bitbucket.org/aivarannamaa/tkinterhtml) for providing the bindings on which this project is based and the [BRL-CAD project](https://github.com/BRL-CAD/brlcad) for providing modifications for Tkhtml on 64-bit Windows. A huge thanks to everyone else who supported this project by reporting bugs and providing suggestions! ================================================ FILE: docs/Makefile ================================================ # Minimal makefile for Sphinx documentation # # You can set these variables from the command line, and also # from the environment for the first two. SPHINXOPTS ?= SPHINXBUILD ?= sphinx-build SOURCEDIR = source BUILDDIR = build # Put it first so that "make" without argument is like "make help". help: @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) .PHONY: help Makefile # Catch-all target: route all unknown targets to Sphinx using the new # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). %: Makefile @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) ================================================ FILE: docs/make.bat ================================================ @ECHO OFF pushd %~dp0 REM Command file for Sphinx documentation if "%SPHINXBUILD%" == "" ( set SPHINXBUILD=sphinx-build ) set SOURCEDIR=source set BUILDDIR=build if "%1" == "" goto help %SPHINXBUILD% >NUL 2>NUL if errorlevel 9009 ( echo. echo.The 'sphinx-build' command was not found. Make sure you have Sphinx echo.installed, then set the SPHINXBUILD environment variable to point echo.to the full path of the 'sphinx-build' executable. Alternatively you echo.may add the Sphinx directory to PATH. echo. echo.If you don't have Sphinx installed, grab it from echo.http://sphinx-doc.org/ exit /b 1 ) %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% goto end :help %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% :end popd ================================================ FILE: docs/requirements.txt ================================================ sphinx==7.1.2 sphinx-rtd-theme==1.3.0rc1 sphinx_design==0.6.1 tkinterweb-tkhtml >= 2.0.0 Pillow >= 10.0.0 ================================================ FILE: docs/source/_static/custom.css ================================================ /* This file is used to make tweak the documentation and make it CSS2 compatible.*/ .wy-nav-side { overflow: hidden !important; } .wy-side-nav-search > div.version { color: #cacaca !important; } .wy-side-nav-search, .wy-nav-top, .note .admonition-title, .wy-menu-vertical a:active { background-color: rgb(77, 122, 77) !important; } .wy-nav-content a { color: rgb(77, 122, 77); } .wy-nav-content a:hover { color: rgb(96, 156, 96); } code.literal, span.literal { color: rgb(94, 94, 94) !important; } .rst-content code.xref, .rst-content tt.xref, a .rst-content code, a .rst-content tt { color: initial !important } .note { background-color: rgb(230, 238, 230) !important; } #rtd-search-form input { width: 80% !important; color: black !important; margin-left: auto; margin-right: auto; } .wy-breadcrumbs .icon-home:before { content: "Home" !important; font-family: Lato, proxima-nova, Helvetica Neue, Arial, sans-serif !important; } .wy-breadcrumbs .wy-breadcrumbs-aside { display: none; } .wy-side-nav-search { padding-left: 0 !important; padding-right: 0 !important; } .wy-breadcrumbs .breadcrumb-item { display: inline !important; } .highlight-python, .highlight-console, .highlight-default { border: 1px solid #e1e4e5 !important; margin: 1px 0 24px !important; background: #f8f8f8 !important; width: 100% !important; } .highlight pre { white-space: pre !important; margin: 0 !important; padding: 12px !important; display: block !important; } .highlight { border: none !important; margin: 0 !important; } .sig-object { display: table !important; margin: 6px 0 !important; margin-top: 6px !important; font-size: 90% !important; line-height: normal !important; background: rgb(230, 238, 230) !important; color: rgb(77, 122, 77) !important; border-top: 3px solid rgb(101, 145, 101) !important; padding: 6px !important; position: relative !important; } .sig-object .property, .sig-object .sig-param, .sig-object .sig-paren { font-size: 90% !important; line-height: normal !important; color: rgb(77, 122, 77) !important; } .sig-object .sig-name, .sig-object .sig-prename { font-family: SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, Courier New, Courier, monospace !important; color: #000 !important; } dd .sig-object { margin-bottom: 6px !important; border: none !important; border-left-width: medium !important; border-left-style: none !important; border-left-color: currentcolor !important; border-left: 3px solid #ccc !important; background: #f0f0f0 !important; color: #555 !important; } dd .sig-name { font-family: SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, Courier New, Courier, monospace !important; color: #000 !important; } dd .property, dd .sig-param, dd .sig-paren { color: inherit !important } .rst-footer-buttons { display: table !important; width: 100% !important; } .rst-footer-buttons .float-left { display: table-cell !important; } .rst-footer-buttons .float-right { display: table-cell !important; } .fa-arrow-circle-right:before { content: " →" !important; } .fa-arrow-circle-left:before { content: "← " !important; } .btn { border-color: #e1e4e5 !important; padding: 6px 12px !important; border-bottom: 2px solid #ccc !important; box-shadow: none !important; transition: none !important; } .btn:active { border-top: 2px solid #ccc !important; padding: 5px 12px 7px !important; border-bottom-width: 1px !important; } .wy-side-nav-search > a { padding: 0 !important; margin: 0 !important; } .wy-side-nav-search > a:hover { background: transparent !important; } .wy-side-nav-search > a img.logo { max-width: 250px !important; margin: 0 !important; } .sd-card-header { display: block; } details.sd-dropdown .sd-summary-content p { cursor: text; } details.sd-dropdown summary.sd-summary-title{ padding: .5em .6em .5em 1em !important; } .sd-mb-3, .sd-my-3 { margin-bottom: 16px !important; } .sd-card-header, .sd-card { border-color: #dcdcdc; border-radius: 4px; } .sd-card-body { padding: 0px 17px !important; } .rst-content .section ul, .rst-content .toctree-wrapper ul, .rst-content section ul, .wy-plain-list-disc, article ul { margin: 12px 0px !important; } .sd-card-body > p { margin: 12px 0px !important; } ================================================ FILE: docs/source/api/extensions.rst ================================================ TkinterWeb Extensions ===================== The following objects are extensions to the :class:`~tkinterweb.TkinterWeb` widget and are largely internal. You will likely never need to access them, but they are described here just in case. The methods described in this page may change at any time without warning. If you are relying on anything here, please let me know so I know to keep compatibility. .. autoclass:: tkinterweb.extensions.SelectionManager :members: .. autoclass:: tkinterweb.extensions.CaretManager :members: .. autoclass:: tkinterweb.extensions.EventManager :members: .. autoclass:: tkinterweb.extensions.WidgetManager :members: .. autoclass:: tkinterweb.extensions.SearchManager :members: ================================================ FILE: docs/source/api/htmldocument.rst ================================================ Document Object Model Documentation =================================== .. note:: The API changed significantly in version 4. See :doc:`the changelog <../upgrading>` for details. The methods described in this page make it easy to modify the appearance and content of a loaded document and manage interaction with the document. For the most part, this page mirrors the core JavaScript DOM API. .. autoclass:: tkinterweb.dom.HTMLDocument :members: .. autoclass:: tkinterweb.dom.HTMLElement :members: The following JavaScript event properties are also supported: ``onchange``, ``onclick``, ``oncontextmenu``, ``ondblclick``, ``onload``, ``onmousedown``, ``onmouseenter``, ``onmouseleave``, ``onmousemove``, ``onmouseout``, ``onmouseover``, and ``onmouseup``. .. autoclass:: tkinterweb.dom.HTMLCollection :members: .. autoclass:: tkinterweb.dom.CSSStyleDeclaration :members: .. autoclass:: tkinterweb.dom.DOMRect :members: Special thanks to `Zamy846692 `_ for the help making this happen! ================================================ FILE: docs/source/api/htmlframe.rst ================================================ HTML Widgets Documentation ========================== .. note:: The API changed significantly in version 4. See :doc:`the changelog <../upgrading>` for details. The :class:`~tkinterweb.HtmlFrame` widget is a Tkinter frame that provides additional functionality to the :class:`~tkinterweb.TkinterWeb` widget by adding automatic scrollbars, error handling, and many convenience methods into one embeddable and easy to use widget. The :class:`~tkinterweb.HtmlFrame` widget is also capable managing other Tkinter widgets, making it easy to combine Tkinter widgets and HTML elements. .. autoclass:: tkinterweb.HtmlFrame :members: This widget also emits the following Tkinter virtual events that can be bound to: * ``<>``/:py:attr:`utilities.DOWNLOADING_RESOURCE_EVENT`: Generated whenever a new resource is being downloaded. * ``<>``/:py:attr:`utilities.DONE_LOADING_EVENT`: Generated whenever all outstanding resources have been downloaded. This is generally a good indicator as to when the website is done loading, but may be generated multiple times while loading a page. * ``<>``/:py:attr:`utilities.DOM_CONTENT_LOADED_EVENT`: Generated once the page content has loaded. The page may not be done loading, but at this point it is possible to interact with the DOM. * ``<>``/:py:attr:`utilities.URL_CHANGED_EVENT`: Generated whenever the widget's url changes or redirects. Use :attr:`.HtmlFrame.current_url` to get the url. * ``<>``/:py:attr:`utilities.ICON_CHANGED_EVENT`: Generated whenever the icon of a webpage changes. Use :attr:`.HtmlFrame.icon` to get the icon. * ``<>``/:py:attr:`utilities.TITLE_CHANGED_EVENT`: Generated whenever the title of a website or file has changed. Use :attr:`.HtmlFrame.title` to get the title. * ``<>```/:py:attr:`utilities.FIELD_CHANGED_EVENT`: Generated whenever the content of an interactive element changes. .. autoclass:: tkinterweb.HtmlLabel :members: .. autoclass:: tkinterweb.HtmlText :members: .. autoclass:: tkinterweb.HtmlParse :members: ================================================ FILE: docs/source/api/jsengine.rst ================================================ JavaScript Engine Documentation =============================== The methods described in this page make it easy to interact with the JavaScript Engine. .. autoclass:: tkinterweb.js.JSEngine :members: ================================================ FILE: docs/source/api/notebook.rst ================================================ Notebook Documentation ======================= The TkinterWeb :class:`~tkinterweb.Notebook` widget should be used in place of :py:class:`ttk.Notebook`, which is incompatable with Tkhtml on 64-bit Windows and crashes when selecting tabs. See https://docs.python.org/3/library/tkinter.ttk.html#notebook for the full API. .. autoclass:: tkinterweb.Notebook :members: This widget also emits the following Tkinter virtual events that can be bound to: * ``<>``: Generated whenever the selected tab changes. ================================================ FILE: docs/source/api/tkinterweb.rst ================================================ Internals Documentation ======================= .. toctree :: :maxdepth: 2 tkinterweb_api extensions ================================================ FILE: docs/source/api/tkinterweb_api.rst ================================================ Bindings Documentation ====================== .. note:: This API has changed significantly recently. See :doc:`the changelog <../upgrading>` for details. The following objects offer the core bindings to the Tkhtml3 HTML widget and are largely internal. You will likely never need to access them, but they are described here just in case. Refer to the `Tkhtml Documentation `_ for more details on some of the commands. .. autoclass:: tkinterweb.TkinterWeb :members: .. autoclass:: tkinterweb.TkHtmlParsedURI :members: ================================================ FILE: docs/source/api.rst ================================================ API Reference ============== .. note:: The API changed significantly in version 4. See :doc:`the changelog ` for details. .. toctree:: :maxdepth: 2 :caption: Available Classes api/htmlframe api/htmldocument api/jsengine api/notebook ------------------- .. toctree:: :maxdepth: 3 api/tkinterweb ================================================ FILE: docs/source/caret.rst ================================================ Making Documents Editable ========================= .. note:: Caret browsing support is new in version 4.8. The :class:`~tkinterweb.HtmlText` widget was made editable in version 4.15. Make sure you are using the latest version of TkinterWeb. Overview -------- **TkinterWeb can be used to create a rich text or HTML editor.** The :class:`~tkinterweb.HtmlText` widget provides a simple HTML editor that can be extended to adapt to the needs of your application. TkinterWeb also provides a useful API for developers to create their own HTML-based what-you-see-is-what-you-get editor. These features are new. Please reach out to report a bug, suggest an improvement, or seek support. Setup ------ To enable caret browsing mode, add ``yourhtmlframe.configure(caret_browsing_enabled=True)`` to your script or add the parameter ``caret_browsing_enabled=True`` when creating your :class:`~tkinterweb.HtmlFrame` or :class:`~tkinterweb.HtmlLabel` widget. When enabled, a caret will appear once the user clicks on text in the document. Use the methods described below to handle keypresses, or instead use the :class:`~tkinterweb.HtmlText` widget which handles most cases on its own. How-to ------ Simply create your :class:`~tkinterweb.HtmlText` and start editing! .. code-block:: python from tkinterweb import HtmlText yourhtmlframe = HtmlText(root, messages_enabled=True) You can also load html, files, and websites. For instance, to create an editable page with a heading, an orange block, and a list, you could use the following: .. code-block:: python yourhtmlframe = HtmlText(root, messages_enabled=True) yourhtmlframe.load_html("""

Hello, world!

Tkinter is so cool.
  • TkinterWeb is also cool
  • Python is also cool
""") .. image:: ./_static/text_widget.png It's that easy! You can insert and edit hyperlinks, images, and much more. Click on a hyperlink while pressing the Ctrl key to navigate to it. Like the :class:`~tkinterweb.HtmlFrame` widget, the :class:`~tkinterweb.HtmlText` widget is also scrollable out of the box! You can also use :meth:`.HtmlText.insert` and :meth:`.HtmlText.delete` to easily modify the document. Customization ------------- Everything described below applies to all HTML widgets with caret browsing enabled. Use :meth:`.HtmlFrame.get_caret_position` to get the caret's position. The element returned will always be a text node. .. tip:: You can use the methods outlined in the `HTMLElement documentation `_ to get the element's parent if needed. From here you can insert new elements, change the text and much more! Use :meth:`.HtmlFrame.shift_caret_left` or :meth:`.HtmlFrame.shift_caret_right` to shift the caret left or right. The following is a simple example showing how to handle keypresses to insert letters and numbers: .. code-block:: python def on_keypress(event): # Get the caret's position caret_position = yourhtmlframe.get_caret_position() if caret_position and event.char: element, text, index = caret_position # Add the key's character to the element's text newtext = text[:index] + event.char + text[index:] # Set the element's text element.textContent = newtext # Shift the caret right yourhtmlframe.shift_caret_right() yourhtmlframe.bind("", on_keypress) This works on all HTML widgets. .. warning:: If using the :class:`~tkinterweb.HtmlText` widget, binding to ```` will remove all default key bindings. Either bind to individual keys as needed or use ``yourhtmlframe.bind("", on_keypress, add="+")``, but keep in mind then both bindings will fire. .. note:: Most HTML elements collapse spaces. To insert a space into the document's text, it is usually best to use a non-breaking space (``"\xa0"`` or ``" "``). Use :meth:`.HtmlFrame.set_caret_position` to set the caret's position if you know the element and index you want to place the caret at. Some extra logic will be needed to handle other types of keypresses. See the :class:`~tkinterweb.HtmlText` source code for inspiration. .. tip:: When handling backspaces at the start of a node or deletions at the end of a node, it is sometimes useful to find the previous or following text nodes, respectively. You can get the preceeding or following text nodes by using :meth:`.HtmlFrame.shift_caret_left` or :meth:`.HtmlFrame.shift_caret_right` followed by :meth:`.HtmlFrame.get_caret_position`. Use :meth:`.HtmlFrame.get_selection_position` to get the position of any selected text and :meth:`.HtmlFrame.clear_selection` to clear the selection. You may need to set the caret's position after modifying the document. .. tip:: :meth:`.HtmlFrame.set_caret_position` will raise an error if the element provided has been removed or is empty. If you need to remove or empty the elements returned by :meth:`.HtmlFrame.get_selection_position` or :meth:`.HtmlFrame.get_caret_position`, you can also get the selection or caret's position relative to the page text content using :meth:`HtmlFrame.get_selection_position(return_elements=False) <.HtmlFrame.get_selection_position>` and :meth:`HtmlFrame.get_caret_position(return_element=False) <.HtmlFrame.get_caret_position>`, respectively. You can then set the selection or caret's position as usual, providing only indexes (i.e. ``yourhtmlframe.set_selection_position(start_index=5, end_index=10)``. The following code can be used as a starting point on handling backspaces when text is selected: .. code-block:: python def on_backspace(event): # Get the selection's position and deselect all selected text selection = yourhtmlframe.get_selection_position() if selection: start, end, middle = selection start_element, start_element_text, start_element_index = start end_element, end_element_text, end_element_index = end # Deselect all selected text d.clear_selection() # Cut out the selection start_element.textContent = start_element_text[:start_element_index] + start_element_text[end_element_index:] if start_element != end_element: # Delete the end element end_element.remove() # Remove each element that is fully selected, and its parent if it is now empty for element in middle: parent = element.parentElement element.remove() if len(parent.children) == 0: parent.remove() # Set the caret's position yourhtmlframe.set_caret_position(start_element, start_element_index) yourhtmlframe.bind("", on_backspace) You can use :meth:`.HtmlFrame.set_selection_position` to set the selection if needed. ------------------- See the `HtmlFrame documentation `_ for a complete list of supported methods. Please report bugs or request new features on the `issues page `_. ================================================ FILE: docs/source/compatibility.rst ================================================ System and Webpage Compatibility ================================ System compatibility -------------------- **TkinterWeb supports all platforms but only ships with precompiled Tkhtml binaries for the most common platforms:** * x86_64 Windows, Linux, and macOS * i686 Windows and Linux * ARM64 Macos and Linux * ARMv71 Linux If your system is unsupported, compile and install Tkhtml by visiting and cloning https://github.com/Andereoo/TkinterWeb-Tkhtml. Then run ``python compile.py --install``. Alternatively, you can install Tkhtml system-wide (i.e. through your system package manager) and then add the parameter :attr:`use_prebuilt_tkhtml=False` when creating your :class:`~tkinterweb.HtmlFrame`, :class:`~tkinterweb.HtmlLabel`, or :class:`~tkinterweb.HtmlText` widget to use the system's Tkhtml. Keep in mind that some features will no longer work. If you are encountering issues, feel free to submit a bug report or feature request. The experimental Tkhtml version is not provided as a pre-built binary but can be compiled from the source code at https://github.com/Andereoo/TkinterWeb-Tkhtml/tree/experimental. This version has better cross-platform compatibility, is printable, and introduces support for some new CSS3 properties! Webpage compatibility --------------------- **HTML & CSS:** * TkinterWeb supports HTML 4.01 and CSS 2.1. A full list of supported CSS declarations can be found at `http://tkhtml.tcl.tk/support.html `_. * Most CSS pseudo-elements, such as ``:hover`` and ``:active`` are also supported. * On 64-bit Windows and Linux, if the `TkinterWeb-Tkhtml-Extras `_ package is installed, HTML5 tags and some extra CSS properties (including ``border-radius`` and ``overflow-x``) and cursors are also supported. To use these features on all other platforms, you will simply need to compile Tkhtml yourself. Visit and clone https://github.com/Andereoo/TkinterWeb-Tkhtml. Then run ``python compile.py --install``. **JavaScript:** * JavaScript partly supported at the moment. See :doc:`javascript` for more information. * To use JavaScript, `PythonMonkey `_ must be installed. * It is also possible for the user to connect their own JavaScript interpreter or manipulate the document through Python. See :doc:`javascript` and :doc:`dom` for more information. **Images:** * TkinterWeb supports nearly 50 different image types through `PIL `_. * In order to load Scalable Vector Graphic images, `CairoSVG `_, `PyGObject `_, or both :py:mod:`PyCairo` and :py:mod:`Rsvg` must also be installed. ------------------- Please report bugs or request new features on the `issues page `_. ================================================ FILE: docs/source/conf.py ================================================ # Configuration file for the Sphinx documentation builder. # -- Project information import os import sys sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname((os.path.realpath(__file__)))))) from tkinterweb import __title__, __copyright__, __author__, __version__ project = __title__ copyright = __copyright__ author = __author__ release = ".".join(__version__.split(".")[:2]) version = __version__ # -- General configuration extensions = [ 'sphinx.ext.duration', 'sphinx.ext.doctest', 'sphinx.ext.autodoc', 'sphinx.ext.autosummary', 'sphinx.ext.intersphinx', "sphinx_design", ] intersphinx_mapping = { 'python': ('https://docs.python.org/3/', None), 'sphinx': ('https://www.sphinx-doc.org/en/master/', None), } html_logo = "_static/logo.png" html_theme_options = {"logo_only": True} templates_path = ['_templates'] html_static_path = ['_static'] html_css_files = ['custom.css'] # -- Options for HTML output autodoc_member_order = 'bysource' html_theme = 'sphinx_rtd_theme' # May switch to agogo or alabaster or python_docs_theme # -- Options for EPUB output epub_show_urls = 'footnote' def skip_member(app, what, name, obj, skip, options): if name == "destroy" and what == "class": return True return skip def setup(app): app.connect("autodoc-skip-member", skip_member) ================================================ FILE: docs/source/dom.rst ================================================ Manipulating the Page ===================== .. note:: The API changed significantly in version 4. See :doc:`the changelog ` for details. Overview -------- **TkinterWeb provides a handful of functions that allow for manipulation of the webpage. They are fashioned after common JavaScript functions.** How-to -------- To manipulate the Document Object Model, use the :attr:`~tkinterweb.HtmlFrame.document` property of your :class:`~tkinterweb.HtmlFrame` or :class:`~tkinterweb.HtmlLabel` widget. For example, to create a heading with blue text inside of an element with the id "container", one can use the following: .. code-block:: python yourhtmlframe = tkinterweb.HtmlFrame(root, messages_enabled=True) yourhtmlframe.load_html("

Test

") container = yourhtmlframe.document.getElementById("container") new_header = yourhtmlframe.document.createElement("h1") new_header.textContent = "Hello, world!" new_header.style.color = "blue" container.appendChild(new_header) .. _binding-to-an-element: Binding to an element --------------------- To manage bindings on HTML elements, simply use :meth:`~tkinterweb.dom.HTMLElement.bind` and :meth:`~tkinterweb.dom.HTMLElement.unbind` (new in version 4.9): .. code-block:: python container = yourhtmlframe.document.getElementById("container") def callback(event): print("Woah this is cool!") container.bind("", callback) ------------------- See the :doc:`api/htmldocument` for a complete list of supported commands. See :doc:`javascript` for information on manipulating the DOM through JavaScript. Please report bugs or request new features on the `issues page `_. ================================================ FILE: docs/source/faq.rst ================================================ Frequently Asked Questions ========================== How do I load websites or files? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Use the :meth:`~tkinterweb.HtmlFrame.load_website` or :meth:`~tkinterweb.HtmlFrame.load_file` commands. Alternatively, use the :meth:`~tkinterweb.HtmlFrame.load_url` command to load any generic url, but keep in mind that the url must be properly formatted, because the url scheme will not be automatically applied. As always, check out the :doc:`api/htmlframe` for more information. How do I manage clicks and use custom bindings? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * The :attr:`on_link_click` configuration option can be used to assign a custom function to link clicks. Likewise :attr:`on_form_submit` can be used to handle form submissions. See the :doc:`api/htmlframe` for more information. * Like any other Tkinter widget, mouse and keyboard events can be bound to the :class:`~tkinterweb.HtmlFrame` widget and associated HTML elements. See the :doc:`usage` page for more information. TkinterWeb is crashing ~~~~~~~~~~~~~~~~~~~~~~ * That is defenitely not normal. Make sure your are using the most up-to-date TkinterWeb version and have crash protection enabled. * If you are using a :py:class:`ttk.Notebook` in your app, see the question below. * If all else fails, `file a bug report `_. Post your operating system, Python version, and TkinterWeb version, as well as any error codes or instructions for reproducing the crash. I'm having issues when using shrink or the HtmlLabel widget ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * See :doc:`shrink` for more information. My app crashes when I open a tab with an HtmlFrame in it ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Tkhtml (the underlying HTML engine) and the :py:class:`ttk.Notebook` widget aren't compatable on 64-bit Windows. * This is a known issue. Fixing this is beyond the scope of this project, but working around it is easy. * Instead of using :py:class:`ttk.Notebook`, use :class:`tkinterweb.Notebook`. This is a wrapper around ttk.Notebook that is designed to be a drop-in replacement for the :py:class:`ttk.Notebook` widget. It should look and behave exactly like a :py:class:`ttk.Notebook` widget, but without the crashes. See `bug #19 `_ for more information. * Please note that after adding a widget to the Notebook (eg. ``mynotebook.add(mywidget)``) there is no need to call :py:func:`~tkinterweb.Widget.pack` or :py:func:`~tkinterweb.Widget.grid` the widget. This may raise errors. TkinterWeb's Notebook widget handles all this on its own. I get a ModuleNotFoundError after compiling my code ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * When compiling your code, you might get an error popup saying ``ModuleNotFoundError: The files required to run TkinterWeb could not be found`` * Your app might also fail quietly if TkinterWeb's dependencies are not installed * This occurs when your Python script bundler isn't finding all the files nessessary for running TkinterWeb. You need to force it to get all of TkinterWeb's files and dependencies. * On PyInstaller: make sure you are using the latest version of PyInstaller by running ``pip install --upgrade pyinstaller pyinstaller-hooks-contrib``. Otherwise, you can also add the flags ``--collect-all tkinterweb --collect-all tkinterweb_tkhtml --collect-all tkinterweb_tkhtml_extras`` when bundling your app. * On py2app / py2exe: Add ``'packages': ['tkinterweb', 'tkinterweb_tkhtml', 'tkinterweb_tkhtml_extras']`` to the ``OPTIONS`` variable in your setup file. ------------------- Please report bugs or request new features on the `issues page `_. ================================================ FILE: docs/source/geometry.rst ================================================ Embedding Widgets ================= .. note:: The API changed significantly in version 4. See :doc:`the changelog ` for details. Overview -------- By default, Tkinter provides three geometry managers: pack, place, and grid. While these geometry managers are very powerful, achieving certain layouts, especially with scrolling, can be very difficult. **TkinterWeb provides a system for attaching Tkinter widgets onto the window, and handles layouts, images, selection, scrolling, and much more for you.** How-to ------ To place a Tkinter widget inside an HTML document, add the ``data=[yourwidget]`` attribute to an ```` element. For example, to add a button under some italic text, one could do: .. code-block:: python yourframe = tkinterweb.HtmlFrame(root, messages_enabled=True) yourbutton = tkinter.Button(yourframe, text="Hello, world!") source_html = f"This is some text
" yourframe.load_html(source_html) # or use add_html to add onto the existing document **Ensure your HtmlFrame widget was created before the widget you are embedding, or else the widget might not be visible.** .. tip:: Add the ``allowstyling`` attribute to automatically change the widget's background color, text color, and font to match the containing HTML element. Use ``allowstyling="deep"`` to also style subwidgets (new in version 4.9). Add the ``handledelete`` attribute to automatically call :meth:`~tkinter.Widget.destroy` on the widget when it is removed from the page (i.e. if another webpage is loaded). .. note:: By default, scrolling over an embedded widget will scroll the page if the widget or subwidgets do not handle scrolling themselves (new in version 4.9). You can override this behaviour by adding the ``allowscrolling`` or ``allowscrolling=false`` attribute. Widget position and sizing can be modified using CSS styling on the widget's associated ```` element. See :doc:`dom` (new in version 3.25) for more details. To get the element containing your widget, either use :meth:`.HtmlFrame.widget_to_element`. Widget handling --------------- You can also set, remove, or change the widget in any element later (new in version 4.2): .. code-block:: python yourbutton = tkinter.Button(yourframe, text="Hello, world!") ... yourelement = yourframe.document.getElementById("#container") # get the element to fill yourelement.widget = yourbutton # set the element's widget The widget can be removed from the element via ``yourelement.widget = None``. ------------------- Please report bugs or request new features on the `issues page `_. ================================================ FILE: docs/source/index.rst ================================================ Welcome to TkinterWeb! ====================== .. image:: https://static.pepy.tech/badge/tkinterweb/month :target: https://pepy.tech/project/tkinterweb :alt: PyPi Downloads .. image:: https://img.shields.io/pypi/l/tkinterweb :target: https://pypi.org/project/tkinterweb/ :alt: MIT Licence .. image:: https://img.shields.io/pypi/pyversions/tkinterweb :target: https://pypi.org/project/tkinterweb/ :alt: Python 3 .. image:: https://img.shields.io/badge/%F0%9F%87%A8%F0%9F%87%A6%20made%20in%20Canada-grey :target: https://pypi.org/project/tkinterweb/ :alt: Made in Canada **TkinterWeb** is a Python library that adds HTML and CSS rendering capabilities to Tkinter widgets. Common use cases include displaying help files, documentation, and other HTML content, rendering images (including SVG), building rich-text editors, designing apps with HTML templates, and creating more modern-looking interfaces, with advanced styling and even round buttons! Getting started --------------- TkinterWeb provides a `frame widget <./api/htmlframe.html>`_, a `label widget <./api/htmlframe.html#tkinterweb.HtmlLabel>`_, and a `text widget <./api/htmlframe.html#tkinterweb.HtmlText>`_. Check out the :doc:`usage` section to learn how to get started and discover tips and tricks, :doc:`faq` for frequently asked questions, and the :doc:`api` to explore all of the widgets and functions at your disposal! Love this project? ------------------ You can help this project by submitting a `bug report `_ to report bugs or suggest new features, or by submitting a `pull request `_ to offer fixes. Your help makes TkinterWeb become more stable and full-featured! ☕ Or, if you’d like to support ongoing development and maintenance, please consider supporting this project by `buying me a coffee `_. Any amount is hugely appreciated! This project is released under the `MIT License `_ and is free to use, including for commercial purposes. If you use this project in a commercial product or derive financial benefit from it, please kindly consider supporting its development with a donation. This helps cover maintenance time and ongoing improvements, which in turn will improve your own software! .. raw:: html Buy Me A Coffee Pages ----- .. toctree:: :maxdepth: 1 usage geometry dom caret shrink javascript faq compatibility upgrading api ================================================ FILE: docs/source/javascript.rst ================================================ Using JavaScript ================ .. note:: JavaScript support is new in version 4.1. Embedded Python support is new in version 4.19. Make sure you are using the latest version of TkinterWeb. Overview -------- **Scripting support makes it easy to embed JavaScript or Python code in your document.** JavaScript is fully supported through Mozilla's SpiderMonkey engine, but not all DOM commands are supported. See the :doc:`api/htmldocument` for an exhaustive list of supported DOM commands. Setup ------ To enable JavaScript support in TkinterWeb, first install `PythonMonkey `_ using pip: .. code-block:: console $ pip install pythonmonkey Skip this step if you are embedding Python code in your document. Or when installing TkinterWeb, use: .. code-block:: console $ pip install tkinterweb[javascript] Then add ``yourhtmlframe.configure(javascript_enabled=True)`` to your script or add the parameter ``javascript_enabled=True`` when creating your :class:`~tkinterweb.HtmlFrame`, :class:`~tkinterweb.HtmlLabel`, or :class:`~tkinterweb.HtmlText` widget. .. note:: If using Windows, ensure you are using an up-to-date Python version. In some Python versions prior to version 3.13, Python will crash when loading PythonMonkey. **Only enable JavaScript in documents with code you know and trust.** How-to ------ To change the color and text of a ``

`` element when clicked, you could use the following: .. code-block:: python yourhtmlframe = tkinterweb.HtmlFrame(root, messages_enabled=True, javascript_enabled=True) yourhtmlframe.load_html("""

Hello, world!

""") Add the ``defer`` attribute to the relevant ``

Hello, world!

") Using your own interpreter -------------------------- Alternatively, you can register your own callback for ``

Test

") You can also use the :attr:`on_element_script` parameter to handle event scripts (i.e. handle an element's ``onclick`` attribute). The element's corresponding Tkhtml node, relevant event, and code to execute will be passed as parameters. If needed you can always then create an :class:`~tkinterweb.dom.HTMLElement` instance from a Tkhtml node: .. code-block:: python from tkinterweb.dom import HTMLElement ... yourhtmlelement = HTMLElement(yourhtmlframe.document, yourtkhtmlnode) ------------------- It is also possible to interact with the document through Python instead. See :doc:`dom`. Please report bugs or request new features on the `issues page `_. ================================================ FILE: docs/source/shrink.rst ================================================ Creating a Label Widget ======================= .. note:: This API changed in version 4.17. See :doc:`the changelog ` for details. Overview -------- **Shrink makes HTML widgets behave like label widgets, automatically resizing to match their content.** How-to ------ Use the :class:`.HtmlLabel` widget or add the parameter ``shrink=True`` to the :class:`.HtmlFrame` widget. Your widget will now shrink to match its content! .. tip:: Use the :class:`.HtmlLabel` widget if you want an HTML widget that looks and behaves like a ttk Label. Use the :class:`.HtmlFrame` widget if you want full control. Tips and tricks --------------- Word wrapping ~~~~~~~~~~~~~ By default, word wrapping is disabled when shrink is enabled. This forces text to keep inline, which is generally expected from label-like widgets, and prevents a number of bugs that cause the widget to shake or wrap when it shouldn't. .. note:: Full shrink word wrapping support is currently only rolled out to 64-bit Windows and Linux users. Ensure you installed TkinterWeb via ``pip install tkinterweb[recommended]`` or ``pip install tkinterweb[full]`` to prevent bugs when using shrink. If you are encountering issues on an unsupported platform, either submit a feature request or compile and install Tkhtml 3.1 by visiting and cloning https://github.com/Andereoo/TkinterWeb-Tkhtml. Then run ``python compile.py --install``. If you need word wrapping, you can re-enable it by using ``HtmlFrame(..., textwrap=True)``. It is a known issue that when word wrapping is enabled and the widget is shrunk it will often not re-expand. You will need to signal to the geometry manager that the widget should expand, or use the experimental ``HtmlFrame.unshrink = True`` (not recommended). Height and width ~~~~~~~~~~~~~~~~ Since the purpose of shrink is to automatically resize the widget according to its content, height and width have little effect. If you need to set the height and width, simply disable shrink. Scrollbars ~~~~~~~~~~ Scrollbars are disabled by default when shrink is enabled. Use ``HtmlFrame(..., vertical_scrollbar="auto", horizontal_scrollbar="auto")`` to enable them. ------------------- Please report bugs or request new features on the `issues page `_. ================================================ FILE: docs/source/upgrading.rst ================================================ Changelog ========= **The API changed significantly in version 4.** .. dropdown:: Key Changes :open: :color: primary * Faster load speed * A more intuitive API * Support for experimental Tkhtml features, such as page printing * Widget behaviour and API is now more closely aligned with standard Tkinter widgets * Many DOM improvements. The DOM API now more closely mirrors its JavaScript counterpart. * Dozens of new configuration options, including access to more settings and the ability to link a JavaScript interpreter * Added basic JavaScript support (new in version 4.1) * Improved embedded widget handling (new in version 4.2) * Cross-platform SVG and ``border-radius`` support (new in version 4.4) * Support for Tcl 9 (new in version 4.5) * Caret browsing functionality (new in version 4.8) * Improved thread safety (new in version 4.9) * Ability to bind to HTML elements (new in version 4.10) * Added an HTML-based text widget (new in version 4.15) .. dropdown:: Removed Version 4.0: * ``HtmlFrame.get_zoom()`` - use ``HtmlFrame.cget("zoom")`` * ``HtmlFrame.set_zoom()`` - use ``HtmlFrame.configure(zoom=)`` * ``HtmlFrame.get_fontscale()`` - use ``HtmlFrame.cget("fontscale")`` * ``HtmlFrame.set_fontscale()`` - use ``HtmlFrame.configure(fontscale=)`` * ``HtmlFrame.get_parsemode()`` - use ``HtmlFrame.cget("parsemode")`` * ``HtmlFrame.set_parsemode()`` - use ``HtmlFrame.configure(parsemode=)`` * ``HtmlFrame.set_message_func()`` - use ``HtmlFrame.configure(message_func=)`` * ``HtmlFrame.set_broken_webpage_message()`` - use ``HtmlFrame.configure(on_navigate_fail=)``. Note that :attr:`on_navigate_fail` requires a function instead. * ``HtmlFrame.set_maximum_thread_count()`` - use ``HtmlFrame.configure(threading_enabled=)`` * ``HtmlFrame.set_recursive_hover_depth()`` - use ``HtmlFrame.html.recursive_hover_depth=`` * ``HtmlFrame.add_visited_links()`` - use ``HtmlFrame.configure(visited_links=)`` * ``HtmlFrame.clear_visited_links()`` - use ``HtmlFrame.configure(visited_links=)`` * ``HtmlFrame.enable_stylesheets()`` - use ``HtmlFrame.configure(stylesheets_enabled=)`` * ``HtmlFrame.enable_images()`` - use ``HtmlFrame.configure(images_enabled=)`` * ``HtmlFrame.enable_forms()`` - use ``HtmlFrame.configure(forms_enabled=)`` * ``HtmlFrame.enable_objects()`` - use ``HtmlFrame.configure(objects_enabled=)`` * ``HtmlFrame.enable_caches()`` - use ``HtmlFrame.configure(caches_enabled=)`` * ``HtmlFrame.enable_dark_theme()`` - use ``HtmlFrame.configure(dark_theme_enabled=, image_inversion_enabled=)`` * ``HtmlFrame.on_image_setup()`` - use ``HtmlFrame.configure(on_resource_setup=)`` * ``HtmlFrame.on_downloading_resource()`` - bind to ``<>``/:py:attr:`utilities.DOWNLOADING_RESOURCE_EVENT` * ``HtmlFrame.on_done_loading()`` - bind to ``<>``/:py:attr:`utilities.DONE_LOADING_EVENT` * ``HtmlFrame.on_url_change()`` - bind to ``<>``/:py:attr:`utilities.URL_CHANGED_EVENT and use :attr:`.HtmlFrame.current_url` * ``HtmlFrame.on_icon_change()`` - bind to ``<>``/:py:attr:`utilities.ICON_CHANGED_EVENT` and use :attr:`.HtmlFrame.title` * ``HtmlFrame.on_title_change()`` - bind to ``<>``/:py:attr:`utilities.TITLE_CHANGED_EVENT` and use :attr:`.HtmlFrame.title` * ``HtmlFrame.on_form_submit()`` - use ``HtmlFrame.configure(on_form_submit=)`` * ``HtmlFrame.on_link_click()`` - use ``HtmlFrame.configure(on_link_click=)`` * ``HtmlFrame.yview_toelement()`` - use :meth:`.HTMLElement.scrollIntoView` * ``HtmlFrame.get_currently_hovered_node_text()`` - :meth:`.HtmlFrame.get_currently_hovered_element` * ``HtmlFrame.get_currently_hovered_node_tag()`` - :meth:`.HtmlFrame.get_currently_hovered_element` * ``HtmlFrame.get_currently_hovered_node_attribute()`` - :meth:`.HtmlFrame.get_currently_hovered_element` * ``HtmlFrame.get_current_link()`` - use :meth:`.HtmlFrame.get_currently_hovered_element` * The ``widgetid`` attribute no longer embeds widgets. Use ```` or :attr:`.HTMLElement.widget` instead. This improves load speeds and allows for widget style handling. Version 4.2: * ``TkinterWeb.replace_widget()`` * ``TkinterWeb.replace_element()`` * ``TkinterWeb.remove_widget()`` Version 4.8 * ``HtmlFrame.replace_widget()`` (deprecated in version 4.0) - use :meth:`.HtmlFrame.widget_to_element` and :attr:`.HTMLElement.widget` * ``HtmlFrame.replace_element()`` (deprecated in version 4.0) - use :attr:`.HTMLElement.widget` * ``HtmlFrame.remove_widget()`` (deprecated in version 4.0) - use :meth:`.HTMLElement.remove` Version 4.14: * The ``style`` configuration option no longer sets the CSS style of :class:`.HtmlLabel` widgets. See `bug #145 `_. .. dropdown:: Deprecated Version 4.11: * ``TkinterWeb.update_tags()`` - use :meth:`.SelectionManager.update_tags` * ``TkinterWeb.select_all()`` - use :meth:`.SelectionManager.select_all` * ``TkinterWeb.clear_selection()`` - use :meth:`.SelectionManager.clear_selection` * ``TkinterWeb.update_selection()`` - use :meth:`.SelectionManager.update_selection` * ``TkinterWeb.get_selection()`` - use :meth:`.SelectionManager.get_selection` * ``TkinterWeb.copy_selection()`` - use :meth:`.SelectionManager.copy_selection` * ``TkinterWeb.allocate_image_name()`` - use :meth:`.ImageManager.allocate_image_name` * ``TkinterWeb.handle_node_replacement()`` - use :meth:`.WidgetManager.handle_node_replacement` * ``TkinterWeb.map_node()`` - use :meth:`.WidgetManager.map_node` * ``TkinterWeb.find_text()`` - use :meth:`.SearchManager.find_text` * ``TkinterWeb.send_onload()`` - use :meth:`.EventManager.send_onload` Version 4.12: * ``Htmlframe.register_JS_object()`` - use :meth:`.JSEngine.register` Version 4.14: * The configuration option ``default_style`` - use ``tkinterweb.utilities.DEFAULT_STYLE`` or the ``defaultstyle`` configuration option. * The configuration option ``dark_style`` - use ``tkinterweb.utilities.DARK_STYLE`` or the ``defaultstyle`` configuration option. * The configuration option ``about_page_background`` - use ``ttk.Style().configure("TFrame", background=)``. * The configuration option ``about_page_foreground`` - use ``ttk.Style().configure("TFrame", foreground=)``. Version 4.16: * :meth:`.HtmlFrame.get_caret_page_position` - use :meth:`HtmlFrame.get_caret_position(return_element=False) <.HtmlFrame.get_caret_position>` * :meth:`.HtmlFrame.set_caret_page_position` - use :meth:`HtmlFrame.set_caret_position(index=) <.HtmlFrame.set_caret_position>` * :meth:`.HtmlFrame.get_selection_page_position` - use :meth:`HtmlFrame.get_selection_position(return_elements=False) <.HtmlFrame.get_selection_position>` * :meth:`.HtmlFrame.set_selection_page_position` - use :meth:`HtmlFrame.set_selection_position(start_index=, end_index=) <.HtmlFrame.set_selection_position>` Version 4.22: * :meth:`.HtmlFrame.insert_html` - use :meth:`.HtmlFrame.add_html` .. dropdown:: Renamed Version 4.0: * ``HtmlFrame.get_currently_selected_text()`` -> :meth:`.HtmlFrame.get_selection` * ``TkwDocumentObjectModel`` -> :class:`.HTMLDocument` * ``HtmlElement`` -> :class:`.HTMLElement` * ``HtmlElement.style()`` -> :attr:`.HTMLElement.style` * ``HtmlElement.innerHTML()`` -> :attr:`.HTMLElement.innerHTML` * ``HtmlElement.textContent()`` -> :attr:`.HTMLElement.textContent` * ``HtmlElement.attributes()`` -> :attr:`.HTMLElement.attributes` * ``HtmlElement.tagName()`` -> :attr:`.HTMLElement.tagName` * ``HtmlElement.parentElement()`` -> :attr:`.HTMLElement.parentElement` * ``HtmlElement.children()`` -> :attr:`.HTMLElement.children` * The ``scroll-x`` attribute was changed to the ``tkinterweb-scroll-x`` attribute. Like the ``overflow`` CSS property, valid options are now "auto", "visible", "clip", "scroll", and "hidden". .. dropdown:: Added Version 4.0: * :meth:`.HtmlFrame.clear_selection` * :meth:`.HtmlFrame.get_currently_hovered_element` * :meth:`.HtmlFrame.save_page` * :meth:`.HtmlFrame.snapshot_page` * :meth:`.HtmlFrame.show_error_page` * :meth:`.HtmlFrame.print_page` * :meth:`.HtmlFrame.screenshot_page` * :attr:`.HtmlFrame.base_url` * :attr:`.HtmlFrame.icon` * :attr:`.HtmlFrame.title` * :meth:`.HTMLElement.getElementById` * :meth:`.HTMLElement.getElementsByClassName` * :meth:`.HTMLElement.getElementsByName` * :meth:`.HTMLElement.getElementsByTagName` * :meth:`.HTMLElement.querySelector` * :meth:`.HTMLElement.querySelectorAll` * :meth:`.HTMLElement.scrollIntoView` * :class:`.CSSStyleDeclaration` * :attr:`.CSSStyleDeclaration.*` (any camel-case CSS property) * :attr:`.CSSStyleDeclaration.cssText` * :attr:`.CSSStyleDeclaration.length` * :attr:`.CSSStyleDeclaration.cssProperties` * :attr:`.CSSStyleDeclaration.cssInlineProperties` * :meth:`.TkinterWeb.enable_imagecache` * :meth:`.TkinterWeb.destroy_node` * :meth:`.TkinterWeb.get_node_properties` * :meth:`.TkinterWeb.override_node_properties` * :meth:`.TkinterWeb.update_tags` * ``utilities.DOWNLOADING_RESOURCE_EVENT`` (equivalent to ``<>``) * ``utilities.DONE_LOADING_EVENT`` (equivalent to ``<>``) * ``utilities.URL_CHANGED_EVENT`` (equivalent to ``<>``) * ``utilities.ICON_CHANGED_EVENT`` (equivalent to ``<>``) * ``utilities.TITLE_CHANGED_EVENT`` (equivalent to ``<>``) * Many new configuration options were added. See the :doc:`api/htmlframe` for a complete list. * The ``tkinterweb-full-page`` attribute can now be added to elements to make them the same height as the viewport. Use this to align content vertically. This has no effect when shrink is enabled. Version 4.1: * :meth:`.HtmlFrame.register_JS_object`` * :attr:`.HTMLElement.widget` (updated again in version 4.2) * :attr:`.HTMLElement.value` * :attr:`.HTMLElement.checked` * :attr:`.HTMLElement.onchange` * :attr:`.HTMLElement.onload` * :attr:`.HTMLElement.onclick` * :attr:`.HTMLElement.oncontextmenu` * :attr:`.HTMLElement.ondblclick` * :attr:`.HTMLElement.onmousedown` * :attr:`.HTMLElement.onmouseenter` * :attr:`.HTMLElement.onmouseleave` * :attr:`.HTMLElement.onmousemove` * :attr:`.HTMLElement.onmouseout` * :attr:`.HTMLElement.onmouseover` * :attr:`.HTMLElement.onmouseup` * :attr:`.CSSStyleDeclaration.setProperty` * :attr:`.CSSStyleDeclaration.getPropertyValue` * :attr:`.CSSStyleDeclaration.removeProperty` * :meth:`.TkinterWeb.send_onload` * Added support for many JavaScript events. * The new configuration option ``on_element_script`` can be used to add a callback to run when a JavaScript event attribute on an element is encountered. * The new configuration option ``javascript_enabled`` can be used to enable JavaScript support. Version 4.2: * :meth:`.HtmlFrame.widget_to_element` * :meth:`.TkinterWeb.replace_node_contents` * :meth:`.TkinterWeb.map_node` * :meth:`.TkinterWeb.replace_node_with_widget` * :meth:`.TkinterWeb.get_node_stacking` Version 4.4: * :class:`.HtmlParse` * :class:`.TkHtmlParsedURI` * :class:`.HTMLCollection` * :meth:`.HtmlFrame.insert_html` * :attr:`.HTMLElement.id` * :attr:`.HTMLElement.className` * :meth:`.TkinterWeb.override_node_CSS` * :meth:`.TkinterWeb.write` * :meth:`.TkinterWeb.get_child_text` * :meth:`.TkinterWeb.safe_tk_eval` * :meth:`.TkinterWeb.serialize_node` * :meth:`.TkinterWeb.serialize_node_style` * Added support for the HTML number input. * The new configuration option ``tkhtml_version`` can be used to choose a specific Tkhtml version to load. Version 4.5: * The new configuration option ``ssl_cafile`` can be used to provide a path to a CA Certificate file. See `bug #28 `_. Version 4.6: * The new configuration option ``request_timeout`` can be used to specify the number of seconds to wait before a request times out. Version 4.7: * The new ``<>`` event will be generated once the page DOM content has loaded. The page may not be done loading, but at this point it is possible to interact with the DOM. Version 4.8: * :meth:`.HtmlFrame.get_page_text` * :meth:`.HtmlFrame.get_caret_position` * :meth:`.HtmlFrame.get_caret_page_position` (deprecated in version 4.16) * :meth:`.HtmlFrame.set_caret_position` * :meth:`.HtmlFrame.set_caret_page_position` (deprecated in version 4.16) * :meth:`.HtmlFrame.shift_caret_left` * :meth:`.HtmlFrame.shift_caret_right` * :meth:`.HtmlFrame.get_selection_position` * :meth:`.HtmlFrame.get_selection_page_position` (deprecated in version 4.16) * :meth:`.HtmlFrame.set_selection_position` * :meth:`.HtmlFrame.set_selection_page_position` (deprecated in version 4.16) * :attr:`.HTMLElement.previousSibling` * :attr:`.HTMLElement.nextSibling` * :attr:`.TkinterWeb.caret_manager` * :meth:`.TkinterWeb.update_selection` * :meth:`.TkinterWeb.tkhtml_offset_to_text_index` * :class:`.CaretManager` * The new configuration option ``caret_browsing_enabled`` can be used to enable or disable caret browsing mode. Version 4.9: * :meth:`.TkinterWeb.post_to_queue` * :meth:`.TkinterWeb.allocate_image_name` * :meth:`.TkinterWeb.check_images` Version 4.10: * :meth:`.HTMLElement.bind` * :meth:`.HTMLElement.unbind` * :attr:`.TkinterWeb.event_manager` * :class:`.EventManager` * You can now set ``allowstyling="deep"`` on elements with embedded widgets to also style their subwidgets. Version 4.11: * :meth:`.HtmlFrame.unbind` * :class:`.HtmlText` * :attr:`.TkinterWeb.selection_manager` * :attr:`.TkinterWeb.widget_manager` * :attr:`.TkinterWeb.search_manager` * :attr:`.TkinterWeb.script_manager` * :attr:`.TkinterWeb.style_manager` * :attr:`.TkinterWeb.image_manager` * :attr:`.TkinterWeb.object_manager` * :attr:`.TkinterWeb.form_manager` * :attr:`.TkinterWeb.node_manager` * :class:`.SelectionManager` * :class:`.WidgetManager` Version 4.12: * :class:`.JSEngine` Version 4.13: * :meth:`.TkinterWeb.get_node_replacement` Version 4.14: * :attr:`.HTMLElement.innerText` * The new configuration option ``request_func`` can be used to set a custom script to use to download resources. * The new configuration option ``defaultstyle`` can be used to set the default stylesheet to use when parsing HTML. Version 4.15: * :meth:`.HtmlFrame.add_css` now accepts the additional parameter ``priority``. * :meth:`.CaretManager.shift_left`, :meth:`.CaretManager.shift_right`, :meth:`.CaretManager.shift_up`, :meth:`.CaretManager.shift_down`, and :meth:`.CaretManager.shift_update` now accept the additional parameter ``update``. * The :class:`.HtmlText` widget now supports the ``background``, ``foreground``, ``bg``, and ``fg`` keywords. Version 4.16: * :meth:`.HtmlFrame.get_caret_position` now accepts the additional parameter ``return_element``. * :meth:`.HtmlFrame.get_selection_position` now accepts the additional parameter ``return_elements``. * :attr:`.HtmlText.insert` * :attr:`.HtmlText.delete` * The :class:`.HtmlText` widget now supports the ``state`` keyword. * Added introductory support for :class:`.HtmlLabel` and :class:`.HtmlFrame(shrink=True)` widget resizing. This feature is experimental and may change at any time. Set ``HtmlFrame.unshrink = True`` to enable it and let me know how it works! Version 4.17: * The new configuration option ``textwrap`` can be used to enable or disable text wrapping. In general, text wrapping should be disabled when shrink is enabled, and should be enabled when shrink is disabled. This is the default behaviour. This is only partially supported in Tkhtml 3.0; make sure you have the `TkinterWeb-Tkhtml-Extras `_ package installed and up-to-date. Version 4.18: * Added basic support for most HTML5 elements in the corresponding `TkinterWeb-Tkhtml-Extras `_ release (version 1.3.0) * Added support for the HTML ``
``, ````, and ```` tags. Version 4.19: * :meth:`.HtmlFrame.generate_style_report` * :attr:`.TkinterWeb.tkhtml_default_style` * :attr:`.TkinterWeb.images` * :attr:`.TkinterWeb.style_report` * :meth:`.TkinterWeb.decode_uri` * :meth:`.TkinterWeb.encode_uri` * :meth:`.TkinterWeb.escape_uri` * Added support for the ``media`` attribute of ```` elements. Ensure our experimental Tkhtml release is installed. * Added support for the HTML ```` tag. Ensure `TkinterWeb-Tkhtml-Extras `_ is installed. * The new configuration option ``javascript_backend`` can be used to evaluate ``