Added pgconsole. It is my older project, a GUI query console. It uses GTK+ and asynchronous queries.
import gtk, gobject, pango
from cgi import escape
class DataView(gtk.ScrolledWindow):
def __init__(self):
super(DataView, self).__init__()
sw = self
sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
sw.set_shadow_type(gtk.SHADOW_ETCHED_IN)
self.treeview = gtk.TreeView(gtk.ListStore(str))
self.treeview.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
self.treeview.set_property("rubber-banding", True)
sw.add(self.treeview)
def load_data(self, names, rows):
x = [str] * (len(names) + 1)
liststore = gtk.ListStore(*x)
for c in self.treeview.get_columns():
self.treeview.remove_column(c)
tvcolumn = gtk.TreeViewColumn()
cell = DataViewCellRenderer()
cell.set_property('head', True)
tvcolumn.pack_start(cell, True)
tvcolumn.set_property('resizable', True)
#tvcolumn.set_property('sizing', gtk.TREE_VIEW_COLUMN_FIXED)
tvcolumn.set_attributes(cell, text=0)
tvcolumn.set_min_width(2)
self.treeview.append_column(tvcolumn)
i = 0
for c in names:
i += 1
typename = c[1]
title = '<b>%s</b>' % escape(c[0])
if typename:
title += '\n<span size="small">%s</span>' % typename
tvcolumn = gtk.TreeViewColumn()
cell = DataViewCellRenderer()
lab = gtk.Label()
lab.set_use_underline(False)
lab.set_markup(title)
lab.show()
tvcolumn.set_widget(lab)
tvcolumn.set_property('resizable', True)
tvcolumn.pack_start(cell, True)
tvcolumn.set_attributes(cell, text=i)
self.treeview.append_column(tvcolumn)
self.treeview.set_model(liststore)
i = 0
for row in rows:
i += 1
liststore.append([i]+list(row))
class DataViewCellRenderer(gtk.GenericCellRenderer):
__gtype_name__ = 'DataViewCellRenderer'
__gproperties__ = {
'text': (gobject.TYPE_STRING, None, None, '', gobject.PARAM_READWRITE),
'head': (gobject.TYPE_BOOLEAN, None, None, False, gobject.PARAM_READWRITE)}
def __init__(self):
gtk.GenericCellRenderer.__init__(self)
self._props = {'text' : '', 'head' : False}
def do_set_property(self, pspec, value):
if not pspec.name in self._props:
raise AttributeError, 'Unknown property: %s' % pspec.name
self._props[pspec.name] = value
def do_get_property(self, pspec):
return self._props[pspec.name]
def on_get_size(self, widget, cell_area):
if cell_area == None:
pangoctx = widget.get_pango_context()
layout = pango.Layout(pangoctx)
layout.set_width(-1)
layout.set_text(self.get_property('text') or 'NULL')
w,h = layout.get_pixel_size()
return (0, 0, w+5, 20)
x = cell_area.x
y = cell_area.x
w = cell_area.width
h = cell_area.height
return (x,y,w,h)
def on_render(self, window, widget, background_area, cell_area, expose_area, flags):
x = background_area.x
y = background_area.y
w = background_area.width
h = background_area.height
ctx = window.cairo_create()
ctx.set_line_width(0.4)
ctx.set_source_rgb(0, 0, 0)
ctx.move_to(x+w-1.5, y-0.5)
ctx.line_to(x+w-1.5, y+h-0.5)
ctx.line_to(x-0.5, y+h-0.5)
ctx.stroke()
ctx.set_source_rgb(1, 1, 1)
ctx.move_to(x+w-0.5, y-0.5)
ctx.line_to(x+w-0.5, y+h-0.5)
ctx.stroke()
pangoctx = widget.get_pango_context()
layout = pango.Layout(pangoctx)
text = self.get_property('text')
head = self.get_property('head')
if head:
layout.set_markup('<b>%s</b>' % text)
else:
if text is None:
layout.set_markup('<span foreground="gray">NULL</span>')
else:
layout.set_text(text)
widget.style.paint_layout(window, gtk.STATE_NORMAL, True,
cell_area, widget, '',
cell_area.x, cell_area.y,
layout)