Hi

Attached is a grid class I wrote which may help you.

Regards

Paul


Laszlo Nagy wrote:
I have a gtk.Table inside a scrolled window. I have many rows and 
columns in the Table. Each cell in the table contains a widget 
(typically a button, but not necessarily.) Some of the cells on the 
edges of the table are headers. They should always be visible even when 
the user scrolls in the middle of the Table.

How can I achieve that? If this cannot be done with gtk.Table, can you 
please suggest another widget that can do the job for me? (If the cells 
cannot hold Widgets but can receive events then it may be a good 
solution...)

Number of cells can be anything from 10 to 10 000.

Thanks,

   Laszlo

_______________________________________________
pygtk mailing list   [email protected]
http://www.daa.com.au/mailman/listinfo/pygtk
Read the PyGTK FAQ: http://www.async.com.br/faq/pygtk/

  
import gtk
import pango

class ScrollGrid:
    """
    A scrolled grid widget
    """
    def __init__(self, **args):
        defaults = {
            "scrn": None,                   # A VBox
            "width": 600,
            "height": 400,
            "heads": [],                    # General Headings
            "cols": None,                   # Column Headings
            "rows": None,                   # Number of rows
            "form": [],                     # Format of data fields as follows:
                                            #   Code  - As per the Format class
                                            #   Size  - Total size . Decimals
                                            #   Event - True or False
            "data": [],                     # Main table data
            "event": None,                  # A function to execute
            "butt": [],                     # Additional buttons
            "pbar": None}                   # Progressbar object
        for nam in args.keys():
            defaults[nam] = args[nam]
        for nam in defaults.keys():
            exec "self.%s = defaults[nam]" % nam
        self.doVariables()
        self.doProcess()

    def doVariables(self):
        if type(self.butt) == tuple:
            self.butt = list(self.butt)
        self.butt.append(("gtk-close", self.closeProcess))

    def doProcess(self):
        # main headings
        colr = self.scrn.get_style().copy().bg[gtk.STATE_ACTIVE]
        for head in self.heads:
            ebox = gtk.EventBox()
            ebox.modify_bg(gtk.STATE_NORMAL, colr)
            self.scrn.pack_start(ebox, False, False, 0)
            labl = gtk.Label()
            ebox.add(labl)
            if head:
                labl.set_markup("<b>%s</b>" % head.replace("&", "&amp;"))
        # create a heading scrolled window
        self.hwin = gtk.ScrolledWindow()
        self.hwin.set_size_request(self.width, -1)
        self.hwin.set_policy(gtk.POLICY_NEVER, gtk.POLICY_ALWAYS)
        self.hadj = self.hwin.get_hadjustment()
        self.scrn.pack_start(self.hwin, True, True, 0)
        # create an eventbox
        ebox = gtk.EventBox()
        ebox.modify_bg(gtk.STATE_NORMAL, colr)
        self.hwin.add_with_viewport(ebox)
        # create a table for the column headings
        headtab = gtk.Table(rows=len(self.cols), columns=len(self.form),
            homogeneous=False)
        ebox.add(headtab)
        # column headings
        for y, col in enumerate(self.cols):
            for x, c in enumerate(col):
                fmt = "%s-%ss" % ("%", int(self.form[x][1]))
                head = gtk.Label()
                head.set_markup(fmt % c.replace("&", "&amp;"))
                headtab.attach(head, x, x+1, y, y+1, 0, 0, 0, 0)
                exec "self.hlabl_%s_%s = head" % (y, x)
        # create a body scrolled window
        self.bwin = gtk.ScrolledWindow()
        self.bwin.set_size_request(self.width, self.height)
        self.bwin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_ALWAYS)
        self.badj = self.bwin.get_hadjustment()
        self.badj.connect("notify::value", self.doHAdjustment)
        self.scrn.pack_start(self.bwin, True, True, 0)
        # create a table for the body details
        bodytab = gtk.Table(rows=self.rows, columns=len(self.cols[0]),
            homogeneous=False)
        self.bwin.add_with_viewport(bodytab)
        # populate the table
        # column data
        col1 = gtk.gdk.color_parse("white")
        col2 = self.scrn.get_style().copy().bg[gtk.STATE_NORMAL]
        colr = col2
        for y, dat in enumerate(self.data):
            if self.pbar:
                self.pbar.displayProgress()
            if colr == col2:
                colr = col1
            else:
                colr = col2
            for x, d in enumerate(dat):
                ebox = gtk.EventBox()
                ebox.modify_bg(gtk.STATE_NORMAL, colr)
                val = Format(d, self.form[x][0], self.form[x][1])
                if val.err:
                    val = Format(d, "NA", self.form[x][1])
                labl = gtk.Label(val.disp)
                if len(self.form[x]) == 4 and val.work < 0:
                    labl.modify_fg(gtk.STATE_NORMAL,
                        gtk.gdk.color_parse(self.form[x][3]))
                ebox.add(labl)
                if self.form[x][2]:
                    if not self.event:
                        ebox.connect("button_release_event", self.execCmd, y, x)
                    else:
                        ebox.connect(self.event[0], self.event[1], dat[-1], x)
                bodytab.attach(ebox, x, x+1, y, y+1, 0, 0, 0, 0)
                exec "self.blabl_%s_%s = labl" % (y, x)
                exec "self.bcell_%s_%s = ebox" % (y, x)
        self.last = y
        # create a hbox to hold the buttons
        hbox = gtk.HBox(False, 0)
        # create a label and spinbox for the font
        self.scrn.pack_start(hbox, False, False, 10)
        sbl = gtk.Label("Font Size")
        sbl.set_alignment(0, 0.5)
        hbox.pack_start(sbl, False, True, 0)
        sba = gtk.Adjustment(10, 6, 12, 1, 0, 0)
        sbw = gtk.SpinButton(sba, 0, 0)
        sbw.set_wrap(True)
        hbox.pack_start(sbw, False, True, 0)
        sba.connect("value_changed", self.doSetFont, sbw)
        # create the buttons
        for num, but in enumerate(self.butt):
            exec "but%s = gtk.Button(stock=but[0])" % num
            exec "but%s.connect('clicked', self.execCmd, num)" % num
            exec "but%s.set_flags(gtk.CAN_DEFAULT)" % num
            exec "hbox.pack_start(but%s, True, True, 0)" % num
            exec "but%s.show()" % num
        self.scrn.show_all()
        if self.pbar:
            self.pbar.closeProgress()

    def doSetFont(self, *args):
        while gtk.events_pending():
            gtk.main_iteration()
        size = args[1].get_value_as_int()
        font = pango.FontDescription("Courier %s" % size)
        for y, col in enumerate(self.cols):
            for x, c in enumerate(col):
                exec "self.hlabl_%s_%s.modify_font(font)" % (y, x)
        for y in range(0, self.last + 1):
            for x, c in enumerate(col):
                try:
                    exec "self.blabl_%s_%s.modify_font(font)" % (y, x)
                except:
                    pass

    def doHAdjustment(self, *args):
        self.hadj.set_value(args[0].get_value())

    def hideCol(self, col):
        for row in range(0, self.last + 1):
            try:
                exec "self.hlabl_%s_%s.hide()" % (row, col)
            except:
                pass
            try:
                exec "self.bcell_%s_%s.hide()" % (row, col)
            except:
                pass

    def showCol(self, col):
        for row in range(0, self.last + 1):
            try:
                exec "self.hlabl_%s_%s.show()" % (row, col)
            except:
                pass
            try:
                exec "self.bcell_%s_%s.show()" % (row, col)
            except:
                pass

    def execCmd(self, widget, *args):
        if self.butt[args[0]][1]:
            self.butt[args[0]][1]()

    def closeProcess(self, widget=None, *args):
        for child in self.scrn.get_children():
            child.destroy()
        # There must be a main loop in the calling class/module
        gtk.main_quit()

