コード例 #1
0
ファイル: frame.py プロジェクト: aphistic/copilot
class CopilotInnerFrame(CopilotBaseFrame):
    def __init__(self, master, config):
        super(CopilotInnerFrame, self).__init__(master, config)

        if config.full_screen:
            self._make_full(master)

        self.master.grid_rowconfigure(1, weight=1)
        self.master.grid_columnconfigure(1, weight=1)

        self._create_header()

        self._sb = Scrollbar(self._master, orient=VERTICAL)
        self._sb.grid(row=1, column=3, sticky='nse')

        self._next_hidden = False

    def _cmd_back(self):
        self._master.destroy()

    def _create_header(self):
        self.back_btn = Button(
            self._master,
            text='< Back',
            command=self._cmd_back
        )
        self.back_btn.grid(row=0, column=0, sticky='w')

        self._frame_lbl = Label(
            self.master,
            text='',
            anchor='center',
            font=self._config.item_font
        )
        self._frame_lbl.grid(row=0, column=1, sticky='ew')

        self._next_btn = Button(
            self.master,
            text='Next >'
        )
        self._next_btn.grid(row=0, column=2, sticky='e')

    def _hide_next(self):
        if not self._next_hidden:
            self._next_btn.grid_remove()
            self._next_hidden = True

    def _show_next(self):
        if self._next_hidden:
            self._next_btn.grid(row=0, column=2, sticky='e')
            self._next_hidden = False
コード例 #2
0
ファイル: frame.py プロジェクト: aphistic/copilot
class CopilotInnerFrame(CopilotBaseFrame):
    def __init__(self, master, config):
        super(CopilotInnerFrame, self).__init__(master, config)

        if config.full_screen:
            self._make_full(master)

        self.master.grid_rowconfigure(1, weight=1)
        self.master.grid_columnconfigure(1, weight=1)

        self._create_header()

        self._sb = Scrollbar(self._master, orient=VERTICAL)
        self._sb.grid(row=1, column=3, sticky='nse')

        self._next_hidden = False

    def _cmd_back(self):
        self._master.destroy()

    def _create_header(self):
        self.back_btn = Button(self._master,
                               text='< Back',
                               command=self._cmd_back)
        self.back_btn.grid(row=0, column=0, sticky='w')

        self._frame_lbl = Label(self.master,
                                text='',
                                anchor='center',
                                font=self._config.item_font)
        self._frame_lbl.grid(row=0, column=1, sticky='ew')

        self._next_btn = Button(self.master, text='Next >')
        self._next_btn.grid(row=0, column=2, sticky='e')

    def _hide_next(self):
        if not self._next_hidden:
            self._next_btn.grid_remove()
            self._next_hidden = True

    def _show_next(self):
        if self._next_hidden:
            self._next_btn.grid(row=0, column=2, sticky='e')
            self._next_hidden = False
