view sandbox/ttk.py @ 645:88c246f20918
Fixed monomer pickling to avoid name clashes. This breaks pickle backwards-compatiblity! [see #35]
Previosly all monomer classes were stored a single namespace,
allpy.data.monomers. This caused a few name clashes, which were mostly
resolved, and one name clash, that was not. (This caused one class to be named
differently depending on the order in which modules were loaded).
Now, instead of one allpy.data.monomers module we have allpy.data.monomers
package with modules dna, rna, protein. This ensures that all name clashes are
resolved uniformly upon any sequence of modules loading.
This may also help in future to keep backward-compatibility longer in case we
replace dynaminc monomer class creation with storing the classes in the module -
if we want to retain independent loading of dna/rna/protein parts.
| author |
Daniil Alexeyevsky <dendik@kodomo.fbb.msu.ru> |
| date |
Wed, 08 Jun 2011 21:31:02 +0400 |
| parents |
ef6692b5ffbc |
| children |
61e5d8e146c7 |
line source
1 from tkinter import ttk, filedialog
4 class Scrollbar(tkinter.Scrollbar):
6 def __init__(self, *args, **kw):
7 tkinter.Scrollbar.__init__(self, *args, **kw)
8 self['command'] = self._command
9 self._attached_widgets = set()
10 self._orient = {'horizontal': 'x', 'vertical': 'y'}[self['orient']]
12 def attach(self, widget):
13 self._attached_widgets.add(widget)
14 command = self._orient + 'scrollcommand'
15 widget[command] = lambda *args, **kw: self._set(widget, *args, **kw)
17 def _command(self, *args, **kw):
18 command = self._orient + 'view'
20 for widget in self._attached_widgets:
21 result = getattr(widget, command)(*args, **kw)
24 def _set(self, sender, *args, **kw):
25 command = self._orient + 'view'
27 for widget in self._attached_widgets:
30 getattr(widget, command)('moveto', args[0])
32 class MegaText(tkinter.Text):
34 def __init__(self, *args, **kw):
35 tkinter.Text.__init__(self, *args, **kw)
37 self.bind("<B1-Motion>", self._select)
38 self.bind("<B1-ButtonRelease>", self._select_end)
39 self.tag_configure('vselection', borderwidth=1, relief="solid", background='#ffbbbb')
41 def tag_clear(self, tag):
42 """Remove the tag from anywhere in the text."""
43 ranges = self.tag_ranges(tag)
44 for begin, end in zip(ranges[::2], ranges[1::2]):
45 self.tag_remove(tag, begin, end)
47 def insert(self, *args, **kw):
48 self['state'] = 'normal'
49 result = tkinter.Text.insert(self, *args, **kw)
50 self['state'] = 'disabled'
53 def _select (self, ev):
54 index = self.index("@%s,%s" % (ev.x, ev.y))
55 line, pos = map(int, index.split('.'))
56 if not hasattr(self, '_selection'):
57 self._selection = [line, line, pos, pos]
58 self._selection[1] = line
59 self._selection[3] = pos
61 self.tag_clear('vselection')
62 line0, line1 = sorted(self._selection[0:2])
63 pos0, pos1 = sorted(self._selection[2:4])
64 for line in range(line0, line1 + 1):
67 '%s.%s' % (line, pos0),
68 '%s.%s' % (line, pos1)
72 def _select_end(self, ev):
79 names.delete(0, 'end')
80 sequences.delete('1.0', 'end')
82 filename = filedialog.askopenfilename()
84 for item in open(filename).read().split('\n>'):
85 lines = item.split('\n')
86 name = lines[0].lstrip('>').strip()
87 body = "".join(map(str.strip, lines[1:]))
89 names.insert('end', name)
90 sequences.insert('end', body+'\n')
91 line = int(sequences.index('end - 1 line').split('.')[0])
92 seqs.add((name, body, line))
95 length = len(list(seqs)[0][1])
98 for pos in range(length):
100 for name, seq, _ in seqs:
102 weights[char] = weights.get(char, 0) + 1
104 weights[char] = weights[char] * 10 // num_seqs
105 seq_weights.append(weights)
107 for name, seq, line in seqs:
108 for pos in range(len(seq)):
110 tag = 'id%d0' % seq_weights[pos].get(char, 0)
111 sequences.tag_add(tag, '%d.%d' % (line, pos))
113 for id in range(10+1):
114 w = (10 - id) * 256 / 10
115 color = '#%02x%02x%02x' % (w, w, w)
116 sequences.tag_configure('id%d0' % id, background=color)
120 root.option_add('*tearOff', False)
121 menu = tkinter.Menu(root)
122 menu_file = tkinter.Menu(menu)
123 menu_file.add_command(label='Open', command=open_file)
124 menu.add_cascade(menu=menu_file, label='File')
125 menu.add_command(label='Colorize', command=colorize)
128 main = ttk.PanedWindow(root, orient="horizontal")
129 names = tkinter.Listbox(main)
130 sequences = MegaText(main)
132 sequences['font'] = names['font'] = "Courier 10"
135 sequences.tag_clear('sel')
136 for line in names.curselection():
138 sequences.tag_add('sel', "%s.0" % line, "%s.end" % line)
139 sequences['inactiveselectbackground'] = 'blue'
140 names.bind('<<ListboxSelect>>', _select)
142 #sequences['spacing3'] = 1
143 sequences['exportselection'] = False
144 sequences['wrap'] = 'none'
145 #names['selectborderwidth'] = -1
146 names['highlightthickness'] = 0
147 names['activestyle'] = 'none'
148 names['exportselection'] = False
152 main.pack(side='right', fill='both', expand=True)
154 vscroll = Scrollbar(root, orient='vertical')
155 vscroll.attach(names)
156 vscroll.attach(sequences)
157 vscroll.pack(side='right', fill='y')