[kgtp] r1171 committed - Add gtpwin.py and gtpwin_example.py.

  • From: kgtp@xxxxxxxxxxxxxx
  • To: kgtp@xxxxxxxxxxxxx
  • Date: Thu, 19 Jul 2012 06:13:54 +0000

Revision: 1171
Author:   teawater
Date:     Wed Jul 18 23:13:32 2012
Log:      Add gtpwin.py and gtpwin_example.py.

http://code.google.com/p/kgtp/source/detail?r=1171

Added:
 /trunk/add-ons/gtpwin.py
 /trunk/add-ons/gtpwin_example.py

=======================================
--- /dev/null
+++ /trunk/add-ons/gtpwin.py    Wed Jul 18 23:13:32 2012
@@ -0,0 +1,328 @@
+#!/usr/bin/python
+
+import gtk
+import glib
+
+version = '20120605+'
+
+def modelName():
+       return __name__
+
+def run():
+       gtk.main()
+
+class gtpline:
+       def __init__(self, name):
+               self.name = name
+               self.val = []
+               self.y = []
+
+       def number(self):
+               return len(self.val)
+
+       def add(self, val):
+               self.val.append(val)
+               self.y.append(-1)
+
+       def remove_head(self, num):
+               if self.number() > 0:
+                       del(self.val[0:num])
+                       del(self.y[0:num])
+
+       def load_new_val(self):
+ '''GUI will auto call this function each sec that you set. Use this function call self.add to add new val to this line.
+               If really got value, add and return it.  If not, add and return 
0.'''
+               self.add(0)
+               return 0
+
+class gtpwin(gtk.Window):
+ def __init__(self, lines, title = "", sec = 1, width = 10, remove_first = False, button_each_line = 4):
+               """lines: the line class list to show.
+               title: the window title.
+               sec: the load new entry wait second.
+               width: the width of each entry.
+ remove_first :true then remove the first entry because it already record a big value.
+               button_each_line: the number of button of each line.
+               """
+               super(gtpwin, self).__init__()
+
+               self.entry_width = width
+
+               self.max_value = 0
+               self.prev_width = 0
+               self.prev_height = 0
+               self.y_ratio = 0
+               self.logfd = False
+
+               #Setup lines
+               color_limit = (0xffb0ff, 0x006000)
+               num = len(lines)
+               block = (color_limit[0] - color_limit[1]) / float(num)
+               color = color_limit[1]
+               for e in lines:
+                       e.bcolor = gtk.gdk.Color("#"+ "%06x" % int(color))
+ e.lcolor = ((((int(color) >> 16) / float(0xff) * 1), ((int(color) >> 8 & 0xff) / float(0xff) * 1), ((int(color) & 0xff) / float(0xff) * 1)))
+                       color += block
+               self.lines = lines
+
+               #Set window
+               self.set_title(title)
+               self.connect("destroy", gtk.main_quit)
+
+               #Create button
+               bhbox = gtk.HBox(False, 0)
+               self.button_hboxes = [bhbox]
+               num = 0
+               for line in self.lines:
+                       line.button = gtk.ToggleButton(line.name)
+                       self.set_button_color(line.button, line.bcolor)
+                       line.button.line = line
+                       line.button.connect("clicked", self.button_click)
+                       line.entry = gtk.Entry()
+                       line.entry.set_editable(False)
+                       hbox = gtk.HBox(False, 0)
+                       hbox.pack_start(line.button, False, False, 0)
+                       hbox.pack_start(line.entry, False, False, 0)
+                       bhbox.pack_start(hbox, True, False, 0)
+                       num += 1
+                       if num >= button_each_line:
+                               bhbox = gtk.HBox(False, 0)
+                               self.button_hboxes.append(bhbox)
+                               num = 0
+
+               #Create self.darea
+               self.darea = gtk.DrawingArea()
+               self.darea.connect("expose-event", self.expose)
+               self.darea.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color("#FFFFFF"))
+
+               #menubar
+               mb = gtk.MenuBar()
+               #file
+               filemenu = gtk.Menu()
+               filem = gtk.MenuItem("File")
+               filem.set_submenu(filemenu)
+               save = gtk.CheckMenuItem("Save log to a CSV file")
+               save.connect("activate", self.mb_save)
+               save.set_active(False)
+               exit = gtk.MenuItem("Exit")
+               exit.connect("activate", gtk.main_quit)
+               filemenu.append(save)
+               filemenu.append(gtk.SeparatorMenuItem())
+               filemenu.append(exit)
+               mb.append(filem)
+               #set
+               setmenu = gtk.Menu()
+               setm = gtk.MenuItem("Settings")
+               setm.set_submenu(setmenu)
+               show_buttons = gtk.CheckMenuItem("Show buttons")
+               show_buttons.set_active(True)
+               show_buttons.connect("activate", self.show_buttons)
+               setmenu.append(show_buttons)
+               mb.append(setm)
+
+               #Put widgets to window
+               vbox = gtk.VBox(False, 0)
+               vbox.pack_start(mb, False, False, 0)
+               vbox.pack_start(self.darea, True, True, 0)
+               for e in self.button_hboxes:
+                       vbox.pack_start(e, False, False, 0)
+               self.add(vbox)
+
+               self.show_all()
+               gtk.Window.maximize(self)
+
+               #Set each button to same width
+               button_size_max = 0
+               entry_size_max = 0
+               for line in self.lines:
+                       if line.button.allocation.width > button_size_max:
+                               button_size_max = line.button.allocation.width
+                       if line.entry.allocation.width > entry_size_max:
+                               entry_size_max = line.entry.allocation.width
+               for line in self.lines:
+                       line.button.set_size_request(button_size_max, -1)
+                       line.entry.set_size_request(entry_size_max, -1)
+
+               #Add timer
+               glib.timeout_add(int(sec * 1000), self.timer_cb)
+               if remove_first:
+                       glib.timeout_add(int(sec * 1100), 
self.timer_remove_first_record)
+
+       def __del__(self):
+               if self.logfd:
+                       self.logfd.close()
+                       self.logfd = False
+               super(gtpwin, self).__del__()
+
+       def each_lines(self, callback, argument = 0):
+               for line in self.lines:
+                       callback(line, argument)
+
+       #DrawingArea ---------------------------------------------------
+       def expose(self, widget, event):
+               cr = widget.window.cairo_create()
+
+               #y
+               if self.prev_height != self.darea.allocation.height:
+                       self.height_change = True
+                       self.prev_height = self.darea.allocation.height
+               else:
+                       self.height_change = False
+               if self.max_value > 0 and (self.height_change or self.y_ratio 
== 0):
+                       self.max_value += 100 - self.max_value % 100
+                       self.y_ratio = float(self.prev_height)/self.max_value
+                       self.height_change = True
+
+               #x
+               entry_number = 0
+ if self.entry_width * self.lines[0].number() > self.darea.allocation.width:
+                       self.entry_number = self.darea.allocation.width // 
self.entry_width
+                       for line in self.lines:
+                               if line.number() > self.entry_number:
+                                       line.remove_head(line.number() - 
self.entry_number)
+
+               #dash
+               cr.set_source_rgb(0, 0, 0)
+               cr.set_dash((1, 5))
+               #dash line for x
+               x = 0
+               while x < self.darea.allocation.width:
+                       x += self.entry_width * 10
+                       cr.move_to(x, 0)
+                       cr.line_to(x, self.prev_height)
+               #dash line for y
+               cr.move_to(0, 10)
+               cr.show_text(str(self.max_value))
+               cr.move_to(0, self.darea.allocation.height/4*3)
+               cr.show_text(str(self.max_value/4))
+               cr.line_to(self.darea.allocation.width, 
self.darea.allocation.height/4*3)
+               cr.move_to(0, self.darea.allocation.height/2)
+               cr.show_text(str(self.max_value/2))
+               cr.line_to(self.darea.allocation.width, 
self.darea.allocation.height/2)
+               cr.move_to(0, self.darea.allocation.height/4)
+               cr.show_text(str(self.max_value/4*3))
+               cr.line_to(self.darea.allocation.width, 
self.darea.allocation.height/4)
+               cr.stroke()
+               cr.set_dash(())
+
+               #lines
+               self.line_max = 0
+               self.each_lines(self.draw_line, cr)
+ if (self.line_max > 0 and self.line_max * 2 > self.max_value) or self.max_value == 0:
+                       self.max_value = self.line_max
+                       self.y_ratio = 0
+               self.height_change = False
+
+       def draw_line(self, line, cr):
+               if line.button.get_active():
+                       return
+               if line.number() < 2:
+                       return
+
+               cr.set_source_rgb(line.lcolor[0], line.lcolor[1], 
line.lcolor[2])
+               x = 0
+               for num in range(0, line.number()):
+                       if self.height_change or line.y[num] < 0:
+                               line.y[num] = self.prev_height - line.val[num] 
* self.y_ratio
+                       if line.val[num] > self.line_max:
+                               self.line_max = line.val[num]
+                       if num == 0:
+                               cr.move_to(x, line.y[num])
+                       else:
+                               cr.line_to(x, line.y[num])
+                       x += self.entry_width
+               cr.stroke()
+
+       #Timer ---------------------------------------------------------
+       def timer_cb(self):
+               for line in self.lines:
+                       val = line.load_new_val()
+                       line.entry.set_text(str(val))
+                       if self.logfd:
+                               self.write_csv(str(val)+",")
+               if self.logfd:
+                       self.write_csv("\n")
+               self.darea.queue_draw()
+               return True
+
+       def timer_remove_first_record(self):
+               if self.lines[0].number() > 0:
+                       for line in self.lines:
+                               line.remove_head(1)
+                       return False
+               else:
+                       return True
+
+       def write_csv(self, msg):
+               try:
+                       self.logfd.write(msg)
+               except:
+                       self.dialog_error("Writ CSV file got error")
+                       widget.set_active(False)
+                       self.logfd.close()
+                       self.logfd = False
+
+       #Menubar -------------------------------------------------------
+       def mb_save(self, widget):
+               if widget.active:
+ md = gtk.FileChooserDialog(title="Save log to a CSV file", action=gtk.FILE_CHOOSER_ACTION_SAVE, buttons = (gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OK, gtk.RESPONSE_OK))
+                       md.set_do_overwrite_confirmation(True)
+                       md.set_current_name("pe.csv")
+                       if md.run() == gtk.RESPONSE_OK:
+                               try:
+                                       self.logfd = open(md.get_filename(), 
"w")
+                                       for line in self.lines:
+                                               self.logfd.write(line.name + 
",")
+                                       self.logfd.write("\n")
+                                       for i in range(0, 
self.lines[0].number()):
+                                               for line in self.lines:
+                                                       self.logfd.write(str(line.val[i]) 
+ ",")
+                                               self.logfd.write("\n")
+                               except:
+                                       if self.logfd:
+                                               self.logfd.close()
+                                               self.logfd = False
+                                       self.dialog_error("Try to open file 
"+md.get_filename()+" got error")
+                                       widget.set_active(False)
+                       else:
+                               widget.set_active(False)
+                       md.destroy()
+               else:
+                       if self.logfd:
+                               self.logfd.close()
+                               self.logfd = False
+
+       def show_buttons(self, widget):
+               if widget.active:
+                       for e in self.button_hboxes:
+                               e.show()
+               else:
+                       for e in self.button_hboxes:
+                               e.hide()
+
+       #Button --------------------------------------------------------
+       def button_click(self, widget):
+               if widget.get_active():
+                       self.set_button_color(widget, gtk.gdk.Color("#FFFFFF"))
+               else:
+                       self.set_button_color(widget, widget.line.bcolor)
+                       for val in widget.line.val:
+                               if val > self.max_value:
+                                       self.max_value = val
+                                       self.y_ratio = 0
+               self.darea.queue_draw()
+
+       def set_button_color(self, button, color):
+               style = button.get_style().copy()
+               style.bg[gtk.STATE_NORMAL] = color
+               style.bg[gtk.STATE_ACTIVE] = color
+               style.bg[gtk.STATE_PRELIGHT] = color
+               style.bg[gtk.STATE_SELECTED] = color
+               style.bg[gtk.STATE_INSENSITIVE] = color
+               button.set_style(style)
+
+       #Dialog -------------------------------------------------------
+       def dialog_error(self, msg):
+ md = gtk.MessageDialog(self,gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_ERROR, gtk.BUTTONS_CLOSE, msg)
+               md.run()
+               md.destroy()
=======================================
--- /dev/null
+++ /trunk/add-ons/gtpwin_example.py    Wed Jul 18 23:13:32 2012
@@ -0,0 +1,28 @@
+#!/usr/bin/python
+
+import sys
+#To use inside GDB, need set the dir of gtpwin.py to this part.
+sys.path.append('/home/teawater/kernel/svn/trunk/add-ons')
+
+import gtpwin
+
+nnn = 100
+
+class example(gtpwin.gtpline):
+       def load_new_val(self):
+               global nnn
+               nnn += 20
+               self.add(nnn)
+               return nnn
+
+l = [example("a"), example("b")]
+l.append(example("wwwwwwww"))
+l.append(example("wwwwwwww11"))
+l.append(example("wwwwwwww"))
+l.append(example("wwwwwwww"))
+l.append(example("wwwwwwww"))
+l.append(example("wwwwwwww"))
+l.append(example("wwwwwwww"))
+win = gtpwin.gtpwin(l, "test")
+gtpwin.run()
+del(win)

Other related posts:

  • » [kgtp] r1171 committed - Add gtpwin.py and gtpwin_example.py. - kgtp