コード例 #3
0
class Playback(Module):
    '''
    Module to handle playback of audio and video files.
    '''
    def __init__(self, app):
        self.app = app
        self.current = None
        if AUDIO_LIBS_INSTALLED:
            info( ' - initializing module: Audio' )
            self.sfile = None
            self.p = pyaudio.PyAudio()
            self.currentInterval = None
            self.started = False
            self.paused = False
            self.sync = threading.Event()
            self.stoprequest = threading.Event()

            # widget management
            #self.frame = Frame(self.app.BOTTOM)
            self.frame = Frame(self.app.LEFT)#, pady=7)

            self.header = Header(self.frame, text="Playback")
            self.playBtn = Button(self.frame, text="⏯", command=self.playpauseAV, state='disabled', takefocus=0) # NOTE: not currently appearing
            self.app.bind('<space>', self.playpauseAV )
            self.app.bind('<Escape>', self.stopAV )
        if VIDEO_LIBS_INSTALLED:
            info( ' - initializing module: Video' )
            self.app.bind('<space>', self.playpauseAV )
            self.app.bind('<Escape>', self.stopAV )
        self.grid()
        self.reset()

    def update(self):
        '''
        don't change the audio file when we change frames
        '''
        pass

    def reset(self):
        '''
        try to load an audio file
        '''
        if AUDIO_LIBS_INSTALLED:
            self.current = None
            audioFallbacks = [ '.wav', '.flac', '.ogg', '.mp3' ]
            for codec in audioFallbacks:
                if self.loadAudio( codec ) == True:
                    self.playBtn.config( state='normal' )
                    return

    def loadAudio(self, codec):
        '''
        load an audio file with a specific codec
        '''
        audiofile = self.app.Data.getFileLevel( codec )
        if audiofile != None:
            try:
                audiofile = self.app.Data.unrelativize(audiofile)
                self.sfile = AudioSegment.from_file( audiofile )
                self.current = audiofile
                self.duration = len(self.sfile)/1000.0
                return True
            except Exception as e:
                error('Unable to load audio file: `%s`' % audiofile, e)
                return False

    def playpauseAV(self, event):
        '''

        '''
        # debug(self.started, self.paused, '1858')
        if self.started == False or self.currentInterval != self.app.TextGrid.selectedItem: #if we haven't started playing or we're in a new interval
            #reset monitoring variables
            self.currentInterval = self.app.TextGrid.selectedItem
            self.started = False
            self.paused = False

            if self.app.TextGrid.selectedItem:
                start, end = self.app.TextGrid.getMinMaxTime()
            else:
                start = self.app.TextGrid.start
                end = self.app.TextGrid.end

            # if VIDEO_LIBS_INSTALLED and AUDIO_LIBS_INSTALLED:
            #   self.readyVideo()
            #   self.readyAudio(start, end)
            #   self.playAudio()
            # elif AUDIO_LIBS_INSTALLED:
            #   self.readyAudio(start, end)
            #   self.playAudio()
            # elif VIDEO_LIBS_INSTALLED:
            #   self.readyVideo()
            #   self.dicomframeQ = queue.Queue()
            #   for i in range(len(self.pngs)):
            #       self.dicomframeQ.put(self.pngs[i])
            #   self.playVideoNoAudio()

            if self.app.Dicom.isLoaded():
                self.readyVideo()
            if AUDIO_LIBS_INSTALLED:
                self.readyAudio(start, end)
                self.playAudio()
            elif self.app.Dicom.isLoaded():
                self.dicomframeQ = queue.Queue()
                for i in range(len(self.pngs)):
                    self.dicomframeQ.put(self.pngs[i])
                self.playVideoNoAudio()

        elif self.started == True:
            if self.paused == False:
                self.paused = True
                self.stream.stop_stream()
            else:
                self.paused = False
                self.playAudio()

    def readyAudio(self, start, end):
        '''

        '''
        #audio stuff
        start_idx = round(float(start)*1000)
        end_idx = round(float(end)*1000)
        self.flen = float(self.app.TextGrid.frame_len)
        fpb = 512
        extrafs = (end_idx-start_idx)%fpb
        extrasecs = extrafs/self.sfile.frame_rate
        pad = AudioSegment.silent(duration=round(extrasecs*1000))
        seg_nopad = self.sfile[start_idx:end_idx]
        self.seg = seg_nopad + pad
        # seg.append()
        self.audioframe = 0

        # open stream using callback (3)
        self.stream = self.p.open(format=self.p.get_format_from_width(self.seg.sample_width),
                        channels=self.seg.channels,
                        rate=self.seg.frame_rate,
                        frames_per_buffer=fpb,
                        output=True,
                        start=False,
                        stream_callback=self.callback)

        # debug(self.seg.frame_count()/fpb, 'number of chunks')
        # debug(self.seg.frame_count()%fpb, 'last chunk size')
        # self.chunkcount = 0

    def readyVideo(self):
        '''

        '''
        self.app.Trace.reset()
        tags = self.app.TextGrid.selectedItem[0].gettags(self.app.TextGrid.selectedItem[1])
        framenums = [tag[5:] for tag in tags if tag[:5]=='frame']
        self.framestart = int(framenums[0])
        imgs = self.app.Dicom.getFrames(framenums)
        canvas = self.app.Dicom.zframe.canvas
        bbox = canvas.bbox(canvas.find_all()[0])
        dim = (bbox[2] - bbox[0], bbox[3] - bbox[1])
        self.pngs = []
        traces = self.app.Data.getTopLevel('traces')
        file = self.app.Data.getCurrentFilename()
        l = util.CROSSHAIR_SELECT_RADIUS
        for frame, img in zip(framenums, imgs):
            img = img.resize(dim)
            draw = ImageDraw.Draw(img)
            for name in traces:
                color = traces[name]['color']
                if file in traces[name]['files'] and frame in traces[name]['files'][file]:
                    for pt in traces[name]['files'][file][frame]:
                        x = int(pt['x'] * img.width)
                        y = int(pt['y'] * img.height)
                        draw.line((x-l, y, x+l, y), fill=color)
                        draw.line((x, y-l, x, y+l), fill=color)
            del draw
            self.pngs.append(ImageTk.PhotoImage(img))

        #video w/audio stuff
        self.dicomframe_timer = 0
        self.dicomframe_num = 1
        self.dicomframeQ = queue.Queue()
        self.dicomframeQ.put(self.pngs[0]) #put now, because audio callback puts frames when audio segments end
        # for i in range(len(self.pngs)):
        #   self.dicomframeQ.put(self.pngs[i])

    def callback(self, in_data, frame_count, time_info, status):
        '''
        Called by pyaudio stream. Gets chunks of audio ready for playing
        With video capabilities, also updates video frame information
        '''
        # self.sync.clear()
        # self.chunkcount+=1
        data = b''.join([self.seg.get_frame(i) for i in range(self.audioframe, self.audioframe+frame_count)])
        # debug(len(data), 'line 1960')
        self.audioframe+=frame_count

        if self.app.Dicom.isLoaded():
            #check & update video frame
            canvas = self.app.Dicom.zframe.canvas
            callbacklen = frame_count/self.seg.frame_rate
            self.dicomframe_timer += callbacklen
            #go to next frame
            if self.dicomframe_timer % self.flen != self.dicomframe_timer and self.dicomframe_num < len(self.pngs):
                floor = math.floor(self.dicomframe_timer/self.flen)
                # debug(floor, 'line 1961')
                self.dicomframe_timer = self.dicomframe_timer-self.flen*floor
                if floor > 1:
                    for i in range(floor-1):
                        # debug(self.dicomframe_num+self.framestart+i, 'putting frame into Q')
                        if self.dicomframe_num+i < len(self.pngs):
                            self.dicomframeQ.put(self.pngs[self.dicomframe_num+i])
                else:
                    self.dicomframeQ.put(self.pngs[self.dicomframe_num])
                # self.sync.set()
                self.dicomframe_num+=floor

                # debug(self.dicomframe_num, len(self.pngs), 'line 1968')
            # else: #stop video loop
                if self.dicomframe_num >= len(self.pngs):
                    self.stoprequest.set()

        return (data, pyaudio.paContinue)

    def playAudio(self):
        self.stream.start_stream()
        self.started = True
        if self.app.Dicom.isLoaded():
            self.playVideoWithAudio()
        else:
            pass #write a loop that keeps audio playing
        # stop stream (6)
        if self.stoprequest.is_set():
            self.stopAV()
        # self.stream.stop_stream()
        # if self.stoprequest.is_set():
        #   self.stream.close()
        #   self.started = False
        # debug(self.chunkcount)
        # close PyAudio (7)
        # self.p.terminate() # NOTE: needs to be removed in order to play multiple audio files in a row

    def playVideoWithAudio(self):
        '''

        '''
        # self.sync.wait()
        if self.paused == True:
            return
        canvas = self.app.Dicom.zframe.canvas
        # debug(self.dicomframeQ.qsize(),'line 1991')
        try:
            pic = self.dicomframeQ.get(timeout=.5)
            canvas.itemconfig(canvas.find_all()[0] , image=pic )
            # canvas.lift(pic)
            # canvas.img = pic
            canvas.update()
        except Exception as e:
            error(e)
        # debug(pic, 'displayed')
        # debug(self.dicomframe_num+self.framestart, 'displayed')
        if not self.stoprequest.is_set() or not self.dicomframeQ.empty(): #should this if be at the top?
            self.playVideoWithAudio()
            # canvas.after(10, self.playVideoWithAudio)

    def playVideoNoAudio(self):
        '''

        '''
        canvas = self.app.Dicom.zframe.canvas
        # pic = self.dicomframeQ.get()
        pic = self.dicomframeQ.get(block=False)
        canvas.itemconfig( canvas.find_all()[0], image=pic )
        canvas.update()
        if not self.dicomframeQ.empty() and self.stoprequest.is_set() == False: #should this if be at the top?
            self.playVideoNoAudio()

    def stopAV(self,event=None):
        self.stoprequest.set()
        if AUDIO_LIBS_INSTALLED:
            self.stream.stop_stream()
            self.stream.close()
        self.started = False
        self.paused = False
        self.app.framesJumpTo()
        self.stoprequest.clear()

    def grid(self):
        ''' grid widgets '''
        self.frame.grid( row=8 )
        self.header.grid()
        self.playBtn.grid()

    def grid_remove(self):
        ''' remove widgets from grid '''
        self.frame.grid_remove()
        self.header.grid_remove()
        self.playBtn.grid_remove()
