[Urwid] scrolling
James Mills
prologic at shortcircuit.net.au
Wed Jun 28 05:25:13 EDT 2006
Hi,
How does one accomplish scrolling ?
See attached source.
On line 60, once this has been filled with as many rows
of the urwid.Text widget as can fit on the screen, I no longer
see any new ones.
Obviously what I'm after here is some kind of scroll-back-type
widget that only shows the newest x rows of text.
Thanks,
cheers
James
PS: If anyone wants to improve upon what I've done (it's only
an example), please send me patches. You'll need my PyMills
library (http://trac.shortcircuit.net.au/projects/pymills/)
svn co
svn://svn.shortcircuit.net.au/projects/pymills/branches/pymills-ng
pymills
--
--
-"Problems are Solved by Method"
-
- James Mills <prologic at shortcircuit.net.au>
- HomePage: http://shortcircuit.net.au/~prologic/
- Phone: +61732166379
- Mobile: +61404270962
- Skype: therealprologic
- MSN: prologic at shortcircuit.net.au
- ICQ: 98888663
- IRC: irc://shortcircuit.net.au#se
Please avoid sending me Word or PowerPoint attachments.
See http://www.gnu.org/philosophy/no-word-attachments.html
-------------- next part --------------
#!/usr/bin/env python
import re
import os
import sys
import urwid
import socket
from inspect import getargspec
from urwid.curses_display import Screen
from pymills.irc import *
from pymills.event import *
from pymills.misc import backMerge
from pymills.sockets import TCPClient
MAIN_TITLE = "PyMills IRC Client"
HELP_STRINGS = {
"main": "For help, type: /help"
}
class TestClient(TCPClient, IRC):
def __init__(self, event):
TCPClient.__init__(self)
IRC.__init__(self)
def ircRAW(self, data):
self.write(data + "\r\n")
@listener("read")
def onREAD(self, line):
TCPClient.onREAD(self, line)
IRC.onREAD(self, line)
class MainWindow(Screen, Component):
def __init__(self, event, client):
Screen.__init__(self)
Component.__init__(self)
self.event = event
self.client = client
self.channel = None
self.client.setNick(
os.getenv("USER", "PyMills"))
self.client.setIdent(
os.getenv("USER", "PyMills"))
self.cmdRegex = re.compile(
"\/(?P<command>[a-z]+) ?"
"(?P<args>.*)(?iu)")
self.register_palette([
("title", "white", "dark blue", "standout"),
("line", "light gray", "black"),
("help", "white", "dark blue")])
self.lines = [urwid.Text("")]
self.body = urwid.Filler(
urwid.Pile(self.lines),
valign="top")
self.title = urwid.Text(MAIN_TITLE)
self.header = urwid.AttrWrap(self.title, "title")
self.help = urwid.AttrWrap(
urwid.Text(
HELP_STRINGS["main"]), "help")
self.input = urwid.Edit(caption="%s> " % self.channel)
self.footer = urwid.Pile([self.help, self.input])
self.top = urwid.Frame(self.body, self.header,
self.footer)
def main(self):
self.run_wrapper(self.run)
def unknownCommand(self, command):
self.lines.append(
urwid.Text(
"Unknown command: %s" % command))
def syntaxError(self, command, args, expected):
self.lines.append(
urwid.Text(
"Syntax error (%s): %s Expected: %s" % (
command, args, expected)))
def process(self, s):
match = self.cmdRegex.match(s)
if match is not None:
command = match.groupdict()["command"]
if not match.groupdict()["args"] == "":
tokens = match.groupdict()["args"].split(" ")
else:
tokens = []
fn = "cmd" + command.upper()
if hasattr(self, fn):
f = getattr(self, fn)
if callable(f):
args, vargs, kwargs, default = getargspec(f)
args.remove("self")
if len(args) == len(tokens):
if len(args) == 0:
f()
else:
f(*tokens)
else:
if len(tokens) > len(args):
if vargs is None:
if len(args) > 0:
factor = len(tokens) - len(args) + 1
f(*backMerge(tokens, factor))
else:
print "1"
self.syntaxError(command,
" ".join(tokens),
" ".join(
[x for x in args + [vargs]
if x is not None]))
else:
f(*tokens)
elif default is not None and \
len(args) == (
len(tokens) + len(default)):
f(*(tokens + list(default)))
else:
self.syntaxError(command,
" ".join(tokens),
" ".join(
[x for x in args + [vargs]
if x is not None]))
else:
if self.channel is not None:
self.client.ircPRIVMSG(channel, s)
else:
self.unknownCommand(command)
@filter("numeric")
def onNUMERIC(self, source, target, numeric, arg, message):
if numeric == ERR_NICKNAMEINUSE:
self.client.ircNICK(
self.client.getNick() + "_")
else:
if arg is not None:
self.lines.append(urwid.Text(
"%s :%s" % (arg, message)))
else:
self.lines.append(urwid.Text(message))
return True, None
@filter("notice")
def onNOTICE(self, source, target, message):
self.lines.append(urwid.Text(
"-%s- %s" % (source, message)))
return True, None
@filter("privmsg")
def onPRIVMSG(self, source, target, message):
self.lines.append(urwid.Text(
"<%s> %s" % (source, message)))
return True, None
def cmdEXIT(self, message=""):
self.cmdQUIT(message)
self.done = True
def cmdSERVER(self, host, port=6667):
self.client.open(host, port)
self.client.ircUSER(
self.client.getIdent(),
socket.gethostname(),
host,
"PyMills Example IRC Client")
self.client.ircNICK(self.client.getNick())
def cmdJOIN(self, channel):
if self.channel is not None:
self.cmdPART(channel, "Joining %s" % channel)
self.client.ircJOIN(channel)
self.channel = channel
def cmdPART(self, channel=None, message="Leaving"):
if channel is None:
channel = self.channel
if channel is not None:
self.client.ircPART(channel, message)
self.channel = None
def cmdQUOTE(self, message):
self.client.ircRAW(message)
def cmdQUIT(self, message="Bye"):
self.client.ircQUIT(message)
def run(self):
size = self.get_cols_rows()
self.done = False
while not self.done:
self.update_screen(size)
keys = self.get_input()
for k in keys:
if k == "window resize":
size = self.get_cols_rows()
continue
elif k == "enter":
self.process(self.input.get_edit_text())
self.input.set_edit_text("")
continue
self.top.keypress(size, k)
self.input.set_edit_text(
self.input.get_edit_text() + k)
if self.client.connected:
self.client.process()
self.event.flush()
def update_screen(self, size):
canvas = self.top.render(size, focus=True)
self.draw_screen(size, canvas)
def main():
event = EventManager()
client = TestClient(event)
MainWindow(event, client).main()
if __name__ == "__main__":
main()
More information about the Urwid
mailing list