{"id":17047064,"url":"https://github.com/chhsiao90/gviewer","last_synced_at":"2025-10-05T10:21:24.088Z","repository":{"id":57436421,"uuid":"61792098","full_name":"chhsiao90/gviewer","owner":"chhsiao90","description":"Simple, Light Weight, but Powerful Terminal UI Library for Python","archived":false,"fork":false,"pushed_at":"2016-09-15T06:24:42.000Z","size":216,"stargazers_count":10,"open_issues_count":1,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-26T10:21:20.403Z","etag":null,"topics":["tui","urwid"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/chhsiao90.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-06-23T09:18:58.000Z","updated_at":"2021-09-22T16:14:45.000Z","dependencies_parsed_at":"2022-09-10T01:51:03.717Z","dependency_job_id":null,"html_url":"https://github.com/chhsiao90/gviewer","commit_stats":null,"previous_names":[],"tags_count":16,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chhsiao90%2Fgviewer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chhsiao90%2Fgviewer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chhsiao90%2Fgviewer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chhsiao90%2Fgviewer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chhsiao90","download_url":"https://codeload.github.com/chhsiao90/gviewer/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248592006,"owners_count":21130163,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["tui","urwid"],"created_at":"2024-10-14T09:48:17.058Z","updated_at":"2025-10-05T10:21:24.026Z","avatar_url":"https://github.com/chhsiao90.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# General Viewer (GViewer)\n[![Build Status](https://travis-ci.org/chhsiao90/gviewer.svg?branch=master)](https://travis-ci.org/chhsiao90/gviewer)\n[![Coverage Status](https://coveralls.io/repos/github/chhsiao90/gviewer/badge.svg?branch=master)](https://coveralls.io/github/chhsiao90/gviewer?branch=master)\n\n**Simple, Light Weight, Powerful**  \nGViewer is a terminal UI library that depends on [urwid](https://github.com/urwid/urwid) simplified writing a tui based reporting system.  \nYou could write a powerful terminal UI that display and operate with data as you want with just less and less code.\n\n## Installation\n```shell\npip install gviewer\n```\n\n## Run Example\nThere are some example in examples that provide some use cases.  \nYou could see and run the examples.\n\n```shell\npython examples/panama.py\n```\n\n## Usage\n\n### Data Store\n\n####StaticDataStore\nUsed for static data list, like log file\nInitiate with a list of eny type of content\nThe content will transfer to the your defined displayer later for display \n\n```python\nfrom gviewer import StaticDataStore\ndata_store = StaticDataStore(data)\n```\n\n#### AsyncDataStore\nUsed for asynchronous data list, like subscribe an [zeromq](http://zeromq.org/) publisher\n\n```python\ndef register_func(on_message):\n    some_listener.on_message(on_message)\n\ndata_store = AsyncDataStore(register_func)\n```\n\n### Displayer\nDefined how you display your data from Data Store to summary/details\n\n```python\nfrom gviewer import BaseDisplayer, View, Group, PropsGroup, Text, Prop\n\nclass MyDisplayer(BaseDisplayer):\n    def to_summary(self, message):\n        \"\"\"\n        return a str or text markup\n        reference: http://urwid.org/manual/displayattributes.html#text-markup\n        \"\"\"\n        return message[\"summary\"]\n\n    def get_views(self):\n        \"\"\"return an array of tuple that contains view title and a function that transform message to detail\"\"\"\n        return [\n            (\"view1\", self.view1),\n            (\"view2\", self.view2),\n        ]\n\n    def view1(self, message):\n        \"\"\"return groups\"\"\"\n        return View(\n            [Group(\"title\", [Text(m) for m in message[\"view1\"]])]\n        )\n\n    def view2(self, message):\n        \"\"\"return groups\"\"\"\n        return View(\n            [PropsGroup(\"title\", [Prop(p[0], p[1]) for p in message[\"view2\"]])]\n        )\n```\n\n### GViewer\nMain class to start the tui\nThe constructor accept any of urwid.MainLoop arguments to intiate with custom config\n\n```python\nfrom gviewer import GViewer, DisplayerContext\ncontext = DisplayerContext(data_store, displayer)\nviewer = GViewer(context)\nviewer.start()\n```\n\n## Advanced Usage\n### Summary Actions\nBind function to specific key to apply customize action, ex: export\n```python\nfrom gviewer import GViewer, DisplayerContext\n\ndef custom_export(controller, message, widget, *args, **kwargs):\n    with open(\"export\", \"w\") as f:\n        f.write(str(message))\n    controller.notify(\"file is export\")\n\ncontext = DisplayerContext(data_store, displayer, actions=Actions([(\"a\", \"Custom export\", custom_export)]))\nviewer = GViewer(context)\n```\n\n### View Actions\nBind function to specific key to apply customize action, ex: export\n```python\nfrom gviewer import View, BaseDisplayer\nclass MyDisplayer(BaseDisplayer):\n    def get_views(self):\n        return [(\"view\", self.view)]\n\n    def view(self, message):\n        return View([], actions=Actions([(\"a\", \"Custom export\", self.custom_export)]))\n\n    def custom_export(controller, message, *args, **kwargs):\n        with open(\"export\", \"w\") as f:\n            f.write(str(message))\n        controller.notify(\"file is export\")\n```\n\n## Built-in actions\n### Summary\n- /: search\n- g: top\n- G: bottom\n- x: clear current item\n- X: clear all items\n- q: quit\n- ?: help\n\n### Detail\n- /: search\n- tab: next view\n- shift+tab: prev view\n- n: search next result \n- N: search previous result\n- e: export current content to file\n- q: quit\n- ?: help\n\n\n## Contribution\nPlease feel free to create issue or create PR\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchhsiao90%2Fgviewer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchhsiao90%2Fgviewer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchhsiao90%2Fgviewer/lists"}