コード例 #4
0
class StreamFrame(Frame):
    def __init__(self, master):
        super(StreamFrame, self).__init__(master)
        self.root = master

        # check if user has saved the training sentiment analyzers
        pol_checkfile = os.path.exists('files/sa_polarity.pickle')
        subj_checkfile = os.path.exists('files/sa_subjectivity.pickle')

        if not (pol_checkfile
                and subj_checkfile):  # if we cant find the SA files
            # These frames will hold the widgets
            nofiles_frm = Frame(
                self
            )  # this for the the warning message and the back and exit buttons
            nofiles_frm.grid(row=3, column=0, pady=5)
            exit_frm = Frame(self)  # exit frame, contains back and exit button
            exit_frm.grid(row=4, column=0, pady=5)

            message = "SA files not found."
            read_write.log_message("[WARN] (frames.StreamFrame) : " + message)
            message += "\nClick Start Training first to train the NLTK classifiers."
            Label(nofiles_frm, text=message).grid(row=0,
                                                  column=0,
                                                  padx=10,
                                                  pady=5)

            self.mng_stream_btn = Button(
                nofiles_frm,
                text="Start Stream")  # ignore this, if there are no tweets

            # Build the widgets for nofiles_frm
            self.back_btn = Button(exit_frm, text="Back")
            self.back_btn.grid(row=1, column=1, ipadx=5, ipady=3, pady=15)
            self.exit_btn = Button(exit_frm,
                                   text="Exit",
                                   command=self.safe_exit)
            self.exit_btn.grid(row=1,
                               column=3,
                               ipadx=5,
                               ipady=3,
                               padx=15,
                               pady=10)
        else:
            # These frames will hold the widgets
            label_frm = Frame(self)  # this for the label and entry
            label_frm.grid(row=0,
                           column=2,
                           padx=10,
                           pady=10,
                           ipady=20,
                           ipadx=20)

            # Frame for keywords
            self.keywords_frm = Frame(
                self
            )  # this will be hidden until user wants to see previous keywords
            self.keywords_frm.grid(row=0, column=3, rowspan=3, pady=15)

            # Build the widgets for label_frm
            Label(label_frm, text="Keyword:").grid(row=0, column=0, padx=20)
            self.keyword_entry = Entry(label_frm, width=30)
            self.keyword_entry.grid(row=0, column=1, columnspan=3)

            # Build the widgets for button_frm
            self.mng_stream_btn = Button(
                label_frm,
                text="Start Stream")  # this will change from start to stop
            self.mng_stream_btn.grid(row=1,
                                     column=1,
                                     ipadx=5,
                                     ipady=3,
                                     pady=20)
            self.pause_stream_btn = Button(
                label_frm,
                text="Pause Stream")  # if user starts stream, show this button
            self.pause_stream_btn.grid(row=1,
                                       column=3,
                                       ipadx=5,
                                       ipady=3,
                                       padx=10,
                                       pady=20)
            self.pause_stream_btn.grid_remove()

            # Build the widgets for keywords_frm
            self.manage_keywords_btn = Button(
                self.keywords_frm, command=self.show_keywords,
                text=">>>")  # this will change into "<<<" when user clicks it
            self.manage_keywords_btn.grid(row=0,
                                          column=0,
                                          ipadx=5,
                                          ipady=3,
                                          padx=10)

            # Build the widgets for exit_frm
            self.back_btn = Button(label_frm, text="Back")
            self.back_btn.grid(row=2, column=1, ipadx=5, ipady=3, pady=15)
            self.exit_btn = Button(label_frm,
                                   text="Exit",
                                   command=self.safe_exit)
            self.exit_btn.grid(row=2,
                               column=3,
                               ipadx=5,
                               ipady=3,
                               padx=15,
                               pady=10)

    # this method creates a new list box and populates it with the data from keywords.json
    def show_keywords(self):
        # first re-configure the button to show the desired text and change the command into hiding method
        self.manage_keywords_btn.config(text="<<<", command=self.hide_keywords)

        self.previous_keywords = read_write.read_keywords(
        )  # get any previous keywords

        # if there are keywords and the list is not empty
        if len(self.previous_keywords) > 0:
            # build the list box
            self.keyword_lb = Listbox(self.keywords_frm, height=10)
            self.keyword_lb.grid(column=1,
                                 row=0,
                                 pady=10,
                                 padx=5,
                                 sticky=(N, S, E, W))
            # add a binding method
            self.keyword_lb.bind('<Double-1>', self.select_keyword)
            # and add the OK button. This happens here, because we don'w want a button without a list box
            self.select_keyword_btn = Button(self.keywords_frm,
                                             text="OK",
                                             command=self.select_keyword)
            self.select_keyword_btn.grid(row=3,
                                         column=1,
                                         ipady=3,
                                         ipadx=5,
                                         pady=10)

            # adding the keywords to the list box
            counter = 0
            for keyword in self.previous_keywords:
                self.keyword_lb.insert(counter, keyword)
                counter += 1

            # Colorize alternating lines of the listbox
            for i in range(0, len(self.previous_keywords), 2):
                self.keyword_lb.itemconfigure(i, background='#f0f0ff')

    # this method changes the button again and it is called to hide the list box
    def hide_keywords(self):
        self.manage_keywords_btn.config(text=">>>", command=self.show_keywords)
        try:
            # this may result to an error, because we can call hide_keywords before we initialize
            # the list box. This happening if no keywords are present in keywords.json
            self.keyword_lb.destroy()
            self.select_keyword_btn.destroy()
        except AttributeError:
            pass

    def select_keyword(self, *args):
        idxs = self.keyword_lb.curselection()
        if len(idxs) == 1:
            idx = int(idxs[0])
            name = self.previous_keywords[idx]
            self.keyword_entry.delete(0, "end")
            self.keyword_entry.insert(0, name)

    def safe_exit(self):
        x = messagebox.askyesno(title="Exit",
                                message="Are you sure you want to exit?",
                                icon="question")
        if x:
            stream_util.stream_controller.stop()
            read_write.log_message("[INFO]" + stream_util.LOG_NAME +
                                   "Exiting...")
            self.root.destroy()
