{"id":21713738,"url":"https://github.com/blurstudio/preditor","last_synced_at":"2026-01-20T02:33:55.154Z","repository":{"id":184611284,"uuid":"672145185","full_name":"blurstudio/PrEditor","owner":"blurstudio","description":"A python REPL and Editor and console based on Qt.","archived":false,"fork":false,"pushed_at":"2026-01-14T00:57:26.000Z","size":3114,"stargazers_count":13,"open_issues_count":3,"forks_count":3,"subscribers_count":3,"default_branch":"main","last_synced_at":"2026-01-14T04:43:01.146Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"lgpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/blurstudio.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2023-07-29T04:26:42.000Z","updated_at":"2026-01-14T00:56:12.000Z","dependencies_parsed_at":"2023-07-29T10:04:48.050Z","dependency_job_id":"0938b62b-a5e9-4622-8f7c-be4104475b9b","html_url":"https://github.com/blurstudio/PrEditor","commit_stats":null,"previous_names":["blurstudio/preditor"],"tags_count":20,"template":false,"template_full_name":null,"purl":"pkg:github/blurstudio/PrEditor","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blurstudio%2FPrEditor","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blurstudio%2FPrEditor/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blurstudio%2FPrEditor/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blurstudio%2FPrEditor/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/blurstudio","download_url":"https://codeload.github.com/blurstudio/PrEditor/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blurstudio%2FPrEditor/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28594942,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-20T02:08:49.799Z","status":"ssl_error","status_checked_at":"2026-01-20T02:08:44.148Z","response_time":117,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-26T00:20:09.513Z","updated_at":"2026-01-20T02:33:55.144Z","avatar_url":"https://github.com/blurstudio.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# PrEditor\n\nA python REPL, editor and console based on Qt. It allows you to interact\ndirectly with the current python session and write/run complex code in workbox's.\nIt also has an interface for configuring python logging.\n\n# Use and Features\n\n![preview](https://github.com/blurstudio/PrEditor/assets/2424292/5425aa5f-0f9b-4b04-8e98-5a58546eb93c)\n\n* **Console:** The top section is a python REPL allowing you to run code like you\nare in the python interactive shell. However, you can't use code\nblocks([...](https://docs.python.org/3/glossary.html#term-...)), use the workbox instead.\n    * Python's stdout and stderr are written here including exceptions.\n    * If the cursor is at the very end of the last line, and that line starts with\n    a prompt (`\u003e\u003e\u003e ` this includes 1 space) the code is executed when you press return.\n    Pressing return on any other prompt line copies that line to the end ready to\n    execute.\n    * Pressing `Ctrl + Up/Down` will cycle through previous command history.\n    * The console is a text edit and you can edit any of the text so you can fix\n    your mistakes as you make them\n* **Workbox:** The workbox is a place to write complex multi-line code. The contents\n    of all workboxes are saved when PrEditor is closed or pressing `Ctrl + S`.\n    * Workboxes are grouped into tabs of workboxes. You can drag and drop\n    individual workboxes between groups and re-order them.\n    * `Ctrl + Return` runs all code inside of the current workbox.\n    * `Shift + Return` or the `Number-pad Return` executes the selected text or\n    the line the cursor is on.\n    * `run_workbox(\"group/tab\")` This command is added allowing you to run the\n    contents of a workbox. Pass the name of the group and workbox tabs separated\n    by a forward slash.\n* **Logging Level button:** Tools for managing python loggers.\n    * This button shows all known python loggers and lets you view/change their\n    logging levels.\n    * You can install logging handlers that have had PrEditor plugins written for them.\n    * Known python logger levels are saved and restored.\n* **OutputConsole:** Selectively shows output from stdout, stderr, specific python\nloggers, and tracebacks(not using stderr). This can be used in various widgets to\nshow selected output. See [examples/output_console.py](examples/output_console.py)\nfor an example of the various modes.\n* All code is run in `__main__`. In code you can add objects to it for inspection in PrEditor.\n* `Ctrl + Shift + PgUp/PgDown` changes focus between the console and workbox.\n* `Ctrl + Alt + Shift + PgUp/PgDown` changes focus and copies the current prompt\nline of the console, or the current line of the workbox to the other.\n\n\n# Examples\n\nSee [examples](examples) for more complete examples of using PrEditor.\n\nFor simple standalone applications that only exist for the life of the main window\nyou can simply call `connect_preditor` in your class `__init__` and optionally add\nthe created QAction into your GUI's menu. All `sys.stdout` and `sys.stderr` output\nwritten after `connect_preditor` is called, will be shown in the PrEditor window\nif it shown. If a exception is raised, and PrEditor is not visible, the user will\nbe notified and can easily show PrEditor.\n```py\nimport preditor\n\n# Create a keyboard shortcut(F2) to launch PrEditor and start capturing sys.stdout\n# and sys.stderr writes. The name argument makes this instance use it for prefs\naction = preditor.connect_preditor(window, name=\"Example\")\n\n# Add the newly created action to a menu\nwindow.menuBar().actions()[0].menu.addAction(action)\n```\n\nSteps for initialization of a more complex application where you don't have\ncontrol over the initialization of the Gui(like Maya).\nSee [examples/add_to_app.py](examples/add_to_app.py) for a simple implementation.\n\n\n```py\n# Step 1: Capture sys.stdout and sys.stderr output to a buffer as early as\n# possible without creating the gui. Add this code to a plugin that gets loaded\n# as early as possible. This can even be run before the gui is created.\nimport preditor\n# The name \"maya\" specifies the core_name that will be used to load/save prefs.\npreditor.configure(\"maya\")\n\n# Step 2: Add a way for the user to trigger calling launch to show the PrEditor\n# gui. This is the first time the PrEditor GUI is initialized.\npreditor.launch()\n\n# Step 3: When closing the application, calling this will ensure that the\n# current PrEditor gui's state is saved. It's safe and fast to call this even\n# if the gui was never created.\npreditor.shutdown()\n```\n\nUp to the point where the PrEditor instance is created you can update the config\ndata set by `preditor.configure`. For example you can change the name(used to load\na set of user prefs) by calling `preditor.config.name = 'NewName'`. This is useful\nfor configuring PrEditor before you import your specific setup code that implements\na better `parent_callback`.\n\n# Installing\n\n`pip install preditor`\n\n## Installing Qt\n\nPrEditor is built on Qt, but uses [Qt.py](https://github.com/mottosso/Qt.py) so\nyou can choose to use PySide6, PySide2, PyQt6 or PyQt5. We have elected to not\ndirectly depend on either of these packages so that you can use PrEditor inside\nof existing applications like Maya or Houdini that already come with PySide\ninstalled. If you are using it externally add them to your pip install command.\n\n- PySide6: `pip install preditor PySide6`\n- PyQt6: `pip install preditor PyQt6`\n\n## Cli\n\nPrEditor is intended to be installed inside existing applications like Maya,\nHoudini, Nuke etc, so it doesn't make sense to require installing packages like\nclick for those installs. If you are setting up a system wide install and want\nto use the cli interface, you will need to install the cli optional dependencies.\n\n`pip install preditor[cli]`\n\n### Creating shortcuts\n\nIf you want to be able to create desktop shortcuts from the cli to launch\nPrEditor, you will also need to include the `shortcut` dependencies. Currently\nthis is only useful for windows.\n\n- `pip install preditor[cli,shortcut]`\n\n## QScintilla workbox\n\nThe more mature QScintilla workbox requires a few extra dependencies that must\nbe passed manually. We have added it as pip `optional-dependencies`. QScintilla\nonly works with PyQt5/6 and it is a little hard to get PyQt working inside of\nDCC's that ship with PySide2/6 by default. Here is the python 3 pip install command.\n\n- PyQt6: `pip install preditor[qsci6] PyQt6, aspell-python-py3`\n- PyQt5: `pip install preditor[qsci5] PyQt5, aspell-python-py3`\n\nThe aspell-python-py3 requirement is optional to enable spell check.\n\nYou may need to set the `QT_PREFERRED_BINDING` or `QT_PREFERRED_BINDING_JSON`\n[environment variable](https://github.com/mottosso/Qt.py?tab=readme-ov-file#override-preferred-choice) to ensure that PrEditor can use PyQt5/PyQt6.\n\n# DCC Integration\n\nHere are several example integrations for DCC's included in PrEditor. These\nrequire some setup to manage installing all pip requirements. These will require\nyou to follow the [Setup](#setup) instructions below.\n\n- [Maya](/preditor/dccs/maya/README.md)\n- [3ds Max](/preditor/dccs/studiomax/README.md)\n\nIf you are using hab, you can simply add the path to the [preditor](/preditor) folder to your site's `distro_paths`. [See .hab.json](/preditor/dccs/.hab.json)\n\n## Setup\n\nPrEditor has many python pip requirements. The easiest way to get access to all\nof them inside an DCC is to create a virtualenv and pip install the requirements.\nYou can possibly use the python included with DCC(mayapy), but this guide covers\nusing a system install of python.\n\n1. Identify the minor version of python that the dcc is using. Running `sys.version_info[:2]` in the DCC returns the major and minor version of python.\n2. Download and install the required version of python. Note, you likely only need to match the major and minor version of python(3.11 not 3.11.12). It's recommended that you don't use the windows store to install python as it has had issues when used to create virtualenvs.\n3. Create a virtualenv using that version of python. On windows you can use `py.exe -3.11` or call the correct python.exe file. Change `-3.11` to match the major and minor version returned by step 1. Note that you should create separate venvs for a given python minor version and potentially for minor versions of Qt if you are using PyQt.\n    ```batch\n    cd c:\\path\\to\\venv\\parent\n    py -3.11 -m virtualenv preditor_311\n    ```\n4. Use the newly created pip exe to install PrEditor and its dependencies.\n    * This example shows using PySide and the simple TextEdit workbox in a minimal configuration.\n        ```batch\n        c:\\path\\to\\venv\\parent\\preditor_311\\Scripts\\pip install PrEditor\n        ```\n    * This example shows using QScintilla in PyQt6 for a better editing experience. Note that you need to match the PyQt version used by the DCC, This may require matching the exact version of PyQt.\n        ```batch\n        c:\\path\\to\\venv\\parent\\preditor_311\\Scripts\\pip install PrEditor[qsci6] PyQt6==6.5.3\n        ```\n\n### Editable install\n\nYou should skip this section unless you want to develop PrEditor's code from an git repo using python's editable pip install.\n\nDue to how editable installs work you will need to set an environment variable\nspecifying the site-packages directory of the virtualenv you created in the\nprevious step. On windows this should be the `lib\\site-packages` folder inside\nof the venv you just created. Store this in the `PREDITOR_SITE`, this can be done\npermanently or temporarily(via `set \"PREDITOR_SITE=c:\\path\\to\\venv\\parent\\preditor_311\\lib\\site-packages\"`).\n\nThis is required because you are going to use the path to your git repo's preditor\nfolder in the module/plugin loading methods for the the DCC you are using, but\nthere is no way to automatically find the virtualenv that your random git repo\nis installed in. In fact, you may have have your git repo installed into multiple\nvirtualenvs at once.\n\n# Plugins\n\nPrEditor is can be extended using entry point plugins defined by other pip packages.\n\n* `preditor.plug.about_module`: Used to add information about various packages\nlike version and install location to the output of `preditor.about_preditor()`.\nThis is what generates the text shown by Help menu -\u003e About PrEditor. See\nsub-classes of `AboutModule` in `preditor.about_module` and how those are\nadded in [setup.cfg](setup.cfg).\n\n* `preditor.plug.editors`: Used to add new workbox editors to PrEditor. See\n[workbox_text_edit.py](preditor/gui/workbox_text_edit.py) for an example of\nimplementing a workbox. See [workbox_mixin.py](preditor/gui/workbox_mixin.py)\nfor the full interface to implement all features of an editor.\n\n* `preditor.plug.loggerwindow`: Used to customize the LoggerWindow instance when\nthe LoggerWindow is created. For example, this can be used to create extra Toolbars\nor add menu items. When using this plugin, make sure to use the\n`preditor.gui.logger_window_plugin.LoggerWindowPlugin` class for your base class.\n\n* `preditor.plug.logging_handlers`: Used to add custom python logging handlers\nto the LoggingLevelButton's handlers sub-menus. This allows you to install a\nhandler instance on a specific logging object.\n\n# Qt Designer integration\n\nPrEditor includes some reusable widgets that are useful to integrate into your\nown custom interfaces. These can be directly imported and added but PrEditor also\ndefines Qt Designer plugins so you can directly add them to your designer files.\n\nNote: This has currently only been tested using [PyQt5](https://pypi.org/project/pyqt5-tools/)/[PyQt6](https://pypi.org/project/pyqt6-tools/).\n\nTo load the plugins append the path to [preditor/gui/qtdesigner](/preditor/gui/qtdesigner)\nto the `PYQTDESIGNERPATH` environment variable.\n\n# Change Log\n\n* **2.0.0:** OutputConsole, link files to workboxe tabs and Workbox editing history\n    * New reusable `OutputConsole` widget that optionally shows stdout, stderr, logging messages, and tracebacks. See the [example](/examples/output_console.py) implementation for details.\n    * Workbox tabs can be linked to files and edited externally\n    * Workbox content change history is versioned and you can quickly switch between the versions.\n    * Recently closed workbox tabs can be be re-opened\n    * Workbox preference saving has been re-worked. It will automatically migrate\n    to the new setup so you won't loose your current workbox tab contents. However\n    after upgrading if you want to switch back to the v1.X release see details below.\n\n        \u003cdetails\u003e\n\n        In the rare case that you must revert to older Preditor (v1.X), you will only\n        see the workboxes you had when you updated to PrEditor v2.0. When you switch\n        back to v2.0 again, you still may only see those same workboxes. This can be\n        fixed with these steps, which in summary is to replace `preditor_pref.json`\n        with one of the backups of that file.\n\n        * Options Menu \u003e Preferences\n        * In the `Prefs files on disk` section, click Browse. An Explorer window opens.\n        * Close PrEditor\n        * Go into the `prefs_bak` folder\n        * Sort by name or by date, so most recent files are at the top\n        * Look for a backup that is at least slightly larger than recent ones. If they are all the same size, go with the latest one.\n        * Copy that into the parent directory (ie PrEditor)\n        * Remove `preditor_pref.json`\n        * Rename the `preditor_pref\u003ctimestamp\u003e.json` file you copied, so it is `preditor_pref.json`\n        * Restart PrEditor. Check if it has all your workboxes.\n        * If it still isn't correct, do a little sleuthing or trial and error to find the correct backup to use.\n        \u003c/details\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fblurstudio%2Fpreditor","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fblurstudio%2Fpreditor","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fblurstudio%2Fpreditor/lists"}