# Copyright 2000 by Katharine Lindner (Cayte). # Copyright 2016 by Markus Piotrowski. # All rights reserved. # This code is part of the Biopython distribution and governed by its # license. Please see the LICENSE file that should have been included # as part of this package. # # The original SeqGui was written by Katharine Lindner (Cayte) in 2000 using # the wxPython library for the GUI. It was rewritten by Markus Piotrowski in # 2016 using tkinter and tkinter's themed widgets (ttk). """A small GUI tool to demonstrate some basic sequence operations. SeqGui (sequence graphical user interface) is a little tool that allows transcription, translation and back translation of a sequence that the user can type or copy into a text field. For translation the user can select from several codon tables which are implemented in Biopython. It runs as a standalone application. """ from __future__ import print_function from Bio.Seq import translate, transcribe, back_transcribe from Bio.Data import CodonTable try: # Python 2 import Tkinter as tk import ttk except ImportError: # Python 3 import tkinter as tk import tkinter.ttk as ttk main_window = tk.Tk() main_window.title('Greetings from Biopython') menue = tk.Menu(main_window) menue_single = tk.Menu(menue, tearoff=0) menue.add_cascade(menu=menue_single, label='File') menue_single.add_command(label='About') menue_single.add_separator() menue_single.add_command(label='Exit', command=main_window.destroy) main_window.config(menu=menue) # Left panel with parameters param_panel = ttk.Frame(main_window, relief=tk.GROOVE, padding=5) codon_panel = ttk.LabelFrame(param_panel, text='Codon Tables') codon_scroller = ttk.Scrollbar(codon_panel, orient=tk.VERTICAL) codon_list = tk.Listbox(codon_panel, height=5, width=25, yscrollcommand=codon_scroller.set) # Import actual codon tables from Biopython and sort alphabetically codon_table_list = sorted([table.names[0] for n, table in CodonTable.generic_by_id.items()]) # 'Standard' table should be first in the list del(codon_table_list[codon_table_list.index('Standard')]) codon_table_list.insert(0, 'Standard') for codon_table in codon_table_list: codon_list.insert(tk.END, codon_table) codon_list.selection_set(0) codon_list.configure(exportselection=False) codon_scroller.config(command=codon_list.yview) # Radiobuttons are more appropiate than another listbox here: transform_panel = ttk.LabelFrame(param_panel, text='Transformation') transform_var = tk.StringVar() transform_transcribe = ttk.Radiobutton(transform_panel, text='Transcribe', variable=transform_var, value='transcribe') transform_translate = ttk.Radiobutton(transform_panel, text='Translate', variable=transform_var, value='translate') transform_backtranscribe = ttk.Radiobutton(transform_panel, text='Back transcribe', variable=transform_var, value='back transcribe') transform_translate.invoke() # Right panel with sequence in- and output seq_panel = ttk.Frame(main_window, relief=tk.GROOVE, padding=5) input_panel = ttk.LabelFrame(seq_panel, text='Original Sequence') input_scroller = ttk.Scrollbar(input_panel, orient=tk.VERTICAL) input_text = tk.Text(input_panel, width=39, height=5, yscrollcommand=input_scroller.set) input_scroller.config(command=input_text.yview) output_panel = ttk.LabelFrame(seq_panel, text='Transformed Sequence') output_scroller = ttk.Scrollbar(output_panel, orient=tk.VERTICAL) output_text = tk.Text(output_panel, width=39, height=5, yscrollcommand=output_scroller.set) output_scroller.config(command=output_text.yview) # Buttons apply_button = ttk.Button(seq_panel, text='Apply') clear_button = ttk.Button(seq_panel, text='Clear') close_button = ttk.Button(seq_panel, text='Close', command=main_window.destroy) # Statusbar statustext = tk.StringVar() statusbar = ttk.Label(main_window, textvariable=statustext, relief=tk.GROOVE, padding=5) statustext.set('This is the statusbar') sizegrip = ttk.Sizegrip(statusbar) # Event methods def clear_output(): """Clear the output window.""" input_text.delete(1.0, tk.END) output_text.delete(1.0, tk.END) return def apply_operation(): """Do the selected operation.""" codon_table = codon_list.get(codon_list.curselection()) print('Code: {}'.format(codon_table)) seq = ''.join(input_text.get(1.0, tk.END).split()) print('Input sequence: {}'.format(seq)) operation = transform_var.get() print('Operation: {}'.format(operation)) if operation == 'transcribe': result = transcribe(seq) elif operation == 'translate': result = translate(seq, table=codon_table, to_stop=True) elif operation == 'back transcribe': result = back_transcribe(seq) else: result = '' output_text.delete(1.0, tk.END) output_text.insert(tk.END, result) print('Result: {}'.format(result)) return def set_statusbar(event): """Show statusbar comments from menu selection.""" index = main_window.call(event.widget, "index", "active") if index == 0: statustext.set('More information about this program') elif index == 2: statustext.set('Terminate the program') else: statustext.set('This is the statusbar') return # Set commands and bind events menue_single.bind('<>', set_statusbar) apply_button.config(command=apply_operation) clear_button.config(command=clear_output) # Build GUI statusbar.pack(side=tk.BOTTOM, padx=1, fill=tk.X) sizegrip.pack(side=tk.RIGHT, padx=3, pady=4) param_panel.pack(side=tk.LEFT, anchor=tk.N, padx=5, pady=10, fill=tk.Y) codon_panel.pack(fill=tk.Y, expand=True) codon_scroller.pack(side=tk.RIGHT, fill=tk.Y) codon_list.pack(fill=tk.Y, expand=True) transform_panel.pack(pady=10, fill=tk.X) transform_transcribe.pack(anchor=tk.W) transform_translate.pack(anchor=tk.W) transform_backtranscribe.pack(anchor=tk.W) seq_panel.pack(anchor=tk.N, padx=5, pady=10, fill=tk.BOTH, expand=True) input_panel.pack(fill=tk.BOTH, expand=True) input_scroller.pack(side=tk.RIGHT, fill=tk.Y) input_text.pack(fill=tk.BOTH, expand=True) output_panel.pack(pady=10, fill=tk.BOTH, expand=True) output_scroller.pack(side=tk.RIGHT, fill=tk.Y) output_text.pack(fill=tk.BOTH, expand=True) apply_button.pack(side=tk.LEFT) clear_button.pack(side=tk.LEFT, padx=10) close_button.pack(side=tk.LEFT) main_window.mainloop()