コード例 #5
0
class CodeStructure(BaseWidget):
    def __init__(self, master, manager):
        BaseWidget.__init__(self, master, 'Code structure', style='border.TFrame')
        self.rowconfigure(1, weight=1)
        self.columnconfigure(0, weight=1)

        self._manager = manager

        header = Frame(self)
        header.columnconfigure(0, weight=1)
        self._close_btn = Button(header, style='close.TButton', padding=0,
                                 command=lambda: self.visible.set(False))
        self._close_btn.grid(row=0, column=1)
        self.filename = Label(header, padding=(4, 0))
        self.filename.grid(row=0, column=0, sticky='w')

        self.codetree = CodeTree(self)
        self._sx = AutoHideScrollbar(self, orient='horizontal', command=self.codetree.xview)
        self._sy = AutoHideScrollbar(self, orient='vertical', command=self.codetree.yview)

        self.goto_frame = Frame(self)
        Label(self.goto_frame, text='Go to:').pack(side='left')
        self.goto_entry = AutoCompleteCombobox2(self.goto_frame, completevalues=[])
        self.goto_entry.pack(side='left', fill='x', expand=True, pady=4, padx=4)
        self._goto_index = 0

        self.codetree.configure(xscrollcommand=self._sx.set,
                                yscrollcommand=self._sy.set)

        header.grid(row=0, columnspan=2, sticky='we')
        self.codetree.grid(row=1, column=0, sticky='ewns')
        self._sx.grid(row=2, column=0, sticky='ew')
        self._sy.grid(row=1, column=1, sticky='ns')
        Frame(self, style='separator.TFrame', height=1).grid(row=3, column=0, columnspan=2, sticky='ew')
        self.goto_frame.grid(row=4, column=0, columnspan=2, sticky='nsew')

        self.set_callback = self.codetree.set_callback

        self.goto_entry.bind('<Return>', self.goto)
        self.goto_entry.bind('<<ComboboxSelected>>', self.goto)
        self.goto_entry.bind('<Key>', self._reset_goto)

    @property
    def manager(self):
        return self._manager

    @manager.setter
    def manager(self, new_manager):
        if CONFIG.get("General", "layout") in ["vertical", "horizontal2"]:
            self.configure(style='TFrame')
            self._close_btn.grid_remove()
        else:
            self.configure(style='border.TFrame')
            self._close_btn.grid()
        if self.visible.get():
            try:
                self._manager.forget(self)
            except TclError:
                pass
            self._manager = new_manager
            self.show()
        else:
            self._manager = new_manager

    def _reset_goto(self, event):
        self._goto_index = 0

    def focus_set(self):
        self.goto_entry.focus_set()

    def hide(self):
        try:
            layout = CONFIG.get("General", "layout")
            if layout in ["vertical", "horizontal2"]:
                self.manager.hide(self)
            else:
                # save layout
                old = CONFIG.get("Layout", layout).split()
                w = self.master.winfo_width()
                pos = '%.3f' % (self.master.sashpos(0)/w)
                CONFIG.set("Layout", layout, f"{pos} {old[1]}")
                CONFIG.save()
                self.manager.forget(self)
        except TclError:
            pass

    def show(self):
        layout = CONFIG.get("General", "layout")
        if layout in ["vertical", "horizontal2"]:
            self.manager.add(self, text=self.name)
            self.manager.select(self)
        else:
            self.manager.insert(0, self, weight=1)
            w = self.master.winfo_width()
            pos = int(float(CONFIG.get("Layout", layout).split()[0]) * w)
            self.master.sashpos(0, pos)

    def _visibility_trace(self, *args):
        visible = self.visible.get()
        if visible:
            self.show()
        else:
            self.hide()
        CONFIG.set('Code structure', 'visible', str(visible))
        CONFIG.save()

    def get_cells(self):
        return self.codetree.cells

    def clear(self, event=None):
        self.codetree.delete(*self.codetree.get_children())
        self.filename.configure(text='')

    def populate(self, title, text):
        reset = self.filename.cget('text') != title
        self.filename.configure(text=title)
        self._sx.timer = self._sx.threshold + 1
        self._sy.timer = self._sy.threshold + 1
        try:
            names = list(self.codetree.populate(text, reset))
        except TclError:
            logging.exception('CodeStructure Error')
            self.codetree.delete(*self.codetree.get_children())
            return
        names.sort()
        self.goto_entry.delete(0, "end")
        self.goto_entry.set_completion_list(names)
        self.event_generate('<<Populate>>')

    def goto(self, event):
        name = self.goto_entry.get()
        res = self.codetree.tag_has(name)
        if res:
            if self._goto_index >= len(res):
                self._goto_index = 0
            self.codetree.see(res[self._goto_index])
            self.codetree.selection_remove(*self.codetree.selection())
            self.codetree.selection_set(res[self._goto_index])
            self._goto_index += 1
コード例 #6
0
ファイル: calculator.py プロジェクト: Tovstogray/projects
class Main(Frame):
    def __init__(self):
        super().__init__(root)
        self.init_main()

    def init_main(self):
        Style().configure("TButton", padding=(0, 5, 0, 5), font='serif 10')

        self.columnconfigure(0, pad=3)
        self.columnconfigure(1, pad=3)
        self.columnconfigure(2, pad=3)
        self.columnconfigure(3, pad=3)

        self.rowconfigure(0, pad=3)
        self.rowconfigure(1, pad=3)
        self.rowconfigure(2, pad=3)
        self.rowconfigure(3, pad=3)
        self.rowconfigure(4, pad=3)

        self.equation = StringVar()
        self.var = IntVar()
        self.var.set(1)
        self.equation.set('enter the expression')

        self.entry = Entry(self, justify="right", textvariable=self.equation)
        self.entry.grid(row=0, columnspan=4, sticky=W + E)
        rad_base = Radiobutton(self,
                               text="Simple",
                               variable=self.var,
                               value=1,
                               command=self.selected)
        rad_base.grid(row=1, columnspan=2)
        rad_ex = Radiobutton(self,
                             text="Extended",
                             variable=self.var,
                             value=2,
                             command=self.selected)
        rad_ex.grid(row=1, column=2, columnspan=2)

        cls = Button(self, text="Cls", command=self.cls)
        cls.grid(row=2, column=0)
        bck = Button(self, text="Back", command=self.back)
        bck.grid(row=2, column=1)
        lbl = Button(self, command=lambda: self.equation.set(":)"))
        lbl.grid(row=2, column=2)
        clo = Button(self, text="Close", command=quit)
        clo.grid(row=2, column=3)

        sev = Button(self, text="7", command=lambda: self.press(7))
        sev.grid(row=3, column=0)
        eig = Button(self, text="8", command=lambda: self.press(8))
        eig.grid(row=3, column=1)
        nin = Button(self, text="9", command=lambda: self.press(9))
        nin.grid(row=3, column=2)
        div = Button(self, text="/", command=lambda: self.press("/"))
        div.grid(row=3, column=3)

        fou = Button(self, text="4", command=lambda: self.press(4))
        fou.grid(row=4, column=0)
        fiv = Button(self, text="5", command=lambda: self.press(5))
        fiv.grid(row=4, column=1)
        six = Button(self, text="6", command=lambda: self.press(6))
        six.grid(row=4, column=2)
        mul = Button(self, text="*", command=lambda: self.press("*"))
        mul.grid(row=4, column=3)

        one = Button(self, text="1", command=lambda: self.press(1))
        one.grid(row=5, column=0)
        two = Button(self, text="2", command=lambda: self.press(2))
        two.grid(row=5, column=1)
        thr = Button(self, text="3", command=lambda: self.press(3))
        thr.grid(row=5, column=2)
        mns = Button(self, text="-", command=lambda: self.press("-"))
        mns.grid(row=5, column=3)

        zer = Button(self, text="0", command=lambda: self.press(0))
        zer.grid(row=6, column=0)
        dot = Button(self, text=".", command=lambda: self.press("."))
        dot.grid(row=6, column=1)
        equ = Button(self, text="=", command=self.equal)
        equ.grid(row=6, column=2)
        pls = Button(self, text="+", command=lambda: self.press("+"))
        pls.grid(row=6, column=3)

        self.btn_1 = Button(self, text="sin", command=lambda: self.sin())
        self.btn_1.grid_remove()
        self.btn_2 = Button(self, text="cos", command=lambda: self.cos())
        self.btn_2.grid_remove()
        self.btn_3 = Button(self, text="tan", command=lambda: self.tan())
        self.btn_3.grid_remove()
        self.btn_4 = Button(self, text="log", command=lambda: self.log())
        self.btn_4.grid_remove()
        self.btn_5 = Button(self, text="ln", command=lambda: self.ln())
        self.btn_5.grid_remove()

        self.pack()

    def press(self, num):
        global expression
        expression += str(num)
        self.equation.set(expression)

    def equal(self):
        try:
            global expression
            total = str(eval(expression))
            self.equation.set(total)

            expression = ""

        except:
            self.equation.set('error')
            expression = ""

    def cls(self):
        global expression
        expression = ""
        self.equation.set("")

    def back(self):
        global expression
        expression = expression[:-1]
        self.equation.set(expression)

    def selected(event):
        global val_get
        val_get = int(event.var.get())
        if val_get == 1:
            event.btn_1.grid_remove()
            event.btn_2.grid_remove()
            event.btn_3.grid_remove()
            event.btn_4.grid_remove()
            event.btn_5.grid_remove()
        elif val_get == 2:
            event.btn_1.grid(row=2, column=4)
            event.btn_2.grid(row=3, column=4)
            event.btn_3.grid(row=4, column=4)
            event.btn_4.grid(row=5, column=4)
            event.btn_5.grid(row=6, column=4)
            event.entry.grid(row=0, columnspan=5, sticky=W + E)

    def sin(self):
        global expression
        expression = math.sin(float(expression))
        self.equation.set(float(expression))

    def cos(self):
        global expression
        expression = math.cos(float(expression))
        self.equation.set(float(expression))

    def tan(self):
        global expression
        expression = math.tan(float(expression))
        self.equation.set(float(expression))

    def log(self):
        global expression
        expression = math.log(float(expression))
        self.equation.set(float(expression))

    def ln(self):
        global expression
        expression = math.log1p(float(expression))
        self.equation.set(float(expression))