class Format:
    """
    A class to format data

    Data Types
    ============================================================================
    CB = Check Box
    D0 = Date (CCYYMMDD)
    D1 = Date (CCYYMMDD)
    d1 = Date (CCYYMMDD) Alowing Zero
    D2 = Current Period Date (CCYYMM)
    d2 = Current Period Date (CCYYMM) Allowing Zero
    D3 = Date (DD-MMM-YYYY)
    DT = Date and Time (DD-MMM-YYYY-HH:MM)
    FF = File or Directory Format
    LA = Lower Case Alphanumeric (Must also have 'size' set)
    La = Lower Case Alphanumeric Right Justified (Must also have 'size' set)
    HA = Normal Alphanumeric Hidden as for Passwords
    NA = Normal Alphanumeric (Must also have 'size' set)
    Na = Normal Alphanumeric Right Justified (Must also have 'size' set)
    RW = Raw Data, No formatting or checking
    SD = Signed Decimal (size includes sign and decimals)
    Sd = Convert Integer to Signed Decimal (size includes sign and decimals)
    SI = Signed Integer (size includes sign)
    SL = Signed Long Integer (size includes sign)
    TM = Time (HH:MM)
    TS = Timestamp (CCYY-MM-DD HH:MM:SS)
    TV = Text View - This is only used with TartanDialog for input purposes
    Tv = Text View - This is only used with TartanDialog for input purposes
    TX = Text or Blob Alphanumeric Variable Length- Storing Text Views etc.
    UA = Upper Case Alphanumeric (Must also have 'size' set)
    Ua = Upper Case Alphanumeric Right Justified (Must also have 'size' set)
    UD = Unsigned Decimal (size includes decimals)
    Ud = Convert Integer to Unsigned Decimal (size includes decimals)
    UI = Unsigned Integer
    UL = Unsigned Long Integer
    US = Unsigned Serial
    """
    def __init__(self, data, type, size):
        self.mthnum = {
            "JAN":1, "FEB":2, "MAR":3, "APR":4, "MAY":5, "JUN":6,
            "JUL":7, "AUG":8, "SEP":9, "OCT":10, "NOV":11, "DEC":12}
        #=======================================================================
        # Work around data types from TartanDialog which are 3 characters long
        #=======================================================================
        if len(type) == 3:
            type = type[1:]
        #=======================================================================
        # Work around for None
        #=======================================================================
        if data == None:
            if type[1].lower() in ("a", "v", "w", "x"):
                self.data = ""
            else:
                self.data = "0"
        #=======================================================================
        # Raw Data Type
        #=======================================================================
        if  type == "RW":
            self.err = ""
            self.work = self.disp = self.data = data
            return
        #=======================================================================
        # Timestamp
        #=======================================================================
        if  type == "TS":
            self.err = ""
            self.work = self.disp = self.data = data
            return
        #=======================================================================
        # Work around for previous format error
        #=======================================================================
        elif not type[0] == "T" and type[1].upper() != "A" and data == "None":
            self.data = str(0)
        #=======================================================================
        else:
            self.data = str(data)
        self.data = self.data.strip()
        self.type = type
        self.size = size
        if type in ("D1","d1","D2","d2","DT","dT","TM"):
            if self.data[-1:] == "L":
                self.data = self.data[:-1]
        elif type in ("Sd", "Ud"):
            self.data = str(float(long(self.data) / 100.0))
        elif type[1] in ("I","L"):
            self.data = self.data.split(".")[0]
            if self.data[-1:] == "L":
                self.data = self.data[:-1]
        elif self.type[1].lower() in ("a", "v", "x"):
            self.data = self.data.replace("\\", "/")
        self.processData()

    def processData(self):
        self.quo = int(self.size / 1)
        self.rem = int(round((self.size % 1) * 10))
        self.disp = None
        self.work = None
        self.err = ""
        if self.type in ("D0","d0"):
            # Work around for previous format error
            #======================================
            if self.mthnum.has_key(self.data[3:6].upper()):
                self.chkD3_Date()
            else:
                self.chkD0_Date()
        elif self.type in ("D1","d1"):
            self.chkD1_Date()
        elif self.type in ("D2","d2"):
            self.chkD2_Date()
        elif self.type in ("D3","d3"):
            self.chkD3_Date()
        elif self.type in ("DT","dT"):
            self.chkDT_Date()
        elif self.type == "TM":
            self.chkTM_Time()
        elif self.type[1] in ("F","A","a"):
            dat = self.data[:self.quo]
            if self.type[1] in ("F","A"):
                if self.data == "":
                    self.work = dat
                    self.disp = " " * self.quo
                else:
                    if self.type[0] == "L":
                        dat = dat.lower()
                    elif self.type[0] == "U":
                        dat = dat.upper()
                    self.work = dat
                    self.disp = dat.ljust(self.quo)
            elif self.type[1] == "a":
                try:
                    if dat[-1:] == "L":
                        raise exception
                    dat = str(long(dat))
                    if dat[-1:] == "L":
                        dat = dat[:-1]
                    self.work = dat.rjust(self.quo)
                    self.disp = dat.rjust(self.quo)
                except:
                    if self.type[0] == "L":
                        dat = dat.lower()
                    elif self.type[0] == "U":
                        dat = dat.upper()
                    self.work = dat
                    self.disp = dat.ljust(self.quo)
        elif self.type == "UI":
            self.unsignedInteger()
        elif self.type == "US":
            self.unsignedInteger()
        elif self.type == "SI":
            self.signedInteger()
        elif self.type == "UL":
            self.unsignedLong()
        elif self.type == "SL":
            self.signedLong()
        elif self.type in ("UD", "Ud"):
            self.unsignedDecimal()
        elif self.type in ("SD", "Sd"):
            self.signedDecimal()
        elif self.type in ("TV", "Tv", "TX"):
            self.work = self.data
            self.disp = self.data
        else:
            self.err = "Invalid Input, Retry (%s)" % self.type

    def chkD0_Date(self):
        date = self.data.replace("-", "")
        self.disp = date
        try:
            self.work = int(date.replace("-", ""))
        except:
            self.work = date

    def chkD1_Date(self):
        date = self.data.replace("-", "")
        if date in ("", "0", "00000000") and (self.type == "d1"):
            self.work = 0
            self.disp = "0000-00-00"
        else:
            try:
                if len(date) < 5 or len(date) > 8:
                    raise Exception
                yy = int(date[0:(len(date) - 4)])
                mm = int(date[(len(date) - 4):(len(date) - 2)])
                dd = int(date[(len(date) - 2):len(date)])
                if yy < 100 and yy > 30:
                    yy += 1900
                elif yy < 100:
                    yy += 2000
                if mm < 01 or mm > 12:
                    self.err = "Invalid Date (D1-1)"
                    return
                chkmth = copy.deepcopy(mthnam)
                if mm == 2:
                    if (yy % 4) == 0:
                        chkmth[2][2] = 29
                    else:
                        chkmth[2][2] = 28
                if dd < 1 or dd > chkmth[mm][2]:
                    self.err = "Invalid Date (D1-2)"
                    return
                self.work = (yy * 10000) + (mm * 100) + dd
                self.disp = "%04i-%02i-%02i" % (yy, mm, dd)
                if len(self.disp) < self.size:
                    self.disp = self.disp + \
                    (" " * (int(self.size/1) - len(self.disp)))
            except:
                self.err = "Invalid Date (D1-3)"

    def chkD2_Date(self):
        date = self.data.replace("-", "")
        if date in ("", "0", "000000") and (self.type == "d2"):
            self.work = 0
            self.disp = "0000-00"
        else:
            try:
                if len(date) < 3 or len(date) > 6:
                    raise Exception
                yy = int(date[0:(len(date) - 2)])
                mm = int(date[(len(date) - 2):len(date)])
                if yy < 100 and yy > 30:
                    yy += 1900
                elif yy < 100:
                    yy += 2000
                if mm < 01 or mm > 12:
                    self.err = "Invalid Month (D2-1)"
                else:
                    self.work = (yy * 100) + mm
                    self.disp = "%04i-%02i" % (yy, mm)
                    if len(self.disp) < self.size:
                        self.disp = self.disp + \
                        (" " * (int(self.size/1) - len(self.disp)))
            except:
                self.err = "Invalid Current Date (D2-2)"

    def chkD3_Date(self):
        date = self.data
        self.work = date
        self.disp = date
        try:
            yy = int(date[7:11])
            mm = self.mthnum[date[3:6].upper()]
            dd = int(date[0:2])
            if yy < 100 and yy > 30:
                yy += 1900
            elif yy < 100:
                yy += 2000
            chkmth = copy.deepcopy(mthnam)
            if mm == 2:
                if (yy % 4) == 0:
                    chkmth[2][2] = 29
                else:
                    chkmth[2][2] = 28
            if mm < 01 or mm > 12:
                self.err = "Invalid Month (D3-1)"
            elif dd < 1 or dd > chkmth[mm][2]:
                self.err = "Invalid Day (D3-2)"
            else:
                self.isoDate = (yy * 10000) + (mm*100) + dd
        except:
            self.err = "Invalid Date (D3-3)"

    def chkDT_Date(self):
        date = self.data.replace("-", "")
        date = self.data.replace(":", "")
        if date in ("", "0", "00000000") and (self.type == "dT"):
            self.work = 0
            self.disp = "0000-00-00-00:00"
        else:
            try:
                if len(date) < 9 or len(date) > 12:
                    raise Exception
                yy = int(date[0:(len(date) - 8)])
                mm = int(date[(len(date) - 8):(len(date) - 6)])
                dd = int(date[(len(date) - 6):(len(date) - 4)])
                hh = int(date[(len(date) - 4):(len(date) - 2)])
                tt = int(date[(len(date) - 2):len(date)])
                if yy < 100 and yy > 30:
                    yy += 1900
                elif yy < 100:
                    yy += 2000
                if mm < 01 or mm > 12:
                    self.err = "Invalid Date (D1-1)"
                    return
                chkmth = copy.deepcopy(mthnam)
                if mm == 2:
                    if (yy % 4) == 0:
                        chkmth[2][2] = 29
                    else:
                        chkmth[2][2] = 28
                if dd < 1 or dd > chkmth[mm][2]:
                    self.err = "Invalid Date (D1-2)"
                    return
                self.work = (yy*100000000)+(mm*1000000)+(dd*10000)+(hh*100)+tt
                self.disp = "%04i-%02i-%02i-%02i:%02i" % (yy, mm, dd, hh, tt)
                if len(self.disp) < self.size:
                    self.disp = self.disp + \
                    (" " * (int(self.size/1) - len(self.disp)))
            except:
                self.err = "Invalid Date (DT)"

    def chkTM_Time(self):
        time = self.data.replace(":", "")
        try:
            if len(time) < 1 or len(time) > 4:
                raise Exception
            time = int(time)
            hh = time / 100
            mm = time % 100
            self.work = (hh*100)+mm
            self.disp = "%02i:%02i" % (hh, mm)
            if len(self.disp) < self.size:
                self.disp = self.disp+(" "*(int(self.size/1)-len(self.disp)))
        except:
            self.err = "Invalid Time (TM)"

    def unsignedInteger(self):
        if self.data == "":
            self.data = "0"
        try:
            if self.data.find("-") != -1:
                self.err = "Invalid UnSigned Integer (UI-)"
            else:
                self.work = int(self.data)
                self.disp = self.data.rjust(self.quo)
                if len(self.disp) > self.quo:
                    self.err = "Invalid UnSigned Integer (UIs)"
        except:
            self.err = "Invalid UnSigned Integer (UI)"

    def signedInteger(self):
        if self.data == "":
            self.data = "0"
        try:
            s = self.data.find("-")
            if s == (len(self.data) - 1):
                self.data = self.data.replace("-", "")
                self.data = "-" + self.data
            self.work = int(self.data)
            s = self.data.find("-")
            if s != -1:
                self.data = self.data.replace("-", "")
                self.data = self.data + "-"
            else:
                self.data = self.data + " "
            self.disp = self.data.rjust(self.quo)
            if len(self.disp) > self.quo:
                self.err = "Invalid UnSigned Integer (UIs)"
        except:
            self.err = "Invalid Signed Integer (SI)"

    def unsignedLong(self):
        if self.data == "":
            self.data = "0"
        try:
            if self.data.find("-") != -1:
                self.err = "Invalid UnSigned Long (UI-)"
            else:
                self.work = long(self.data)
                self.disp = self.data.rjust(self.quo)
                if len(self.disp) > self.quo:
                    self.err = "Invalid UnSigned Long (ULs)"
        except:
            self.err = "Invalid UnSigned Long (UL)"

    def signedLong(self):
        if self.data == "":
            self.data = "0"
        try:
            s = self.data.find("-")
            if s == (len(self.data) - 1):
                self.data = self.data.replace("-", "")
                self.data = "-" + self.data
            self.work = long(self.data)
            s = self.data.find("-")
            if s != -1:
                self.data = self.data.replace("-", "")
                self.data = self.data + "-"
            else:
                self.data = self.data + " "
            self.disp = self.data.rjust(self.quo)
            if len(self.disp) > self.quo:
                self.err = "Invalid UnSigned Long (ULs)"
        except:
            self.err = "Invalid Signed Long (SL)"

    def unsignedDecimal(self):
        if self.data == "":
            self.data = "0.0"
        try:
            if self.data.find("-") != -1:
                self.err = "Invalid UnSigned Decimal (UD-)"
            else:
                if self.data.find(".") == -1:
                    self.data = self.data + "." + (self.rem*"0")
                self.work = float(self.data)
                dec = self.data.split(".", self.rem)
                if len(dec[0]) > self.quo - (self.rem + 1):
                    self.err = "Invalid Unsigned Decimal (UDs)"
                elif len(dec[1]) > self.rem:
                    self.err = "Invalid Unsigned Decimal (UDd)"
                else:
                    self.data = self.data + ((self.rem - len(dec[1]))*"0")
                    self.disp = self.data.rjust(self.quo)
                    d = len(self.disp) - self.quo
                    if d > 0:
                        self.disp = self.disp[d:]
        except:
            self.err = "Invalid UnSigned Decimal (UD)"

    def signedDecimal(self):
        if self.data == "":
            self.data = "0.0"
        try:
            s = self.data.find("-")
            if s == (len(self.data) - 1):
                self.data = self.data.replace("-", "")
                self.data = "-" + self.data
            if self.data.find(".") == -1:
                self.data = self.data + "." + (self.rem*"0")
            self.work = float(self.data)
            dec = self.data.split(".", self.rem)
            if len(dec[0]) > self.quo - (self.rem + 1):
                self.err = "Invalid Signed Decimal (SDs)"
            elif len(dec[1]) > self.rem:
                self.err = "Invalid Signed Decimal (SDd)"
            else:
                self.data = self.data + ((self.rem - len(dec[1]))*"0")
                s = self.data.find("-")
                if s != -1:
                    self.data = self.data.replace("-", "")
                    self.data = self.data + "-"
                else:
                    self.data = self.data + " "
                self.disp = self.data.rjust(self.quo)
                d = len(self.disp) - self.quo
                if d > 0:
                    self.disp = self.disp[d:]
        except:
            self.err = "Invalid Signed Decimal (SD)"

