{"id":16585317,"url":"https://github.com/sindrets/spt_gfx","last_synced_at":"2026-07-03T16:33:59.010Z","repository":{"id":104197746,"uuid":"222366122","full_name":"sindrets/spt_gfx","owner":"sindrets","description":"Simple Python Terminal Graphics - A simple, lightweight framework for creating graphics in the terminal.","archived":false,"fork":false,"pushed_at":"2019-12-03T15:07:27.000Z","size":36,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-10-12T04:12:40.181Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sindrets.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"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":"2019-11-18T04:51:35.000Z","updated_at":"2022-11-19T01:47:20.000Z","dependencies_parsed_at":null,"dependency_job_id":"6af16f67-7790-45d1-98b8-72fa7879f919","html_url":"https://github.com/sindrets/spt_gfx","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/sindrets/spt_gfx","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sindrets%2Fspt_gfx","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sindrets%2Fspt_gfx/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sindrets%2Fspt_gfx/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sindrets%2Fspt_gfx/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sindrets","download_url":"https://codeload.github.com/sindrets/spt_gfx/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sindrets%2Fspt_gfx/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35094064,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-03T02:00:05.635Z","response_time":110,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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-10-11T22:47:35.373Z","updated_at":"2026-07-03T16:33:58.968Z","avatar_url":"https://github.com/sindrets.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n# Simple Python Terminal Graphics\n\n`spt_gfx` is a small, lightweight framework that is designed to give you a simple, yet fast and powerful way to access the alternate buffer and create graphics in the terminal.\n\n\u003e Note: Only works with ANSI terminals. This framework heavily relies on ANSI control sequences, and I'm not really interested in supporting Windows.\n\n### Installation\n```sh\nsudo python3 setup.py install\n```\n\n### Usage\n\nFollowing is a simple example of how to draw some text to the screen and attach a key listener.\n\n```python\nfrom spt_gfx import Screen, KeyEvent\n\nscreen = Screen()\nscreen.open()\n\nscreen.setTextWrap(\n    10, 5,\n    \"This text is written directly to the screen, and will disappear on\"\n    + \"the next screen clear.\"\n)\n\ndef screenUpdate(this: Screen):\n    this.setTextWrap(\n        10, 9,\n        \"This text is written from the screen's update method, and will \"\n        + \"persist over screen refreshes.\"\n    )\n\nscreen.update = screenUpdate\n\ndef onKeyPressed(keyEvent: KeyEvent):\n    screen.clear()\n    screen.setString(1, 1, str(keyEvent))\n    screen.refresh()\n\nscreen.addKeyListener(onKeyPressed)\n\nscreen.refresh()\n```\n\nThe `screen.open()` method initializes the screen and opens the alternate buffer. You leave the alternate buffer and dispose of the screen by calling the `screen.close()` method. By default this method is called when pressing ctrl+c or ctrl+d, but this can be intercepted in a key  listener by calling `keyEvent.invalidate()`.\n\nThe `screen.update` property is a callable that is a called on each screen refresh. This property exists on all `Buffer` objects.\n\nThe `screen.refresh()` method will first call every buffer's update method before rendering all pending draw events to the screen.\n\nThere are four methods for drawing text to the screen:\n\n```python\nbuffer.setString(x: int, y: int, data: str)\n```\n\nThis method is used for modifying a single line in the buffer, and does not support newline characters. When reaching the end of the screen it will simply stop.\n\n```python\nbuffer.setText(x: int, y: int, data: str)\n```\n\nThis method supports newline characters and new lines will start from the same x-value as the initial line.\n\n```python\nbuffer.setTextWrap(x: int, y: int, data: str)\n```\n\nThis method supports newline characters and will also automatically hard-wrap text that reaches the end of the screen.\n\n```python\nbuffer.setTextWrapWords(x: int, y: int, data: str)\n```\n\nThis is similar to the `setTextWrap` method, but this will sensibly wrap words.\n\n### Using multiple Buffer objects\n\nThe following is an example of how to use multiple buffer objects. This example, along with the `lorem_ipsum.txt` file can be located in `./test`.\n\n```python\nfrom spt_gfx import Screen, Buffer, KeyEvent, color, Key\nfrom pathlib import Path\n\nscreen = Screen()\nscreen.open()\n\nstyles = [\n    color.yellow.bold,\n    color.red.italic,\n    color.green.underline\n]\ncurrentStyleIndex = 0\ncurrentStyle = styles[currentStyleIndex]\n\ndef cycleStyles():\n    global currentStyleIndex, styles, currentStyle\n    currentStyleIndex += 1\n    currentStyleIndex %= len(styles)\n    currentStyle = styles[currentStyleIndex]\n\nlorem = \"\"\nwith open(Path(__file__).joinpath(\"../lorem_ipsum.txt\").resolve(), \"r\") as file:\n    lorem = file.read()\n\ncontent = Buffer()\n\ndef contentUpdate(this: Buffer):\n    this.clear()\n    this.setTextWrap(1, 1, currentStyle(lorem))\ncontent.update = contentUpdate\ncontent.setZ(1)\nscreen.addBuffer(content)\n\nui = Buffer()\n\ndef uiUpdate(this: Buffer):\n    this.clear()\n    this.setString(\n        1, this.getHeight(), color.bgWhite.black(\n            \"  enter: cycle styles  ctrl+c: quit\"\n            + (\" \" * this.getWidth())\n        )\n    )\nui.update = uiUpdate\nui.setZ(2)\nscreen.addBuffer(ui)\n\ndef onKeyPressed(keyEvent: KeyEvent):\n    if Key.ENTER in keyEvent.keys:\n        cycleStyles()\n        screen.refresh()\n\nscreen.addKeyListener(onKeyPressed)\n\nscreen.refresh()\n```\n\nThe `buffer.setZ()` method adjusts the buffer's z-index. The z-index determines the order in which the buffers are drawn to the screen. Buffers with higher z values are drawn over buffers with lower z values.\n\nOn screen refresh, the renderer merges the data from all buffers into a temporary buffer before all data is drawn to the screen in a single print call. This helps minimize any flashing that might occur if the buffers are drawn to the screen in sequence. \n\n### Text styling\n\nIncluded in the framework is a text styling utility that is heavily inspired by [chalk](https://github.com/chalk/chalk). The usage is simple:\n\n```python\nfrom spt_gfx import color\nprint(color.yellow(\"Foo bar.\"))\n```\n\nAnd just like chalk, the API calls are chainable:\n\n```python\nprint(color.yellow.bgCyan.italic.underline(\"Foo bar.\"))\n```\n\nFor terminals that support truecolor you can also use RGB:\n\n```python\nprint(color.bgRgb(233, 30, 99)(\"Foo bar.\"))\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsindrets%2Fspt_gfx","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsindrets%2Fspt_gfx","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsindrets%2Fspt_gfx/lists"}