コード例 #7
0
class EuchreApp(Tk):
    def __init__(self, title, controller, user_player):
        self.user_player = user_player
        Tk.__init__(self)
        self.title(title)
        self.centerWindow()

        self.w = Frame(self)
        self.w.pack(fill=BOTH, expand=1)
        for x in range(15):
            self.w.columnconfigure(x, weight=1)
        self.w.rowconfigure(3, weight=1)
        self.w.rowconfigure(6, weight=1)
        self.w.rowconfigure(7, weight=1)
        self.w.rowconfigure(8, weight=1)
        self.w.rowconfigure(11, weight=1)

        self.lblTitle = Label(self.w, text="Euchre")
        self.lblTitle.grid(row=0, column=5, columnspan=5)

        # Center Table
        self.btnDeck = Button(self.w, text="Deck", state="disabled")
        self.btnDeck.grid(row=4, column=5, rowspan=5, columnspan=2, sticky=N+S+E+W)
        self.lblTrump = Label(self.w, text="Trump: ")
        self.lblTrump.grid(row=4, column=7, columnspan=3)
        self.lblCurrentPlayer = Label(self.w, text="Current Player: ")
        self.lblCurrentPlayer.grid(row=5, column=7, columnspan=3)
        self.btnP1CardPlayed = Button(self.w, state="disabled")
        self.btnP1CardPlayed.grid(row=8, column=8, sticky=N+S+E+W)
        self.btnP2CardPlayed = Button(self.w, state="disabled")
        self.btnP2CardPlayed.grid(row=7, column=7, sticky=N+S+E+W)
        self.btnP3CardPlayed = Button(self.w, state="disabled")
        self.btnP3CardPlayed.grid(row=6, column=8, sticky=N+S+E+W)
        self.btnP4CardPlayed = Button(self.w, state="disabled")
        self.btnP4CardPlayed.grid(row=7, column=9, sticky=N+S+E+W)
        self.btnNewHand = Button(self.w, text="New Hand", command=lambda: controller.restart_trick())
        self.btnNewHand.grid(row=7, column=8, sticky=N+S+E+W)
        self.btnDeal = Button(self.w, text="Deal", command=lambda:controller.deal())
        self.btnDeal.grid(row=4, column=7, rowspan=5, columnspan=3, sticky=N+S+E+W)

        def player_choose_card_callback_factory(player, card):
            return lambda: controller.player_choose_card(player, card)

        # Player 1 hand
        self.lblPlayer1Title = Label(self.w, text=("You" if user_player else "Player 1"))
        self.lblPlayer1Title.grid(row=9, column=5, columnspan=5)
        self.lblPlayer1Points = Label(self.w, text=("Points: 0"))
        self.lblPlayer1Points.grid(row=10, column=5, columnspan=5)
        self.btnPlayer1Cards = []
        for i in range(5):
            self.btnPlayer1Cards.append(Button(self.w, command=player_choose_card_callback_factory(0, i), state="disabled"))
            self.btnPlayer1Cards[i].grid(row=11, column=5+i, sticky=N+S+E+W)

        # Player 2 hand
        self.lblPlayer2Title = Label(self.w, text="Player 2")
        self.lblPlayer2Title.grid(row=4, column=0, columnspan=5)
        self.lblPlayer2Points = Label(self.w, text="Points: 0")
        self.lblPlayer2Points.grid(row=5, column=0, columnspan=5)
        self.btnPlayer2Cards = []
        for i in range(5):
            self.btnPlayer2Cards.append(Button(self.w, command=player_choose_card_callback_factory(1, i), state="disabled"))
            self.btnPlayer2Cards[i].grid(row=6, column=0+i, rowspan=3, sticky=N+S+E+W)

        # Player 3 hand
        self.lblPlayer3Title = Label(self.w, text="Player 3")
        self.lblPlayer3Title.grid(row=1, column=5, columnspan=5)
        self.lblPlayer3Points = Label(self.w, text="Points: 0")
        self.lblPlayer3Points.grid(row=2, column=5, columnspan=5)
        self.btnPlayer3Cards = []
        for i in range(5):
            self.btnPlayer3Cards.append(Button(self.w, command=player_choose_card_callback_factory(2, i), state="disabled"))
            self.btnPlayer3Cards[i].grid(row=3, column=5+i, sticky=N+S+E+W)

        # Player 4 hand
        self.lblPlayer4Title = Label(self.w, text="Player 4")
        self.lblPlayer4Title.grid(row=4, column=10, columnspan=5)
        self.lblPlayer4Points = Label(self.w, text="Points: 0")
        self.lblPlayer4Points.grid(row=5, column=10, columnspan=5)
        self.btnPlayer4Cards = []
        for i in range(5):
            self.btnPlayer4Cards.append(Button(self.w, command=player_choose_card_callback_factory(3, i), state="disabled"))
            self.btnPlayer4Cards[i].grid(row=6, column=10+i, rowspan=3, sticky=N+S+E+W)

    def centerWindow(self):
        w = 1000
        h = 600

        sw = self.winfo_screenwidth()
        sh = self.winfo_screenheight()

        x = (sw - w)/2
        y = (sh - h)/2
        self.geometry('%dx%d+%d+%d' % (w, h, x, y))

    def restart_trick(self, dealer):
        self.btnNewHand.grid_remove()
        self.btnDeal.grid()
        self.lblPlayer1Title.config(text=("You" if self.user_player else "Player 1") + (": dealer" if dealer % 4 == 0 else ""))
        self.lblPlayer2Title.config(text="Player 2" + (": dealer" if dealer % 4 == 1 else ""))
        self.lblPlayer3Title.config(text="Player 3" + (": dealer" if dealer % 4 == 2 else ""))
        self.lblPlayer4Title.config(text="Player 4" + (": dealer" if dealer % 4 == 3 else ""))
        self.lblPlayer1Points.config(text="Points: 0")
        self.lblPlayer2Points.config(text="Points: 0")
        self.lblPlayer3Points.config(text="Points: 0")
        self.lblPlayer4Points.config(text="Points: 0")
        for c in self.btnPlayer1Cards:
            c.config(text="")
        for c in self.btnPlayer2Cards:
            c.config(text="")
        for c in self.btnPlayer3Cards:
            c.config(text="")
        for c in self.btnPlayer4Cards:
            c.config(text="")

    def deal(self, trump):
        self.btnDeal.grid_remove()
        self.lblTrump.config(text="Trump: " + str(trump))
        self.new_round()

    def new_round(self):
        self.btnP1CardPlayed.config(text="")
        self.btnP1CardPlayed.grid_remove()
        self.btnP2CardPlayed.config(text="")
        self.btnP2CardPlayed.grid_remove()
        self.btnP3CardPlayed.config(text="")
        self.btnP3CardPlayed.grid_remove()
        self.btnP4CardPlayed.config(text="")
        self.btnP4CardPlayed.grid_remove()

    def update_player_hand(self, player, player_num):
        if player_num == 0:
            for c in self.btnPlayer1Cards:
                c.config(text="")
                c.grid_remove()
            for i, c in enumerate(player.hand.cards):
                self.btnPlayer1Cards[i].grid()
                self.btnPlayer1Cards[i].config(text=str(c.rank) + str(c.suit))
        elif player_num == 1:
            for c in self.btnPlayer2Cards:
                c.config(text="")
                c.grid_remove()
            for i, c in enumerate(player.hand.cards):
                self.btnPlayer2Cards[i].grid()
                if self.user_player:
                    self.btnPlayer2Cards[i].config(text="???")
                else:
                    self.btnPlayer2Cards[i].config(text=str(c.rank) + str(c.suit))
        elif player_num == 2:
            for c in self.btnPlayer3Cards:
                c.config(text="")
                c.grid_remove()
            for i, c in enumerate(player.hand.cards):
                self.btnPlayer3Cards[i].grid()
                if self.user_player:
                    self.btnPlayer3Cards[i].config(text="???")
                else:
                    self.btnPlayer3Cards[i].config(text=str(c.rank) + str(c.suit))
        elif player_num == 3:
            for c in self.btnPlayer4Cards:
                c.config(text="")
                c.grid_remove()
            for i, c in enumerate(player.hand.cards):
                self.btnPlayer4Cards[i].grid()
                if self.user_player:
                    self.btnPlayer4Cards[i].config(text="???")
                else:
                    self.btnPlayer4Cards[i].config(text=str(c.rank) + str(c.suit))
        self.update_player_points(player, player_num)

    def update_player_points(self, player, player_num):
        if player_num == 0:
            self.lblPlayer1Points.config(text="Points: " + str(player.points))
        elif player_num == 1:
            self.lblPlayer2Points.config(text="Points: " + str(player.points))
        elif player_num == 2:
            self.lblPlayer3Points.config(text="Points: " + str(player.points))
        elif player_num == 3:
            self.lblPlayer4Points.config(text="Points: " + str(player.points))

    def activate_player_turn(self, player, player_num):
        if player_num == 0:
            for i, c in enumerate(player.hand.cards):
                if player.valid_cards[i]:
                    self.btnPlayer1Cards[i].config(state="enabled")
        elif player_num == 1:
            for i, c in enumerate(player.hand.cards):
                if player.valid_cards[i]:
                    self.btnPlayer2Cards[i].config(state="enabled")
        elif player_num == 2:
            for i, c in enumerate(player.hand.cards):
                if player.valid_cards[i]:
                    self.btnPlayer3Cards[i].config(state="enabled")
        elif player_num == 3:
            for i, c in enumerate(player.hand.cards):
                if player.valid_cards[i]:
                    self.btnPlayer4Cards[i].config(state="enabled")

    def deactivate_player_turn(self, player, player_num):
        if player_num == 0:
            for i, c in enumerate(player.hand.cards):
                self.btnPlayer1Cards[i].config(state="disabled")
        elif player_num == 1:
            for i, c in enumerate(player.hand.cards):
                self.btnPlayer2Cards[i].config(state="disabled")
        elif player_num == 2:
            for i, c in enumerate(player.hand.cards):
                self.btnPlayer3Cards[i].config(state="disabled")
        elif player_num == 3:
            for i, c in enumerate(player.hand.cards):
                self.btnPlayer4Cards[i].config(state="disabled")

    def update_current_player(self, player_num):
        self.lblCurrentPlayer.config(text="Current Player: " + str(player_num))

    def player_play_card(self, player, player_num, card):
        self.update_player_hand(player, player_num)
        if player_num == 0:
            self.btnP1CardPlayed.grid()
            self.btnP1CardPlayed.config(text=str(card.rank)+str(card.suit))
        elif player_num == 1:
            self.btnP2CardPlayed.grid()
            self.btnP2CardPlayed.config(text=str(card.rank)+str(card.suit))
        elif player_num == 2:
            self.btnP3CardPlayed.grid()
            self.btnP3CardPlayed.config(text=str(card.rank)+str(card.suit))
        elif player_num == 3:
            self.btnP4CardPlayed.grid()
            self.btnP4CardPlayed.config(text=str(card.rank)+str(card.suit))

    def game_over(self):
        self.btnNewHand.grid()