def clicked(*args):
    print "row", args[2], "col", args[3]

def quit(*args):
    print args

if __name__ == "__main__":
    heads = ("ABC Company (Pty) Limited", "",
        "Financial Statements for the Period Ending 2008-02-29")
    cols = (
        (
        "",
        "-------------", "-- Month-01 -","------------ ",
        "-------------", "-- Month-02 -","------------ ",
        "-------------", "-- Month-03 -","------------ ",
        "-------------", "-- Month-04 -","------------ ",
        "-------------", "-- Month-05 -","------------ ",
        "-------------", "-- Month-06 -","------------ ",
        "-------------", "-- Month-07 -","------------ ",
        "-------------", "-- Month-08 -","------------ ",
        "-------------", "-- Month-09 -","------------ ",
        "-------------", "-- Month-10 -","------------ ",
        "-------------", "-- Month-11 -","------------ ",
        "-------------", "-- Month-12 -","------------ ",
        "-------------", "--- Totals --","------------ "),
        (
        "Description",
        "Current-Year ", "   Last-Year ", "      Budget ",
        "Current-Year ", "   Last-Year ", "      Budget ",
        "Current-Year ", "   Last-Year ", "      Budget ",
        "Current-Year ", "   Last-Year ", "      Budget ",
        "Current-Year ", "   Last-Year ", "      Budget ",
        "Current-Year ", "   Last-Year ", "      Budget ",
        "Current-Year ", "   Last-Year ", "      Budget ",
        "Current-Year ", "   Last-Year ", "      Budget ",
        "Current-Year ", "   Last-Year ", "      Budget ",
        "Current-Year ", "   Last-Year ", "      Budget ",
        "Current-Year ", "   Last-Year ", "      Budget ",
        "Current-Year ", "   Last-Year ", "      Budget ",
        "Current-Year ", "   Last-Year ", "      Budget "))
    form = (
        ("NA", 30, False),
        ("SD", 13.2, True), ("SD", 13.2, False), ("SD", 13.2, False),
        ("SD", 13.2, True), ("SD", 13.2, False), ("SD", 13.2, False),
        ("SD", 13.2, True), ("SD", 13.2, False), ("SD", 13.2, False),
        ("SD", 13.2, True), ("SD", 13.2, False), ("SD", 13.2, False),
        ("SD", 13.2, True), ("SD", 13.2, False), ("SD", 13.2, False),
        ("SD", 13.2, True), ("SD", 13.2, False), ("SD", 13.2, False),
        ("SD", 13.2, True), ("SD", 13.2, False), ("SD", 13.2, False),
        ("SD", 13.2, True), ("SD", 13.2, False), ("SD", 13.2, False),
        ("SD", 13.2, True), ("SD", 13.2, False), ("SD", 13.2, False),
        ("SD", 13.2, True), ("SD", 13.2, False), ("SD", 13.2, False),
        ("SD", 13.2, True), ("SD", 13.2, False), ("SD", 13.2, False),
        ("SD", 13.2, True), ("SD", 13.2, False), ("SD", 13.2, False),
        ("SD", 13.2, True), ("SD", 13.2, False), ("SD", 13.2, False))
    data = [("One",100,100,100,200,200,200,300,300,300,400,400,400,500,500,500,
            600,600,600,700,700,700,800,800,800,900,900,900,1000,1000,1000,
            1100,1100,1100,1200,1200,1200,7800,7800,7800)] * 30

    win = gtk.Window()
    win.set_size_request(800, 600)
    win.get_settings().set_string_property('gtk-font-name', 'courier 10','')
    scrn = gtk.VBox()
    win.add(scrn)

    size = win.get_size()
    width = int(size[0] * .95)
    height = height=int(size[1] * .70)
    swin = ScrollGrid(scrn=scrn, width=width, height=height, heads=heads,
        rows=3, cols=cols, form=form, data=data, event=("button_release_event",
        clicked))

    win.show_all()
    gtk.main()
_______________________________________________
pygtk mailing list   [email protected]
http://www.daa.com.au/mailman/listinfo/pygtk
Read the PyGTK FAQ: http://www.async.com.br/faq/pygtk/

Reply via email to