コード例 #8
0
class Control(Module):
    '''
    This class provides a clean interface for managing Undo/Redo functionality.
    Implementation relies on storing two lists of actions as stacks, one for Undo
    and one for Redo.  Calling Undo/Redo should pop the corresponding stack and
    execute the inverse of that action, pushing the inverse action to the other
    stack (so its inversion can also be executed).

    Note: both stacks get cleared on
        - change files
        - change frames
        - Dicom.resetZoom()
    '''
    def __init__(self, app):
        info( ' - initializing module: Control' )
        # reference to our main object containing other functionality managers
        self.app = app
        # initialize our stacks
        self.reset()

        # some images for the buttons
        # Source for icons: https://material.io/tools/icons/?style=outline
        # License: Apache Version 2.0 www.apache.org/licenses/LICENSE-2.0.txt
        data_copy = '''R0lGODlhGAAYAPAAAAAAAAAAACH5BAEAAAEALAAAAAAYABgAAAJHjI+pCe3/1oHUSdOunmDvHFTWBYrjUnbMuWIqAqEqCMdt+HI25yrVTZMEcT3NMPXJEZckJdKorCWbU2H0JqvKTBErl+XZFAAAOw'''
        data_paste = '''R0lGODlhGAAYAPAAAAAAAAAAACH5BAEAAAEALAAAAAAYABgAAAJBjI+pq+DAonlPToqza7rv9FlBeJCSOUJpd3EXm7piDKoi+nkqvnttPaMhUAzeiwJMapJDm8U44+kynCkmiM1qZwUAOw'''

        self.img_copy = PhotoImage(data=data_copy)
        self.img_paste = PhotoImage(data=data_paste)

        # bind Ctrl+z to UNDO and Ctrl+Shift+Z to REDO
        if util.get_platform() == 'Linux':
            self.app.bind('<Control-z>', self.undo )
            self.app.bind('<Control-Z>', self.redo )
        else:
            self.app.bind('<Command-z>', self.undo )
            self.app.bind('<Command-Z>', self.redo )
        # also make some buttons and bind them
        self.frame = Frame(self.app.LEFT)#, pady=7)
        self.frame.grid( row=5 )
        self.header = Header(self.frame, text="Points")
        self.selectAllBtn = Button(self.frame, text='⬚', command=self.selectAll, takefocus=0, style="symbol.TButton", width=1.5)
        self.copyBtn = Button(self.frame, image=self.img_copy, command=self.copy, takefocus=0)  # FIXME: add tooltip for "Copy"
        self.pasteBtn = Button(self.frame, image=self.img_paste, command=self.paste, takefocus=0) # FIXME: add tooltip for "Paste"
        self.undoBtn = Button(self.frame, text='↶', command=self.undo, takefocus=0, width=1.5, style="symbol.TButton")
        self.redoBtn = Button(self.frame, text='↷', command=self.redo, takefocus=0, width=1.5, style="symbol.TButton")
        self.updateButtons()
    def push(self, item):
        '''
        add an item to the undo-stack
        and empty out the redo-stack
        '''
        self.uStack.append( item )
        self.rStack = []
        self.updateButtons()
    def reset(self):
        ''' reset our stacks '''
        self.uStack = [] # undo
        self.rStack = [] # redo
    def update(self):
        ''' changing files and changing frames should have the same effect '''
        self.reset()
    def selectAll(self):
        self.app.Trace.selectAll()
    def copy(self):
        self.app.Trace.copy()
    def paste(self):
        self.app.Trace.paste()
    def undo(self, event=None):
        ''' perform the undo-ing '''

        if len(self.uStack):
            item = self.uStack.pop()

            if item['type'] == 'add':
                chs = item['chs']
                for ch in chs:
                    self.app.Trace.remove( ch )
                self.rStack.append({ 'type':'delete', 'chs':chs })
            elif item['type'] == 'delete':
                chs = item['chs']
                for ch in chs:
                    ch.draw()
                self.rStack.append({ 'type':'add', 'chs':chs })
            elif item['type'] == 'move':
                chs = item['chs']
                coords = item['coords']
                for i in range(len(chs)):
                    chs[i].dragTo( coords[i] )
                self.rStack.append({ 'type':'move', 'chs':chs, 'coords':coords })
            elif item['type'] == 'recolor':
                oldColor = self.app.Trace.recolor( item['trace'], item['color'] )
                self.rStack.append({ 'type':'recolor', 'trace':item['trace'], 'color':oldColor })
            elif item['type'] == 'rename':
                self.app.Trace.renameTrace( newName=item['old'], oldName=item['new'] ) # this is backwards on purpose
                self.rStack.append({ 'type':'rename', 'old':item['old'], 'new':item['new'] })
            else:
                error(item)
                raise NotImplementedError

            self.app.Trace.unselectAll()
            self.app.Trace.write()
            self.updateButtons()
        else:
            warn( 'Nothing to undo!' )
    def redo(self, event=None):
        ''' perform the redo-ing '''

        if len(self.rStack):
            item = self.rStack.pop()

            if item['type'] == 'add':
                chs = item['chs']
                for ch in chs:
                    self.app.Trace.remove( ch )
                self.uStack.append({ 'type':'delete', 'chs':chs })
            elif item['type'] == 'delete':
                chs = item['chs']
                for ch in chs:
                    ch.draw()
                self.uStack.append({ 'type':'add', 'chs':chs })
            elif item['type'] == 'move':
                chs = item['chs']
                coords = item['coords']
                for i in range(len(chs)):
                    chs[i].dragTo( coords[i] )
                self.uStack.append({ 'type':'move', 'chs':chs, 'coords':coords })
            elif item['type'] == 'recolor':
                oldColor = self.app.Trace.recolor( item['trace'], item['color'] )
                self.uStack.append({ 'type':'recolor', 'trace':item['trace'], 'color':oldColor })
            elif item['type'] == 'rename':
                self.app.Trace.renameTrace( newName=item['new'], oldName=item['old'] )
                self.uStack.append({ 'type':'rename', 'old':item['old'], 'new':item['new'] })
            else:
                error(item)
                raise NotImplementedError

            self.app.Trace.unselectAll()
            self.app.Trace.write()
            self.updateButtons()
        else:
            warn( 'Nothing to redo!' )
    def updateButtons(self):
        '''
        Don't allow clicking buttons that wrap empty stacks.  However, users will
        still be able to access that functionality thru key bindings.
        '''
        self.undoBtn['state'] = 'normal' if len(self.uStack) else 'disabled'
        self.redoBtn['state'] = 'normal' if len(self.rStack) else 'disabled'
        self.grid()
    def grid(self):
        '''
        Grid button widgets
        '''
        self.header.grid(row=0,column=0, columnspan=5)
        self.selectAllBtn.grid(row=1, column=0)
        self.copyBtn.grid(row=1, column=1, ipady=3)
        self.pasteBtn.grid(row=1, column=2, ipady=3)

        self.undoBtn.grid(row=1, column=3)
        self.redoBtn.grid(row=1, column=4)
    def grid_remove(self):
        '''
        Remove button widgets from grid
        '''
        self.undoBtn.grid_remove()
        self.redoBtn.grid_remove()
コード例 #9
0
class Dicom(Module):
    def __init__(self, app):
        info(' - initializing module: Dicom')

        self.app = app

        if LIBS_INSTALLED:
            # grid load button
            self.frame_holder = Frame(self.app.LEFT)  #, pady=7)
            self.frame_holder.grid(row=2)
            self.frame = Frame(self.frame_holder)
            self.frame.pack(expand=True)

            self.method = StringVar(self.app)
            self.mode = None
            self.reader = None

            # zoom buttons
            self.zbframe = Frame(self.app.LEFT)
            self.zbframe.grid(row=6, column=0)

            # zoom frame (contains our tracing canvas)
            self.zframe = ZoomFrame(self.app.RIGHT, 1.3, app)

            # zoom in, zoom out, reset zoom buttons
            #self.header = Header(self.zbframe, text="Zoom")
            self.zoomResetBtn = Button(self.zbframe,
                                       text='⊜',
                                       command=self.zoomReset,
                                       width=1.5,
                                       style="symbol.TButton",
                                       takefocus=0)  #, pady=7 )
            self.zoomInBtn = Button(self.zbframe,
                                    text='⊕',
                                    command=self.zoomIn,
                                    width=1.5,
                                    style="symbol.TButton",
                                    takefocus=0)
            self.zoomOutBtn = Button(self.zbframe,
                                     text='⊝',
                                     command=self.zoomOut,
                                     width=1.5,
                                     style="symbol.TButton",
                                     takefocus=0)

            # reset zoom keyboard shortcut
            if util.get_platform() == 'Linux':
                self.app.bind('<Control-0>', self.zoomReset)
            else:
                self.app.bind('<Command-0>', self.zoomReset)
            self.reset()
            self.grid()

    def zoomReset(self, fromButton=False):
        '''
        reset zoom frame canvas and rebind it
        '''
        if self.isLoaded():
            # creates a new canvas object and we redraw everything to it
            self.zframe.resetCanvas()
            # self.zframe.canvas.bind('<Button-1>', self.app.onClickZoom )
            # self.zframe.canvas.bind('<ButtonRelease-1>', self.app.onRelease )
            # self.zframe.canvas.bind('<Motion>', self.app.onMotion )

            # we want to go here only after a button press
            if fromButton: self.app.framesUpdate()

    def zoomIn(self):
        self.zframe.zoomIn()

    def zoomOut(self):
        self.zframe.zoomOut()

    def update(self, _frame=None):
        '''
        change the image on the zoom frame
        '''
        if self.reader and self.reader.loaded:
            self.zframe.setImage(self.reader.getFrame(_frame
                                                      or self.app.frame))

    def load(self, event=None):
        '''
        brings a dicom file into memory if it exists
        '''
        if LIBS_INSTALLED:
            if self.reader and not self.reader.loaded:
                self.reader.load()
                self.app.frame = 1
                self.update()
            self.loadBtn['state'] = 'disabled'

    def chooseMethod(self, event=None):
        if self.mode:
            cls = LABEL_TO_READER[self.mode][self.method.get()]
            if self.mode == 'dicom':
                dcm = self.app.Data.checkFileLevel('.dicom')
                if dcm:
                    if cls == DicomPNGReader and self.app.Data.getFileLevel(
                            'processed'):
                        self.reader = cls(dcm, self.app.Data.path)
                    else:
                        self.reader = cls(dcm)
                else:
                    self.reader = None
            elif self.mode == 'ult':
                ult = self.app.Data.checkFileLevel('.ult')
                meta = self.app.Data.checkFileLevel('US.txt')
                if ult and meta:
                    self.reader = cls(ult, meta)
                else:
                    self.reader = None
            self.zframe.resetImageDimensions()
            if not self.reader:
                self.loadBtn['state'] = 'disabled'
            elif self.reader.loaded:
                self.loadBtn['state'] = 'disabled'
                self.update()
            else:
                self.loadBtn['state'] = 'normal'

    def isLoaded(self):
        return self.reader and self.reader.loaded

    def getFrames(self, framenums):
        return [self.reader.getFrame(int(x)) for x in framenums]

    def getFrameTimes(self):
        if self.reader:
            return self.reader.getFrameTimes()
        elif self.mode == 'dicom':
            rd = DicomReader(
                self.app.Data.unrelativize(
                    self.app.Data.getFileLevel('.dicom')))
            return rd.getFrameTimes()
        elif self.mode == 'ult':
            rd = ULTScanLineReader(
                self.app.Data.unrelativize(self.app.Data.getFileLevel('.ult')),
                self.app.Data.unrelativize(
                    self.app.Data.getFileLevel('US.txt')))
            return rd.getFrameTimes()
        else:
            return [0]

    def reset(self):
        '''
        new files should default to not showing dicom unless it has already been processed
        '''
        # hide frame navigation widgets
        # self.grid_remove()

        self.zframe.shown = False
        self.zframe.setImage(None)
        self.frame.destroy()
        self.frame = Frame(self.frame_holder)
        self.frame.pack(expand=True)
        self.reader = None

        if self.app.Data.getFileLevel('.dicom'):
            self.mode = 'dicom'
        elif self.app.Data.getFileLevel('.ult'):
            self.mode = 'ult'
        else:
            self.mode = None

        self.method.set('')
        options = [x.label for x in READERS[self.mode]] or ['[no ultrasound]']
        self.methodMenu = OptionMenu(self.frame,
                                     self.method,
                                     '---',
                                     *options,
                                     command=self.chooseMethod)
        self.methodMenu.grid(row=0)
        self.loadBtn = Button(self.frame,
                              text='Load frames',
                              command=self.load,
                              takefocus=0,
                              state='disabled')
        self.loadBtn.grid(row=1)
        if len(READERS[self.mode]) == 1:
            self.method.set(options[0])
            self.chooseMethod()

    def grid(self):
        '''
        Grid frame navigation, zoom reset, and Control (Undo/Redo) widgets
        '''
        self.app.framesHeader.grid(row=0)
        self.app.framesPrevBtn.grid(row=0, column=0)
        self.app.framesEntryText.grid(row=0, column=1)
        self.app.framesEntryBtn.grid(row=0, column=2)
        self.app.framesNextBtn.grid(row=0, column=3)

        #self.header.grid(row=0, column=0, columnspan=5)
        self.zoomInBtn.grid(row=0, column=3)
        self.zoomResetBtn.grid(row=0, column=2)
        self.zoomOutBtn.grid(row=0, column=1)
        self.app.Control.grid()

    def grid_remove(self):
        '''
        Remove widgets from grid
        '''
        self.app.framesHeader.grid_remove()
        self.app.framesPrevBtn.grid_remove()
        self.app.framesEntryText.grid_remove()
        self.app.framesEntryBtn.grid_remove()
        self.app.framesNextBtn.grid_remove()
        self.zoomInBtn.grid_remove()
        self.zoomResetBtn.grid_remove()
        self.zoomOutBtn.grid_remove()
        self.app.Control.grid_remove()