Пример #1
0
class DlgDelay(Dialog):
    def body(self, master, cfg={}):
        "place user dialog widgets"
        self.config = cfg
        self.config["OK button"] = False
        self.delay = StringVar()
        self.delay.set(cfg.get("delay", ""))
        self.edelay = Entry(master, width=15, textvariable=self.delay)
        self.edelay.grid(column=1, row=0, sticky="e")
        Label(master, text=_("Delay:")).grid(column=0, row=0, sticky="w")
        self.resizable(width=0, height=0)
        return self.edelay

    def validate(self):
        try:
            flt = float(self.delay.get())
        except ValueError:
            return self.edelay
        if flt < 0 or flt > 5:
            return self.edelay
        return None

    def apply(self):
        "On ok button pressed"
        self.config["delay"] = self.delay.get()
        self.config["OK button"] = True
    def add_file_info_box(self, mainframe, name, labeldict, btncallback, fvar):
        """
        Create and add a infobox containing the info about a loaded
        savegame.
        """
        title = {'source':'Copy face from source file:',
                 'target':'To target file:'}
        frame = LabelFrame(mainframe, text=title[name])
        frame.pack(anchor=N, fill=X, expand=1, side=TOP, padx=0, pady=0)
        frame.columnconfigure(1, weight=1)

        btn = Button(frame, text='Browse', command=btncallback)
        btn.grid(column=0, row=0, padx=2, pady=2)

        field = Entry(frame, width=50, textvariable=fvar)
        field.grid(column=1, row=0, columnspan=2, padx=2, pady=2, sticky=W+E)

        l = ('name','gender','level','race','location','save number','playing time')
        for n, (i, j) in enumerate([(x.capitalize()+':', x) for x in l]):
            Label(frame, text=i, state=DISABLED).grid(column=0, row=n+1, padx=4,
                                                      pady=3, sticky=E)
            labeldict[j] = StringVar()
            Label(frame, textvariable=labeldict[j]).grid(column=1, row=n+1,
                                                     padx=4, pady=3, sticky=W)
        self.screenshot[name] = Label(frame)
        self.screenshot[name].grid(column=2, row=1, rowspan=len(l),
                                   padx=4, pady=4)
Пример #3
0
 def __init__(self, parent, url=None, buttonSEC=False, buttonRSS=False):
     super(DialogURL, self).__init__(parent)
     self.parent = parent
     parentGeometry = re.match("(\d+)x(\d+)[+]?([-]?\d+)[+]?([-]?\d+)", parent.geometry())
     dialogX = int(parentGeometry.group(3))
     dialogY = int(parentGeometry.group(4))
     self.accepted = False
     self.url = None
     self.transient(self.parent)
     self.title("Enter URL")
     self.urlVar = StringVar()
     self.urlVar.set(url if url is not None else "http://")
     
     frame = Frame(self)
     urlLabel = Label(frame, text=_("URL:"), underline=0)
     urlEntry = Entry(frame, textvariable=self.urlVar, width=60)
     urlEntry.focus_set()
     okButton = Button(frame, text=_("OK"), command=self.ok)
     cancelButton = Button(frame, text=_("Cancel"), command=self.close)
     if buttonSEC:
         usSecButton = Button(frame, text=_("SEC search"), command=self.usSec)
         usSecButton.grid(row=1, column=1, sticky=W, pady=3)
         ToolTip(usSecButton, text=_("Opens US SEC Edgar Company Search (in web browser)\n\n"
                                  "(1) Find the company in web browser,\n"
                                  "(2) Click 'documents' button for desired filing,\n"
                                  "(3) Find 'data files' panel, instance document row, 'document' column,\n"
                                  "(4) On instance document file name, right-click browser menu: 'copy shortcut',\n"
                                  "(5) Come back to this dialog window,\n"
                                  "(6) Ctrl-v (paste) shortcut into above URL text box,\n"
                                  "(7) Click ok button to load instance document"),
                                  wraplength=480)
     if buttonRSS:
         rssButton = Button(frame, text=_("SEC RSS"), command=self.rssFeed)
         rssButton.grid(row=1, column=1, pady=3)
         ToolTip(rssButton, text=_("Opens current US SEC Edgar RSS feed"),
                                  wraplength=480)
     urlLabel.grid(row=0, column=0, sticky=W, pady=3, padx=3)
     urlEntry.grid(row=0, column=1, columnspan=3, sticky=EW, pady=3, padx=3)
     okButton.grid(row=1, column=2, sticky=E, pady=3)
     ToolTip(okButton, text=_("Opens above URL from web cache, downloading to cache if necessary"), wraplength=240)
     cancelButton.grid(row=1, column=3, sticky=EW, pady=3, padx=3)
     ToolTip(cancelButton, text=_("Cancel operation"))
                 
     frame.grid(row=0, column=0, sticky=(N,S,E,W))
     frame.columnconfigure(1, weight=1)
     window = self.winfo_toplevel()
     window.columnconfigure(0, weight=1)
     self.geometry("+{0}+{1}".format(dialogX+50,dialogY+100))
     
     self.bind("<Alt-u>", lambda *ignore: urlEntry.focus_set())
     self.bind("<Return>", self.ok)
     self.bind("<Escape>", self.close)
     
     self.protocol("WM_DELETE_WINDOW", self.close)
     self.grab_set()
     self.wait_window(self)
Пример #4
0
    def make_entry(self, label_text, var):
        '''Return (entry, label), .

        entry - gridded labeled Entry for text entry.
        label - Label widget, returned for testing.
        '''
        label = Label(self.top, text=label_text)
        label.grid(row=self.row, column=0, sticky="nw")
        entry = Entry(self.top, textvariable=var, exportselection=0)
        entry.grid(row=self.row, column=1, sticky="nwe")
        self.row = self.row + 1
        return entry, label
Пример #5
0
class MyTestDialog( ModalDialog ):

    def body( self, master ):
        """
        Override the empty ModalDialog.body function
            to set up the dialog how we want it.
        """
        from tkinter.ttk import Label, Entry

        Label( master, text="First:" ).grid( row=0 )
        Label( master, text="Second:" ).grid( row=1 )

        self.e1 = Entry( master )
        self.e2 = Entry( master )

        self.e1.grid( row=0, column=1 )
        self.e2.grid( row=1, column=1 )
        return self.e1 # initial focus
    # end of MyTestDialog.apply


    def validate( self ):
        """
        Override the empty ModalDialog.validate function
            to check that the results are how we need them.
        """
        try: int( self.e1.get() ) and int( self.e2.get() )
        except ValueError:
            print( "ERROR: We need two valid integers!" )
            return False
        return True
    # end of MyTestDialog.validate


    def apply( self ):
        """
        Override the empty ModalDialog.apply function
            to process the results how we need them.
        """
        first = int( self.e1.get() )
        second = int( self.e2.get() )
        print( first, second ) # or something
        self.result = (first, second,)
Пример #6
0
    def createRow(self,rowNumber):
        isopach_L = Label(self.innerFrame, text=str(rowNumber+1), width=2)
        isopach_L.grid(column=0, row=rowNumber+2, padx=(0,5), pady=5)
        
        thicknessVar = tkinter.StringVar()
        thicknessM_E = Entry(self.innerFrame,width=self.entryWidth,textvariable=thicknessVar, justify="right")
        thicknessM_E.grid(column=1, row=rowNumber+2, pady=5)
        
        areaVar = tkinter.StringVar()
        sqrtAreaKM_E = Entry(self.innerFrame,width=self.entryWidth,textvariable=areaVar, justify="right")
        sqrtAreaKM_E.grid(column=2, row=rowNumber+2, pady=5)

        includeVar = tkinter.IntVar()
        includeCB = tkinter.Checkbutton(self.innerFrame,variable=includeVar, selectimage=self.tickImage)
        includeCB.grid(column=3,row=rowNumber+2,pady=5)
        includeCB.invoke()
        includeCB.bind("<Leave>",self.calculationTimeEstimationFunction)
        
        return (isopach_L,None),(thicknessM_E,thicknessVar),(sqrtAreaKM_E,areaVar),(includeCB,includeVar)
Пример #7
0
    def text_query(self, query_lable, original_text=None, accept_func=None):
        if self._query is not None:
            return
        frame = Frame(self.menubar)
        label = Label(frame, text=query_lable)
        label.grid(column=0, row=0, sticky=(N, S))
        self._accept_func = accept_func

        entry = Entry(frame)
        if original_text is not None:
            entry.insert(0, original_text)
        entry.original_value = original_text
        entry.grid(column=1, row=0, sticky=(N,S,W,E))
        kb.make_bindings(kb.text_query, 
                {'accept': self.accept_query,
                 'cancel': lambda e: self.close_query()}, entry.bind)

        frame.grid(column=self._menucolumn, row=0)
        self._menucolumn += 1
        entry.focus_set()
        self._query = frame
Пример #8
0
 def body(self, master, cfg={}):
     "place user dialog widgets"
     self.config = cfg
     self.config["OK button"] = False
     self.site = StringVar()
     self.site.set(cfg.get("site", ""))
     self.login = StringVar()
     self.login.set(cfg.get("user", ""))
     self.password = StringVar()
     self.password.set(str(cfg.get("password", "")))
     site = Entry(master, width=15, textvariable=self.site)
     site.grid(column=1, row=0, sticky="e")
     Label(master, text=_("Site:")).grid(column=0, row=0, sticky="w")
     loge = Entry(master, width=15, textvariable=self.login)
     loge.grid(column=1, row=1, sticky="e")
     Label(master, text=_("Username:"******"w")
     pase = Entry(master, width=15, textvariable=self.password, show="*")
     pase.grid(column=1, row=2, sticky="e")
     Label(master, text=_("Password:"******"w")
     self.to_remember = IntVar()
     self.to_remember.set(cfg.get("remember_passwd", 1))
     chk1 = Checkbutton(master, text="Remember",
                        variable=self.to_remember)
     chk1.grid(column=0, row=3, sticky="w", columnspan=2)
     self.resizable(width=0, height=0)
     return loge
Пример #9
0
class Tampil(Tk):
    def __init__(self):
        super().__init__()
        self.dekPrev = myDek()
        self.dekNext = myDek()
        self.dekHistory = myDek()
        self.current = ""

        #Windows
        self.title("Stack Using Deque")
        self.geometry("400x160")

        #Label
        self.lblTitle = Label(self,
                              text="Bejjo Parse Browser",
                              foreground="blue")
        self.lblTitle.grid(row=0, column=2, pady=5, padx=2)

        self.lblBody = Label(self, text="Welcome")
        self.lblBody.grid(row=2, column=0, columnspan=4, pady=5, padx=2)

        #Button
        self.btnPrev = Button(self,
                              text="<",
                              width=5,
                              state="disabled",
                              command=self.prev)
        self.btnPrev.grid(row=1, column=0, pady=5, padx=2)

        self.btnNext = Button(self,
                              text=">",
                              width=5,
                              state="disabled",
                              command=self.next)
        self.btnNext.grid(row=1, column=1, pady=5, padx=2)

        self.btnSearch = Button(self,
                                text="Search",
                                width=8,
                                command=self.search)
        self.btnSearch.grid(row=1, column=3, pady=5, padx=2)

        self.btnHistory = Button(self,
                                 text="History",
                                 width=12,
                                 command=self.history)
        self.btnHistory.grid(row=0, column=0, columnspan=2, pady=5, padx=2)

        self.btnParse = Button(self, text="Parse", width=8, command=self.parse)
        self.btnParse.grid(row=0, column=3, pady=5, padx=2)

        #Entry
        self.txtSearch = Entry(self, width=40)
        self.txtSearch.grid(row=1, column=2, pady=5, padx=2)

    def parse(self):
        if self.btnParse["text"] == "Parse":
            teks = "Welcome"
            if self.current != "":
                teks = ""
                url = Url(self.current)
                for x in url:
                    teks += x + "\n"
            self.lblBody["text"] = teks
            self.btnParse["text"] = "Close"
            self.btnHistory["text"] = "History"
        else:
            self.btnParse["text"] = "Parse"
            self.switch_attr()

    def history(self):
        if self.btnHistory["text"] == "History":
            self.lblBody["text"] = self.dekHistory
            self.btnHistory["text"] = "Close"
            self.btnParse["text"] = "Parse"
        else:
            self.btnHistory["text"] = "History"
            self.switch_attr()

    def data(self):
        teks = "Welcome"
        if self.current != "":
            url = Url(self.current)
            teks = url.title()
        return teks

    def switch_attr(self):
        if len(self.dekPrev) == 0:
            self.btnPrev["state"] = "disabled"
        else:
            self.btnPrev["state"] = "normal"

        if len(self.dekNext) == 0:
            self.btnNext["state"] = "disabled"
        else:
            self.btnNext["state"] = "normal"

        self.txtSearch.delete(0, "end")
        self.txtSearch.insert(0, self.current)

        teks = self.data()
        self.lblBody["text"] = teks

    def prev(self):
        self.dekNext + self.current
        self.current = self.dekPrev.back()
        self.btnHistory["text"] = "History"
        self.btnParse["text"] = "Parse"
        self.switch_attr()

    def next(self):
        self.dekPrev + self.current
        self.current = self.dekNext.back()
        self.btnHistory["text"] = "History"
        self.btnParse["text"] = "Parse"
        self.switch_attr()

    def search(self):
        url = self.txtSearch.get().strip()
        if self.current == url and url:
            self.btnHistory["text"] = "History"
            self.btnParse["text"] = "Parse"
            self.switch_attr()
        elif "http" == url[:4] and len(url.replace(
                "http", "", 1).strip()) > 5 and "." in url:
            self.dekPrev + self.current
            self.current = url
            self.dekNext = myDek()
            self.dekHistory.history(self.current)
            self.btnHistory["text"] = "History"
            self.btnParse["text"] = "Parse"
            self.switch_attr()
        else:
            messagebox.showinfo("Warning", "Incorrect URL")
Пример #10
0
    def initUI(self):

        self.master.title("Calculator")

        # padding (left, top, right, bottom)
        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)

        entry = Entry(self)
        entry.grid(row=0, columnspan=4, sticky=W + E)
        cls = Button(self, text="Cls")
        cls.grid(row=1, column=0)
        bck = Button(self, text="Back")
        bck.grid(row=1, column=1)
        lbl = Button(self)
        lbl.grid(row=1, column=2)
        clo = Button(self, text="Close")
        clo.grid(row=1, column=3)
        sev = Button(self, text="7")
        sev.grid(row=2, column=0)
        eig = Button(self, text="8")
        eig.grid(row=2, column=1)
        nin = Button(self, text="9")
        nin.grid(row=2, column=2)
        div = Button(self, text="/")
        div.grid(row=2, column=3)

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

        one = Button(self, text="1")
        one.grid(row=4, column=0)
        two = Button(self, text="2")
        two.grid(row=4, column=1)
        thr = Button(self, text="3")
        thr.grid(row=4, column=2)
        mns = Button(self, text="-")
        mns.grid(row=4, column=3)

        zer = Button(self, text="0")
        zer.grid(row=5, column=0)
        dot = Button(self, text=".")
        dot.grid(row=5, column=1)
        equ = Button(self, text="=")
        equ.grid(row=5, column=2)
        pls = Button(self, text="+")
        pls.grid(row=5, column=3)

        self.pack()
Пример #11
0
class Sync(Tk):
    def __init__(self):
        Tk.__init__(self)
        self.title("FolderSync")
        self.geometry("%ix%i" %
                      (self.winfo_screenwidth(), self.winfo_screenheight()))
        self.protocol("WM_DELETE_WINDOW", self.quitter)
        self.icon = PhotoImage(master=self, file=IM_ICON)
        self.iconphoto(True, self.icon)
        self.rowconfigure(2, weight=1)
        self.columnconfigure(0, weight=1)

        # --- icons
        self.img_about = PhotoImage(master=self, file=IM_ABOUT)
        self.img_open = PhotoImage(master=self, file=IM_OPEN)
        self.img_plus = PhotoImage(master=self, file=IM_PLUS)
        self.img_moins = PhotoImage(master=self, file=IM_MOINS)
        self.img_sync = PhotoImage(master=self, file=IM_SYNC)
        self.img_prev = PhotoImage(master=self, file=IM_PREV)
        self.img_expand = PhotoImage(master=self, file=IM_EXPAND)
        self.img_collapse = PhotoImage(master=self, file=IM_COLLAPSE)

        self.original = ""
        self.sauvegarde = ""
        # liste des fichiers/dossiers à supprimer avant de lancer la copie car
        # ils sont de nature différente sur l'original et la sauvegarde
        self.pb_chemins = []
        self.err_copie = False
        self.err_supp = False

        # --- init log files
        l = [
            f for f in listdir('/tmp') if re.match(r"foldersync[0-9]+.pid", f)
        ]
        nbs = []
        for f in l:
            with open(join('/tmp', f)) as fich:
                old_pid = fich.read().strip()
            if exists("/proc/%s" % old_pid):
                nbs.append(int(re.search(r"[0-9]+", f).group()))
            else:
                remove(f)
        if not nbs:
            i = 0
        else:
            nbs.sort()
            i = 0
            while i in nbs:
                i += 1
        self.pidfile = PID_FILE % i
        open(self.pidfile, 'w').write(str(getpid()))

        self.log_copie = LOG_COPIE % i
        self.log_supp = LOG_SUPP % i

        self.logger_copie = setup_logger("copie", self.log_copie)
        self.logger_supp = setup_logger("supp", self.log_supp)
        date = datetime.now().strftime('%d/%m/%Y %H:%M')
        self.logger_copie.info("\n###  %s  ###\n" % date)
        self.logger_supp.info("\n###  %s  ###\n" % date)

        # --- filenames and extensions that will not be copied
        exclude_list = split(r'(?<!\\) ',
                             CONFIG.get("Defaults", "exclude_copie"))
        self.exclude_names = []
        self.exclude_ext = []
        for elt in exclude_list:
            if elt:
                if elt[:2] == "*.":
                    self.exclude_ext.append(elt[1:])
                else:
                    self.exclude_names.append(elt.replace("\ ", " "))

        # --- paths that will not be deleted
        self.exclude_path_supp = [
            ch.replace("\ ", " ") for ch in split(
                r'(?<!\\) ', CONFIG.get("Defaults", "exclude_supp")) if ch
        ]
        #        while "" in self.exclude_path_supp:
        #            self.exclude_path_supp.remove("")

        self.q_copie = Queue()
        self.q_supp = Queue()
        # True si une copie / suppression est en cours
        self.is_running_copie = False
        self.is_running_supp = False

        self.style = Style(self)
        self.style.theme_use("clam")
        self.style.configure("TProgressbar",
                             troughcolor='lightgray',
                             background='#387EF5',
                             lightcolor="#5D95F5",
                             darkcolor="#2758AB")
        self.style.map("TProgressbar",
                       lightcolor=[("disabled", "white")],
                       darkcolor=[("disabled", "gray")])
        self.style.configure("folder.TButton", padding=1)
        # --- menu
        self.menu = Menu(self, tearoff=False)
        self.configure(menu=self.menu)

        # emplacements récents
        self.menu_recent = Menu(self.menu, tearoff=False)
        if RECENT:
            for ch_o, ch_s in RECENT:
                self.menu_recent.add_command(
                    label="%s -> %s" % (ch_o, ch_s),
                    command=lambda o=ch_o, s=ch_s: self.open(o, s))
        else:
            self.menu.entryconfigure(0, state="disabled")

        # emplacements favoris
        self.menu_fav = Menu(self.menu, tearoff=False)
        self.menu_fav_del = Menu(self.menu_fav, tearoff=False)
        self.menu_fav.add_command(label="Ajouter",
                                  image=self.img_plus,
                                  compound="left",
                                  command=self.add_fav)
        self.menu_fav.add_cascade(label="Supprimer",
                                  image=self.img_moins,
                                  compound="left",
                                  menu=self.menu_fav_del)
        for ch_o, ch_s in FAVORIS:
            label = "%s -> %s" % (ch_o, ch_s)
            self.menu_fav.add_command(
                label=label, command=lambda o=ch_o, s=ch_s: self.open(o, s))
            self.menu_fav_del.add_command(
                label=label, command=lambda nom=label: self.del_fav(nom))
        if not FAVORIS:
            self.menu_fav.entryconfigure(1, state="disabled")

        # accès aux fichiers log
        menu_log = Menu(self.menu, tearoff=False)
        menu_log.add_command(label="Copie", command=self.open_log_copie)
        menu_log.add_command(label="Suppression",
                             command=self.open_log_suppression)

        # paramètres, préférences
        menu_params = Menu(self.menu, tearoff=False)
        self.copy_links = BooleanVar(self,
                                     value=CONFIG.getboolean(
                                         "Defaults", "copy_links"))
        menu_params.add_checkbutton(label="Copier les liens",
                                    variable=self.copy_links,
                                    command=self.toggle_copy_links)
        menu_params.add_command(label="Exclusions copie",
                                command=self.exclusion_copie)
        menu_params.add_command(label="Exclusions supp",
                                command=self.exclusion_supp)

        self.menu.add_cascade(label="Récents", menu=self.menu_recent)
        self.menu.add_cascade(label="Favoris", menu=self.menu_fav)
        self.menu.add_cascade(label="Log", menu=menu_log)
        self.menu.add_cascade(label="Paramètres", menu=menu_params)
        self.menu.add_command(image=self.img_prev,
                              compound="center",
                              command=self.list_files_to_sync)
        self.menu.add_command(image=self.img_sync,
                              compound="center",
                              state="disabled",
                              command=self.synchronise)
        self.menu.add_command(image=self.img_about,
                              compound="center",
                              command=lambda: About(self))

        # sélection chemins
        frame_paths = Frame(self)
        frame_paths.grid(row=0, sticky="ew", pady=(10, 0))
        frame_paths.columnconfigure(0, weight=1)
        frame_paths.columnconfigure(1, weight=1)
        f1 = Frame(frame_paths, height=26)
        f2 = Frame(frame_paths, height=26)
        f1.grid(row=0, column=0, sticky="ew")
        f2.grid(row=0, column=1, sticky="ew")
        f1.grid_propagate(False)
        f2.grid_propagate(False)
        f1.columnconfigure(1, weight=1)
        f2.columnconfigure(1, weight=1)

        ## chemin vers original
        Label(f1, text="Original").grid(row=0, column=0, padx=(10, 4))
        self.entry_orig = Entry(f1)
        self.entry_orig.grid(row=0, column=1, sticky="ew", padx=(4, 2))
        self.b_open_orig = Button(f1,
                                  image=self.img_open,
                                  style="folder.TButton",
                                  command=self.open_orig)
        self.b_open_orig.grid(row=0, column=2, padx=(1, 8))
        ## chemin vers sauvegarde
        Label(f2, text="Sauvegarde").grid(row=0, column=0, padx=(8, 4))
        self.entry_sauve = Entry(f2)
        self.entry_sauve.grid(row=0, column=1, sticky="ew", padx=(4, 2))
        self.b_open_sauve = Button(f2,
                                   image=self.img_open,
                                   width=2,
                                   style="folder.TButton",
                                   command=self.open_sauve)
        self.b_open_sauve.grid(row=0, column=5, padx=(1, 10))

        #        self.b_prev = Button(frame_paths, image=self.img_prev,
        #                             command=self.list_files_to_sync)
        #        self.b_prev.grid(row=1, column=4, padx=4)
        #
        #        self.b_sync = Button(frame_paths, image=self.img_sync,
        #                             command=self.synchronise)
        #        self.b_sync.grid(row=1, column=5, padx=(4, 10))
        #        self.b_sync.state(("disabled", ))
        #        self.b_prev = Button(self, image=self.img_prev,
        #                             command=self.list_files_to_sync)
        #        self.b_prev.grid(row=1, sticky="ew", pady=(4, 10), padx=10)

        paned = PanedWindow(self, orient='horizontal')
        paned.grid(row=2, sticky="eswn")
        paned.rowconfigure(0, weight=1)
        paned.columnconfigure(1, weight=1)
        paned.columnconfigure(0, weight=1)

        # --- côté gauche
        frame_left = Frame(paned)
        paned.add(frame_left, weight=1)
        frame_left.rowconfigure(3, weight=1)
        frame_left.columnconfigure(0, weight=1)

        # fichiers à copier
        f_left = Frame(frame_left)
        f_left.columnconfigure(2, weight=1)
        f_left.grid(row=2,
                    columnspan=2,
                    pady=(4, 2),
                    padx=(10, 4),
                    sticky="ew")

        Label(f_left, text="À copier").grid(row=0, column=2)
        frame_copie = Frame(frame_left)
        frame_copie.rowconfigure(0, weight=1)
        frame_copie.columnconfigure(0, weight=1)
        frame_copie.grid(row=3,
                         column=0,
                         sticky="eswn",
                         columnspan=2,
                         pady=(2, 4),
                         padx=(10, 4))
        self.tree_copie = CheckboxTreeview(frame_copie,
                                           selectmode='none',
                                           show='tree')
        self.b_expand_copie = Button(f_left,
                                     image=self.img_expand,
                                     style="folder.TButton",
                                     command=self.tree_copie.expand_all)
        self.b_expand_copie.grid(row=0, column=0)
        self.b_expand_copie.state(("disabled", ))
        self.b_collapse_copie = Button(f_left,
                                       image=self.img_collapse,
                                       style="folder.TButton",
                                       command=self.tree_copie.collapse_all)
        self.b_collapse_copie.grid(row=0, column=1, padx=4)
        self.b_collapse_copie.state(("disabled", ))
        self.tree_copie.tag_configure("warning", foreground="red")
        self.tree_copie.tag_configure("link",
                                      font="tkDefaultFont 9 italic",
                                      foreground="blue")
        self.tree_copie.tag_bind("warning", "<Button-1>", self.show_warning)
        self.tree_copie.grid(row=0, column=0, sticky="eswn")
        self.scroll_y_copie = Scrollbar(frame_copie,
                                        orient="vertical",
                                        command=self.tree_copie.yview)
        self.scroll_y_copie.grid(row=0, column=1, sticky="ns")
        self.scroll_x_copie = Scrollbar(frame_copie,
                                        orient="horizontal",
                                        command=self.tree_copie.xview)
        self.scroll_x_copie.grid(row=1, column=0, sticky="ew")
        self.tree_copie.configure(yscrollcommand=self.scroll_y_copie.set,
                                  xscrollcommand=self.scroll_x_copie.set)
        self.pbar_copie = Progressbar(frame_left,
                                      orient="horizontal",
                                      mode="determinate")
        self.pbar_copie.grid(row=4,
                             columnspan=2,
                             sticky="ew",
                             padx=(10, 4),
                             pady=4)
        self.pbar_copie.state(("disabled", ))

        # --- côté droit
        frame_right = Frame(paned)
        paned.add(frame_right, weight=1)
        frame_right.rowconfigure(3, weight=1)
        frame_right.columnconfigure(0, weight=1)

        # fichiers à supprimer
        f_right = Frame(frame_right)
        f_right.columnconfigure(2, weight=1)
        f_right.grid(row=2,
                     columnspan=2,
                     pady=(4, 2),
                     padx=(4, 10),
                     sticky="ew")
        Label(f_right, text="À supprimer").grid(row=0, column=2)
        frame_supp = Frame(frame_right)
        frame_supp.rowconfigure(0, weight=1)
        frame_supp.columnconfigure(0, weight=1)
        frame_supp.grid(row=3,
                        columnspan=2,
                        sticky="eswn",
                        pady=(2, 4),
                        padx=(4, 10))
        self.tree_supp = CheckboxTreeview(frame_supp,
                                          selectmode='none',
                                          show='tree')
        self.b_expand_supp = Button(f_right,
                                    image=self.img_expand,
                                    style="folder.TButton",
                                    command=self.tree_supp.expand_all)
        self.b_expand_supp.grid(row=0, column=0)
        self.b_expand_supp.state(("disabled", ))
        self.b_collapse_supp = Button(f_right,
                                      image=self.img_collapse,
                                      style="folder.TButton",
                                      command=self.tree_supp.collapse_all)
        self.b_collapse_supp.grid(row=0, column=1, padx=4)
        self.b_collapse_supp.state(("disabled", ))
        self.tree_supp.grid(row=0, column=0, sticky="eswn")
        self.scroll_y_supp = Scrollbar(frame_supp,
                                       orient="vertical",
                                       command=self.tree_supp.yview)
        self.scroll_y_supp.grid(row=0, column=1, sticky="ns")
        self.scroll_x_supp = Scrollbar(frame_supp,
                                       orient="horizontal",
                                       command=self.tree_supp.xview)
        self.scroll_x_supp.grid(row=1, column=0, sticky="ew")
        self.tree_supp.configure(yscrollcommand=self.scroll_y_supp.set,
                                 xscrollcommand=self.scroll_x_supp.set)
        self.pbar_supp = Progressbar(frame_right,
                                     orient="horizontal",
                                     mode="determinate")
        self.pbar_supp.grid(row=4,
                            columnspan=2,
                            sticky="ew",
                            padx=(4, 10),
                            pady=4)
        self.pbar_supp.state(("disabled", ))

        #        # lancer synchronisation
        #        self.b_sync = Button(self, image=self.img_sync,
        #                             command=self.synchronise)
        #        self.b_sync.grid(row=3, sticky="ew", pady=(4, 10), padx=10)
        #        self.b_sync.state(("disabled", ))

        # bindings
        self.entry_orig.bind("<Key-Return>", self.list_files_to_sync)
        self.entry_sauve.bind("<Key-Return>", self.list_files_to_sync)

    def exclusion_supp(self):
        excl = ExclusionsSupp(self)
        self.wait_window(excl)
        # paths that will not be deleted
        self.exclude_path_supp = [
            ch.replace("\ ", " ") for ch in split(
                r'(?<!\\) ', CONFIG.get("Defaults", "exclude_supp")) if ch
        ]

    def exclusion_copie(self):
        excl = ExclusionsCopie(self)
        self.wait_window(excl)
        exclude_list = CONFIG.get("Defaults", "exclude_copie").split(" ")
        self.exclude_names = []
        self.exclude_ext = []
        for elt in exclude_list:
            if elt:
                if elt[:2] == "*.":
                    self.exclude_ext.append(elt[2:])
                else:
                    self.exclude_names.append(elt)

    def toggle_copy_links(self):
        CONFIG.set("Defaults", "copy_links", str(self.copy_links.get()))

    def open_log_copie(self):
        run(["xdg-open", self.log_copie])

    def open_log_suppression(self):
        run(["xdg-open", self.log_supp])

    def quitter(self):
        rep = True
        if self.is_running_copie or self.is_running_supp:
            rep = askokcancel(
                "Confirmation",
                "Une synchronisation est en cours, êtes-vous sur de vouloir quitter ?"
            )
        if rep:
            self.destroy()

    def del_fav(self, nom):
        self.menu_fav.delete(nom)
        self.menu_fav_del.delete(nom)
        FAVORIS.remove(tuple(nom.split(" -> ")))
        save_config()
        if not FAVORIS:
            self.menu_fav.entryconfigure(1, state="disabled")

    def add_fav(self):
        sauvegarde = self.entry_sauve.get()
        original = self.entry_orig.get()
        if original != sauvegarde and original and sauvegarde:
            if exists(original) and exists(sauvegarde):
                if not (original, sauvegarde) in FAVORIS:
                    FAVORIS.append((original, sauvegarde))
                    save_config()
                    label = "%s -> %s" % (original, sauvegarde)
                    self.menu_fav.entryconfigure(1, state="normal")
                    self.menu_fav.add_command(label=label,
                                              command=lambda o=original, s=
                                              sauvegarde: self.open(o, s))
                    self.menu_fav_del.add_command(
                        label=label,
                        command=lambda nom=label: self.del_fav(nom))

    def open(self, ch_o, ch_s):
        self.entry_orig.delete(0, "end")
        self.entry_orig.insert(0, ch_o)
        self.entry_sauve.delete(0, "end")
        self.entry_sauve.insert(0, ch_s)
        self.list_files_to_sync()

    def open_sauve(self):
        sauvegarde = askdirectory(self.entry_sauve.get())
        if sauvegarde:
            self.entry_sauve.delete(0, "end")
            self.entry_sauve.insert(0, sauvegarde)

    def open_orig(self):
        original = askdirectory(self.entry_orig.get())
        if original:
            self.entry_orig.delete(0, "end")
            self.entry_orig.insert(0, original)

    def sync(self, original, sauvegarde):
        """ peuple tree_copie avec l'arborescence des fichiers d'original à copier
            vers sauvegarde et tree_supp avec celle des fichiers de sauvegarde à
            supprimer """
        errors = []
        copy_links = self.copy_links.get()
        excl_supp = [
            path for path in self.exclude_path_supp
            if commonpath([path, sauvegarde]) == sauvegarde
        ]

        def arbo(tree, parent, n):
            """ affiche l'arborescence complète de parent et renvoie la longueur
                maximale des items (pour gérer la scrollbar horizontale) """
            m = 0
            if isdir(parent):
                try:
                    l = listdir(parent)
                except Exception as e:
                    errors.append(str(e))
                    l = []
                l.sort(key=lambda x: x.lower())
                for item in l:
                    chemin = join(parent, item)
                    if islink(chemin):
                        if copy_links:
                            tree.insert(parent,
                                        'end',
                                        chemin,
                                        text=item,
                                        tags=("whole", "link"))
                            m = max(m, len(item) * 9 + 20 * (n + 1))
                    elif ((item not in self.exclude_names)
                          and (splitext(item)[-1] not in self.exclude_ext)):
                        tree.insert(parent,
                                    'end',
                                    chemin,
                                    text=item,
                                    tags=("whole", ))
                        m = max(m, len(item) * 9 + 20 * (n + 1))
                        if isdir(chemin):
                            m = max(m, arbo(tree, chemin, n + 1))
            return m

        def aux(orig, sauve, n, search_supp):
            m_copie = 0
            m_supp = 0
            try:
                lo = listdir(orig)
                ls = listdir(sauve)
            except Exception as e:
                errors.append(str(e))
                lo = []
                ls = []
            lo.sort(key=lambda x: x.lower())
            ls.sort(key=lambda x: x.lower())
            supp = False
            copie = False
            if search_supp:
                for item in ls:
                    chemin_s = join(sauve, item)
                    if chemin_s not in excl_supp and item not in lo:
                        supp = True
                        self.tree_supp.insert(sauve,
                                              'end',
                                              chemin_s,
                                              text=item,
                                              tags=("whole", ))
                        m_supp = max(m_supp, int(len(item) * 9 + 20 * (n + 1)),
                                     arbo(self.tree_supp, chemin_s, n + 1))

            for item in lo:
                chemin_o = join(orig, item)
                chemin_s = join(sauve, item)
                if ((item not in self.exclude_names)
                        and (splitext(item)[-1] not in self.exclude_ext)):
                    if item not in ls:
                        # le dossier / fichier n'est pas dans la sauvegarde
                        if islink(chemin_o):
                            if copy_links:
                                copie = True
                                self.tree_copie.insert(orig,
                                                       'end',
                                                       chemin_o,
                                                       text=item,
                                                       tags=("whole", "link"))
                                m_copie = max(
                                    m_copie,
                                    (int(len(item) * 9 + 20 * (n + 1))))
                        else:
                            copie = True
                            self.tree_copie.insert(orig,
                                                   'end',
                                                   chemin_o,
                                                   text=item,
                                                   tags=("whole", ))
                            m_copie = max(
                                m_copie, (int(len(item) * 9 + 20 * (n + 1))),
                                arbo(self.tree_copie, chemin_o, n + 1))
                    elif islink(chemin_o) and exists(chemin_o):
                        # checking the existence prevent from copying broken links
                        if copy_links:
                            if not islink(chemin_s):
                                self.pb_chemins.append(chemin_o)
                                tags = ("whole", "warning", "link")
                            else:
                                tags = ("whole", "link")
                            self.tree_copie.insert(orig,
                                                   'end',
                                                   chemin_o,
                                                   text=item,
                                                   tags=tags)
                            m_copie = max(m_copie,
                                          int(len(item) * 9 + 20 * (n + 1)))
                            copie = True
                    elif isfile(chemin_o):
                        # first check if chemin_s is also a file
                        if isfile(chemin_s):
                            if getmtime(chemin_o) // 60 > getmtime(
                                    chemin_s) // 60:
                                # le fichier f a été modifié depuis la dernière sauvegarde
                                copie = True
                                self.tree_copie.insert(orig,
                                                       'end',
                                                       chemin_o,
                                                       text=item,
                                                       tags=("whole", ))
                        else:
                            self.pb_chemins.append(chemin_o)
                            self.tree_copie.insert(orig,
                                                   'end',
                                                   chemin_o,
                                                   text=item,
                                                   tags=("whole", "warning"))
                    elif isdir(chemin_o):
                        # to avoid errors due to unrecognized item types (neither file nor folder nor link)
                        if isdir(chemin_s):
                            self.tree_copie.insert(orig,
                                                   'end',
                                                   chemin_o,
                                                   text=item)
                            self.tree_supp.insert(sauve,
                                                  'end',
                                                  chemin_s,
                                                  text=item)
                            c, s, mc, ms = aux(
                                chemin_o, chemin_s, n + 1, search_supp
                                and (chemin_s not in excl_supp))
                            supp = supp or s
                            copie = copie or c
                            if not c:
                                # nothing to copy
                                self.tree_copie.delete(chemin_o)
                            else:
                                m_copie = max(
                                    m_copie, mc,
                                    int(len(item) * 9 + 20 * (n + 1)))
                            if not s:
                                # nothing to delete
                                self.tree_supp.delete(chemin_s)
                            else:
                                m_supp = max(m_supp, ms,
                                             int(len(item) * 9 + 20 * (n + 1)))
                        else:
                            copie = True
                            self.pb_chemins.append(chemin_o)
                            self.tree_copie.insert(orig,
                                                   'end',
                                                   chemin_o,
                                                   text=item,
                                                   tags=("whole", "warning"))
                            m_copie = max(
                                m_copie, (int(len(item) * 9 + 20 * (n + 1))),
                                arbo(self.tree_copie, chemin_o, n + 1))
            return copie, supp, m_copie, m_supp

        self.tree_copie.insert("",
                               0,
                               original,
                               text=original,
                               tags=("checked", ),
                               open=True)
        self.tree_supp.insert("",
                              0,
                              sauvegarde,
                              text=sauvegarde,
                              tags=("checked", ),
                              open=True)
        c, s, mc, ms = aux(original, sauvegarde, 1, True)
        if not c:
            self.tree_copie.delete(original)
            self.tree_copie.column("#0", minwidth=0, width=0)
        else:
            mc = max(len(original) * 9 + 20, mc)
            self.tree_copie.column("#0", minwidth=mc, width=mc)
        if not s:
            self.tree_supp.delete(sauvegarde)
            self.tree_supp.column("#0", minwidth=0, width=0)
        else:
            ms = max(len(sauvegarde) * 9 + 20, mc)
            self.tree_supp.column("#0", minwidth=ms, width=ms)
        return errors

    def show_warning(self, event):
        x, y = event.x, event.y
        elem = event.widget.identify("element", x, y)
        if elem == "padding":
            orig = self.tree_copie.identify_row(y)
            sauve = orig.replace(self.original, self.sauvegarde)
            showwarning(
                "Attention",
                "%s et %s ne sont pas de même nature (dossier/fichier/lien)" %
                (orig, sauve),
                master=self)

    def list_files_to_sync(self, event=None):
        """ display in a treeview the file to copy and the one to delete """
        self.pbar_copie.configure(value=0)
        self.pbar_supp.configure(value=0)
        self.sauvegarde = self.entry_sauve.get()
        self.original = self.entry_orig.get()
        if self.original != self.sauvegarde and self.original and self.sauvegarde:
            if exists(self.original) and exists(self.sauvegarde):
                o_s = (self.original, self.sauvegarde)
                if o_s in RECENT:
                    RECENT.remove(o_s)
                    self.menu_recent.delete("%s -> %s" % o_s)
                RECENT.insert(0, o_s)
                self.menu_recent.insert_command(
                    0,
                    label="%s -> %s" % o_s,
                    command=lambda o=self.original, s=self.sauvegarde: self.
                    open(o, s))
                if len(RECENT) == 10:
                    del (RECENT[-1])
                    self.menu_recent.delete(9)
                save_config()
                self.menu.entryconfigure(0, state="normal")
                self.configure(cursor="watch")
                self.toggle_state_gui()
                self.update_idletasks()
                self.update()
                self.efface_tree()
                err = self.sync(self.original, self.sauvegarde)
                self.configure(cursor="")
                self.toggle_state_gui()
                c = self.tree_copie.get_children("")
                s = self.tree_supp.get_children("")
                if not (c or s):
                    self.menu.entryconfigure(5, state="disabled")
                    self.b_collapse_copie.state(("disabled", ))
                    self.b_expand_copie.state(("disabled", ))
                    self.b_collapse_supp.state(("disabled", ))
                    self.b_expand_supp.state(("disabled", ))
                elif not c:
                    self.b_collapse_copie.state(("disabled", ))
                    self.b_expand_copie.state(("disabled", ))
                elif not s:
                    self.b_collapse_supp.state(("disabled", ))
                    self.b_expand_supp.state(("disabled", ))
                if err:
                    showerror("Erreurs", "\n".join(err))
                run([
                    "notify-send", "-i", IM_ICON, "FolderSync",
                    "Scan is finished."
                ])
                warnings = self.tree_copie.tag_has('warning')
                if warnings:
                    showwarning(
                        "Attention",
                        "Certains éléments à copier (en rouge) ne sont pas de même nature sur l'original et la sauvegarde"
                    )
            else:
                showerror("Erreur", "Chemin invalide !")

    def efface_tree(self):
        c = self.tree_copie.get_children("")
        for item in c:
            self.tree_copie.delete(item)
        s = self.tree_supp.get_children("")
        for item in s:
            self.tree_supp.delete(item)
        self.b_collapse_copie.state(("disabled", ))
        self.b_expand_copie.state(("disabled", ))
        self.b_collapse_supp.state(("disabled", ))
        self.b_expand_supp.state(("disabled", ))

    def toggle_state_gui(self):
        """ toggle the state (normal/disabled) of key elements of the GUI """
        if "disabled" in self.b_open_orig.state():
            state = "!disabled"
            for i in range(7):
                self.menu.entryconfigure(i, state="normal")
        else:
            state = "disabled"
            for i in range(7):
                self.menu.entryconfigure(i, state="disabled")
        self.tree_copie.state((state, ))
        self.tree_supp.state((state, ))
        self.entry_orig.state((state, ))
        self.entry_sauve.state((state, ))
        #        self.b_sync.state((state, ))
        #        self.b_prev.state((state, ))
        self.b_expand_copie.state((state, ))
        self.b_collapse_copie.state((state, ))
        self.b_expand_supp.state((state, ))
        self.b_collapse_supp.state((state, ))
        self.b_open_orig.state((state, ))
        self.b_open_sauve.state((state, ))

    def update_pbar(self):
        """ dislay the progress of the copy and deletion and put the GUI back in
            normal state once both processes are done. """
        if not self.is_running_copie and not self.is_running_supp:
            run([
                "notify-send", "-i", IM_ICON, "FolderSync", "Sync is finished."
            ])
            self.toggle_state_gui()
            self.pbar_copie.configure(value=self.pbar_copie.cget("maximum"))
            self.pbar_supp.configure(value=self.pbar_supp.cget("maximum"))
            #            self.b_sync.state(("disabled", ))
            self.menu.entryconfigure(5, state="disabled")
            self.configure(cursor="")
            self.efface_tree()
            msg = ""
            if self.err_copie:
                msg += "Il y a eu des erreurs lors de la copie, voir %s pour plus de détails.\n" % self.log_copie
            if self.err_supp:
                msg += "Il y a eu des erreurs lors de la suppression, voir %s pour plus de détails.\n" % self.log_supp
            if msg:
                showerror("Erreur", msg, master=self)
        else:
            if not self.q_copie.empty():
                self.pbar_copie.configure(value=self.q_copie.get())
            if not self.q_supp.empty():
                self.pbar_supp.configure(value=self.q_supp.get())
            self.update()
            self.after(50, self.update_pbar)

    @staticmethod
    def get_list(tree):
        """ return the list of files/folders to copy/delete
            (depending on the tree)"""
        selected = []

        def aux(item):
            tags = tree.item(item, "tags")
            if "checked" in tags and "whole" in tags:
                selected.append(item)
            elif "checked" in tags or "tristate" in tags:
                ch = tree.get_children(item)
                for c in ch:
                    aux(c)

        ch = tree.get_children("")
        for c in ch:
            aux(c)
        return selected

    def synchronise(self):
        """ display the list of files/folders that will be copied / deleted
            and launch the copy and deletion if the user validates the sync. """
        # get files to delete and folder to delete if they are empty
        a_supp = self.get_list(self.tree_supp)
        # get files to copy
        a_copier = self.get_list(self.tree_copie)
        a_supp_avant_cp = []
        for ch in self.pb_chemins:
            if ch in a_copier:
                a_supp_avant_cp.append(
                    ch.replace(self.original, self.sauvegarde))
        if a_supp or a_copier:
            Confirmation(self, a_copier, a_supp, a_supp_avant_cp,
                         self.original, self.sauvegarde)

    def copie_supp(self, a_copier, a_supp, a_supp_avant_cp):
        """ launch sync """
        self.toggle_state_gui()
        self.configure(cursor="watch")
        self.update()
        self.pbar_copie.state(("!disabled", ))
        self.pbar_supp.state(("!disabled", ))
        nbtot_copie = len(a_copier) + len(a_supp_avant_cp)
        self.pbar_copie.configure(maximum=nbtot_copie, value=0)
        nbtot_supp = len(a_supp)
        self.pbar_supp.configure(maximum=nbtot_supp, value=0)
        self.is_running_copie = True
        self.is_running_supp = True
        process_copie = Thread(target=self.copie,
                               name="copie",
                               daemon=True,
                               args=(a_copier, a_supp_avant_cp))
        process_supp = Thread(target=self.supp,
                              daemon=True,
                              name="suppression",
                              args=(a_supp, ))
        process_copie.start()
        process_supp.start()
        self.update_pbar()

    def copie(self, a_copier, a_supp_avant_cp):
        """ copie tous les fichiers/dossiers de a_copier de original vers
            sauvegarde en utilisant la commande système cp. Les erreurs
            rencontrées au cours du processus sont inscrites dans
            ~/.foldersync/copie.log """
        self.err_copie = False
        orig = abspath(self.original) + "/"
        sauve = abspath(self.sauvegarde) + "/"
        chdir(orig)
        self.logger_copie.info("\nCopie: %s -> %s\n" %
                               (self.original, self.sauvegarde))
        n = len(a_supp_avant_cp)
        self.logger_copie.info("\nSuppression avant copie:")
        for i, ch in zip(range(1, n + 1), a_supp_avant_cp):
            self.logger_copie.info(ch)
            p_copie = run(["rm", "-r", ch], stderr=PIPE)
            self.q_copie.put(i)
            err = p_copie.stderr.decode()
            if err:
                self.err_copie = True
                self.logger_copie.error(err.strip())
        self.logger_copie.info("\nCopie:")
        for i, ch in zip(range(n + 1, n + 1 + len(a_copier)), a_copier):
            ch_o = ch.replace(orig, "")
            self.logger_copie.info("%s -> %s" % (ch_o, sauve))
            p_copie = run(["cp", "-ra", "--parents", ch_o, sauve], stderr=PIPE)
            self.q_copie.put(i)
            err = p_copie.stderr.decode()
            if err:
                self.err_copie = True
                self.logger_copie.error(err.strip())
        self.is_running_copie = False

    def supp(self, a_supp):
        """ supprime tous les fichiers/dossiers de a_supp de original vers
            sauvegarde en utilisant la commande système rm. Les erreurs
            rencontrées au cours du processus sont inscrites dans
            ~/.foldersync/suppression.log """
        self.err_supp = False
        self.logger_supp.info("\nSuppression: %s -> %s\n" %
                              (self.original, self.sauvegarde))
        for i, ch in enumerate(a_supp):
            self.logger_supp.info(ch)
            p_supp = run(["rm", "-r", ch], stderr=PIPE)
            self.q_supp.put(i + 1)
            err = p_supp.stderr.decode()
            if err:
                self.logger_supp.error(err.strip())
                self.err_supp = True
        self.is_running_supp = False

    def unlink(self):
        """Unlink pidfile."""
        unlink(self.pidfile)
class TextFrameTry02(Frame):
    def __init__(self, parent, q):
        Frame.__init__(self, parent)

        # self.queue = q
        self.parent = parent

        # Status XInitThreads(void)
        # XInitThreads(void)

        self.initUI()

    def callback(self):
        self.root.quit()

    def initUI(self):

        # self.root = tk.Tk()
        # self.root = Tk()
        # self.root.protocol("WM_DELETE_WINDOW", self.callback)

        self.parent.title("TextFrameTry02 init title only")
        #self.title("TextFrameTry02 init title only")
        self.pack(fill=BOTH, expand=True)

        self.grid_columnconfigure(4, weight=1)
        self.grid_rowconfigure(3, weight=1)

        lbl1 = Label(self, text="Digits:")
        lbl1.grid(row=0, column=0, sticky=E, padx=10, pady=10)

        self.ent1 = Entry(self, width=10)
        self.ent1.insert(END, "4000")
        self.ent1.grid(row=0, column=1, sticky=W)

        lbl2 = Label(self, text="Accuracy:")
        lbl2.grid(row=0, column=2, sticky=E, padx=10, pady=10)

        self.ent2 = Entry(self, width=10)
        self.ent2.insert(END, "100")
        self.ent2.grid(row=0, column=3, sticky=W)

        self.startBtn = Button(self, text="Start", command=self.onStart)
        self.startBtn.grid(row=1, column=0, padx=10, pady=5, sticky=W)

        self.pbar = Progressbar(self, mode='indeterminate')
        self.pbar.grid(row=1, column=1, columnspan=3, sticky=W + E)

        # self.txt = st.ScrolledText(win)
        self.txt = st.ScrolledText(self)
        self.txt.grid(row=2,
                      column=0,
                      rowspan=4,
                      padx=10,
                      pady=5,
                      columnspan=5,
                      sticky=E + W + S + N)

        self.txt.insert(INSERT, "\nJust set up this txt.\n")
        self.txt.insert(INSERT, "Just set up this txt.\n")
        self.txt.insert(INSERT, "Just set up this txt.\n")
        self.txt.insert(INSERT, "Just set up this txt.\n")
        self.txt.insert(INSERT, "Just set up this txt.\n\n")
        # aKeyStrk = keyboard.read_key()
        # aKeyStrk = input()

        aComment = ''' 
        st.insert(tkinter.INSERT, 'Following Ports are open\n' )
        st.insert(tkinter.INSERT, str(portlist)) 
        
        # Creating scrolled text 
        # area widget
        text_area = st.ScrolledText(win, 
                                              wrap = tk.WORD, 
                                              width = 40, 
                                              height = 10, 
                                              font = ("Times New Roman",
                                                      15))
          
        text_area.grid(column = 0, pady = 10, padx = 10)
          
        # Placing cursor in the text area
        text_area.focus()
        
        '''

        # self.txt = st.ScrolledText(self.root, wrap = tk.WORD, width = 40, height = 10, font = ("Times New Roman", 15), grid=(row=2, column=0, rowspan=4, padx=10, pady=5, columnspan=5, sticky=E+W+S+N))

        # self.txt = st.ScrolledText(width = 40, height = 10, font = ("Times New Roman", 15), grid.row(2), grid.column(0), grid.rowspan(4), grid.padx(10), grid.pady(5), grid.columnspan(5), grid.sticky(E+W+S+N), wrap(tk.WORD))

        # self.txt = st.ScrolledText(self)

        # self.txt.grid(row=2, column=0, rowspan=4, padx=10, pady=5, columnspan=5, sticky=E+W+S+N)

        # text_area = st.ScrolledText(win,
        #wrap = tk.WORD,
        #width = 40,
        #height = 10,
        #font = ("Times New Roman",
        #15))

        # self.root.mainloop()

    def onStart(self):

        self.startBtn.config(state=DISABLED)
        self.txt.delete("1.0", END)
        self.txt.insert(INSERT, "\n\nNow onStart method is running.\n\n")
        print(self.onStart, "\nNow onStart method is running.\n")

        self.digits = int(self.ent1.get())
        self.accuracy = int(self.ent2.get())

        print("\nonStart, start to process generatePi is next.\n")
        self.txt.insert(
            INSERT, "\n\nonStart, start to process to generatePi is next.\n\n")

        self.parent_conn, self.child_conn = multiprocessing.Pipe()

        # creating new processes
        # p1 = multiprocessing.Process(target=sender, args=(parent_conn,msgs))
        # p2 = multiprocessing.Process(target=receiver, args=(child_conn,))

        msgs = ""

        # self.p1 = Process(target=self.generatePi)
        # self.p1 = Process(target=self.generatePi, args=(self.queue, ))
        self.p1 = Process(target=self.generatePi,
                          args=(self.parent_conn, msgs))
        self.p1.start()

        print("\nonStart, start to parallel process to generatePi started.\n")
        self.txt.insert(
            INSERT,
            "\n\nonStart, start to parallel process to generatePi started.\n\n"
        )
        self.pbar.start(DELAY2)
        self.after(DELAY1, self.onGetValue(self.child_conn, msgs))

    def onGetValue(self, conn, msgs):

        # if (self.p1.is_alive()):

        while self.p1.is_alive():
            print(
                "\nonGetValue finds ------------------------- generatePi Process is alive"
            )
            self.txt.insert(
                INSERT,
                "\nonGetValue finds ---------------------- generatePi Process is alive\n"
            )
            # self.after(DELAY1, self.onGetValue(conn, msgs))   # self.onGetValue)
            # return
            # msg = conn.recv()
            # self.txt.insert( msg )
            time.sleep(0.1)

    # else:

    # while 1:
    #     msg = conn.recv()
    #     if msg == "END":
    #         break
    #     print("Received the message: {}".format(msg))

    # try:
        msg = "msg"
        msg = conn.recv()
        print("This should be a pi: ", msg)
        self.txt.insert(END, "\nThis should be a pi: ")  # self.queue.get(0))
        self.txt.insert(END, msg)  # self.queue.get(0))
        self.txt.insert(END, "\n")
        self.txt.insert(INSERT, "\n\nNow running onGetValue else section.\n\n")
        print("\nNow running onGetValue else section.\n")

        self.pbar.stop()
        self.startBtn.config(state=NORMAL)

        # except conn.Empty:   # queue.Empty:
        # print("\nqueue is PLACEKEEPER empty\n")
        # self.txt.insert("\nqueue is PLACEKEEPER empty\n")

    def generatePi(self, conn, msgs):
        # def generatePi(self, queue):
        # def generatePi(self):               self.queue, , self.parent_conn, msgs
        #                  def sender(conn, msgs):

        getcontext().prec = self.digits

        pi = Decimal(0)
        # pi=999
        k = 0
        n = self.accuracy

        # self.txt.delete('1.0', END)
        # clear the outputtext text widget. 1.0 and
        # self.txt.delete("1.0", "end-1c")

        #self.txt.focus()

        # self.txt.delete(1.0,tk.END) # clear the outputtext text widget. 1.0 and tk.END are neccessary. tk implies the tkinter module. If you just want to add text dont incude that line
        print("\nNow running generatePi section.\n")
        ##### self.text.put("---------------")
        self.txt.insert(INSERT, "\n\n---------------\n\n")
        self.txt.insert(INSERT, "\n\nNow running generatePi section.\n\n")

        # aComment='''
        while k < n:
            pi += (Decimal(1)/(16**k))*((Decimal(4)/(8*k+1)) - \
                (Decimal(2)/(8*k+4)) - (Decimal(1)/(8*k+5))- \
                (Decimal(1)/(8*k+6)))
            k += 1

            # self.txt.insert(INSERT, 'Following Ports are open\n' )
            #st.insert(tkinter.INSERT, 'Following Ports are open\n' )
            #st.insert(tkinter.INSERT, str(portlist))
            # myvar = "the answer is {}".format(answer)
            # myvar = "the answer is " + str(answer)
            insertToTxtfr = ("\nTextFrameTry02 is still alive = " +
                             str(self.p1.is_alive()) + "")

            # insertToTxtfr = ('TextFrameTry02 is still alive = {}'.format(self.p1.is_alive())
            # insertToTxtfr = ('TextFrameTry02 is still alive = XXX')

            print(insertToTxtfr)
            # queue.put("TextFrameTry02 is still alive = ", self.p1.is_alive())
            # queue.put(" ")

            # outputtext.insert(tk.END,entryvar) # insert the entry widget contents in the text widget. tk.END is necessary.

            #self.txt.insert(INSERT, insertToTxtfr) # insert the entry widget contents in the text widget. tk.END is necessary.

            ##### self.txt.update_idletasks()
            # XInitThreads
            # self.txt.pack
            # conn.send( insertToTxtfr )
            time.sleep(0.01)
            # '''

        #### self.txt.update_idletasks()
        # self.txt.pack

        print("\nNow running print out pi section.\n")
        self.txt.insert(INSERT, "\n\nNow running print out pi section.\n\n")
        print(pi)
        print(self.parent.title(), " frame end")

        self.txt.insert(INSERT, "\n\nNow running INSERT out pi section.\n\n")
        self.txt.insert(INSERT, pi)
        self.txt.insert(INSERT, "\n\nDone INSERTING and printing out pi.\n\n")
        print("\nDone INSERTING and printing out pi.\n")

        conn.send(pi)

        #queue.put(" ")
        #queue.put("Putting Pi from generatePi function.\n")
        #queue.put(pi)
        #queue.put("Done putting Pi from generatePi function.\n")
        # queue.put(" ")
        # self.txt.pack
        print("Returning from generatePi.")
        return pi
Пример #13
0
class Query(Toplevel):
    """Base class for getting verified answer from a user.

    For this base class, accept any non-blank string.
    """
    def __init__(self, parent, title, message, *, text0='', used_names={},
                 _htest=False, _utest=False):
        """Create popup, do not return until tk widget destroyed.

        Additional subclass init must be done before calling this
        unless  _utest=True is passed to suppress wait_window().

        title - string, title of popup dialog
        message - string, informational message to display
        text0 - initial value for entry
        used_names - names already in use
        _htest - bool, change box location when running htest
        _utest - bool, leave window hidden and not modal
        """
        Toplevel.__init__(self, parent)
        self.withdraw()  # Hide while configuring, especially geometry.
        self.parent = parent
        self.title(title)
        self.message = message
        self.text0 = text0
        self.used_names = used_names
        self.transient(parent)
        self.grab_set()
        windowingsystem = self.tk.call('tk', 'windowingsystem')
        if windowingsystem == 'aqua':
            try:
                self.tk.call('::tk::unsupported::MacWindowStyle', 'style',
                             self._w, 'moveableModal', '')
            except:
                pass
            self.bind("<Command-.>", self.cancel)
        self.bind('<Key-Escape>', self.cancel)
        self.protocol("WM_DELETE_WINDOW", self.cancel)
        self.bind('<Key-Return>', self.ok)
        self.bind("<KP_Enter>", self.ok)
        self.resizable(height=False, width=False)
        self.create_widgets()
        self.update_idletasks()  # Needed here for winfo_reqwidth below.
        self.geometry(  # Center dialog over parent (or below htest box).
                "+%d+%d" % (
                    parent.winfo_rootx() +
                    (parent.winfo_width()/2 - self.winfo_reqwidth()/2),
                    parent.winfo_rooty() +
                    ((parent.winfo_height()/2 - self.winfo_reqheight()/2)
                    if not _htest else 150)
                ) )
        if not _utest:
            self.deiconify()  # Unhide now that geometry set.
            self.wait_window()

    def create_widgets(self):  # Call from override, if any.
        # Bind to self widgets needed for entry_ok or unittest.
        self.frame = frame = Frame(self, padding=10)
        frame.grid(column=0, row=0, sticky='news')
        frame.grid_columnconfigure(0, weight=1)

        entrylabel = Label(frame, anchor='w', justify='left',
                           text=self.message)
        self.entryvar = StringVar(self, self.text0)
        self.entry = Entry(frame, width=30, textvariable=self.entryvar)
        self.entry.focus_set()
        self.error_font = Font(name='TkCaptionFont',
                               exists=True, root=self.parent)
        self.entry_error = Label(frame, text=' ', foreground='red',
                                 font=self.error_font)
        self.button_ok = Button(
                frame, text='OK', default='active', command=self.ok)
        self.button_cancel = Button(
                frame, text='Cancel', command=self.cancel)

        entrylabel.grid(column=0, row=0, columnspan=3, padx=5, sticky=W)
        self.entry.grid(column=0, row=1, columnspan=3, padx=5, sticky=W+E,
                        pady=[10,0])
        self.entry_error.grid(column=0, row=2, columnspan=3, padx=5,
                              sticky=W+E)
        self.button_ok.grid(column=1, row=99, padx=5)
        self.button_cancel.grid(column=2, row=99, padx=5)

    def showerror(self, message, widget=None):
        #self.bell(displayof=self)
        (widget or self.entry_error)['text'] = 'ERROR: ' + message

    def entry_ok(self):  # Example: usually replace.
        "Return non-blank entry or None."
        self.entry_error['text'] = ''
        entry = self.entry.get().strip()
        if not entry:
            self.showerror('blank line.')
            return None
        return entry

    def ok(self, event=None):  # Do not replace.
        '''If entry is valid, bind it to 'result' and destroy tk widget.

        Otherwise leave dialog open for user to correct entry or cancel.
        '''
        entry = self.entry_ok()
        if entry is not None:
            self.result = entry
            self.destroy()
        else:
            # [Ok] moves focus.  (<Return> does not.)  Move it back.
            self.entry.focus_set()

    def cancel(self, event=None):  # Do not replace.
        "Set dialog result to None and destroy tk widget."
        self.result = None
        self.destroy()
Пример #14
0
class MemberChecker(PanedWindow):
    def __init__(self, parent):
        PanedWindow.__init__(self, parent, background="white")

        self.parent = parent
        self.init_data()
        self.init_log()
        self.init_ui()
        self.update_status()

    def init_data(self):
        self.data_store = api.DataStore()

    def init_log(self):
        self.entrance_log = entrance_log.EntranceLog()

    def init_ui(self):
        self.parent.title("Member Checker")
        self.columnconfigure(3, weight=3)
        self.pack(fill=BOTH, expand=True)

        self.input = StringVar()
        self.input_entry = Entry(self, textvariable=self.input)
        self.input_entry.bind('<Return>', self.submit)
        self.input_entry.grid(row=0, column=0, columnspan=3, sticky=E + W)

        self.result = StringVar()
        self.result_label = Label(self, textvariable=self.result)
        self.result_label.grid(row=3, column=0, columnspan=3, sticky=E + W)

        self.name = StringVar()
        name_label = Label(self, textvariable=self.name)
        name_label.grid(row=2, column=0, columnspan=3, sticky=E + W)

        self.status = StringVar()
        status_label = Label(self, textvariable=self.status)
        status_label.grid(row=4, column=0, columnspan=4, sticky=E + W)

        submit_button = Button(self, text="Submit", command=self.submit)
        submit_button.grid(row=1, column=2)

        enter_without_card_button = Button(self, text="Enter without card", command=self.enter_without_card)
        enter_without_card_button.grid(row=1, column=0)

        enter_member_without_card_button = Button(self, text="Enter member without card",
                                                  command=self.enter_member_without_card)
        enter_member_without_card_button.grid(row=1, column=1)

        self.entrance_log_list = Listbox(self)
        self.entrance_log_list.grid(row=0, column=3, rowspan=4, sticky=E + W + S + N)

        self.input_entry.focus()

    def load_data(self):
        if messagebox.askyesno("Load new API Data",
                               "Are you sure you want to load the new API data? All previous data will be removed. The program might be unresponsive for a few seconds, but don't kill it, please! It has feelings too."):
            self.data_store.load_api_data()

    def enter_by_identification(self, identification):
        member = self.data_store.find_member_by_identification(identification)
        if member is None:
            if messagebox.askyesno("Not a member",
                                   "This university identification is not registered as a member. Do you want to let them in as a non-member?"):
                self.enter_non_member_by_identification(identification)
        else:
            self.enter_member(member)

    def enter_by_barcode(self, barcode):
        member = self.data_store.find_member_by_barcode(barcode)
        if member is None:
            if messagebox.askyesno("Not a member",
                                   "This barcode is not registered as a member. Do you want to let them in as a non-member?"):
                self.enter_non_member_by_barcode(barcode)
        else:
            self.enter_member(member)

    def enter_non_member_by_identification(self, identification):
        self.entrance_log.enter_non_member_by_identification(identification)
        self.enter_non_member()

    def enter_non_member_by_barcode(self, barcode):
        self.entrance_log.enter_non_member_by_barcode(barcode)
        self.enter_non_member()

    def enter_without_card(self):
        self.clear_result()
        self.entrance_log.enter_without_card()
        self.enter_non_member()
        self.input_entry.focus()

    def enter_member(self, member):
        inside_result = self.entrance_log.is_member_inside(member)
        if inside_result[0]:
            if not messagebox.askyesno("Already inside",
                                       "This membership card has already been used to enter at {}. Are you sure you want to register it again? Normally you should let this person enter without card (and bill them accordingly).".format(
                                           inside_result[1])):
                return
        self.entrance_log.enter_member(member)
        self.result.set('Member!')
        self.result_label.configure(background='green')
        self.name.set(member['firstName'] + ' ' + member['lastName'])

        self.update_status()

    def enter_non_member(self):
        self.result.set('Not a member!')
        self.result_label.configure(background='red')
        self.name.set('Not in the database')

        self.update_status()

    def enter_member_without_card(self):
        name = self.input.get()
        if len(name) == 0:
            messagebox.showinfo('Name required', 'Please enter the name of this person!')
            return
        self.entrance_log.enter_member_without_card(name)
        self.result.set('Member without card!')
        self.result_label.configure(background="orange")
        self.name.set('')
        self.input.set('')
        self.update_status()

    def clear_result(self):
        self.result.set('')
        self.result_label.configure(background='white')
        self.name.set('')

    def submit(self, event=None):
        self.clear_result()

        entry = self.input.get()
        if helpers.is_valid_identification(entry):
            self.enter_by_identification(entry)
        elif helpers.is_valid_barcode(entry):
            self.enter_by_barcode(entry)
        else:
            messagebox.showinfo('Invalid entry',
                                'The data entered was not recognized as a valid bar code or a valid university identification. You should click \'enter without card\' to let this person in.')
            return

        self.input.set('')
        self.input_entry.focus()

    def clear_log(self):
        if messagebox.askyesno("Clear log", "Are you sure you want to clear the log of all people who entered?"):
            self.entrance_log.clear_log()
            self.update_status()

    def update_status(self):
        self.status.set("{} members inside. Total: {}".format(self.entrance_log.members_inside_count(),
                                                              self.entrance_log.inside_count()))

        logs = self.entrance_log.get_latest_logs(15)
        self.entrance_log_list.delete(0, 15)
        for l in logs:
            s = l['timestamp'] + ": "
            data = l['data']
            if 'member_id' in data:
                member = self.data_store.find_member(data['member_id'])
                s += member['firstName'] + " " + member['lastName']
            elif 'barcode' in data:
                s += data['barcode']
            elif 'identification' in data:
                s += data['identification']
            elif 'name' in data:
                s += '[no card]' + data['name']
            else:
                s += "-"
            self.entrance_log_list.insert(0, s)
Пример #15
0
class FrameDownload(Frame):

    def __init__(self, master=None, option=()):
        super().__init__(master=master)
        self.master = master
        self.master.title('Download information')
        self.option = option
        self.setupUI()

    def setupUI(self):
        # build UI base on URLS
        if self.option[2] == SEARCH:
            # title window
            label_title = Label(self, text='Search Photos')
            label_title.config(anchor='center', foreground='white', background='#8e44ad')
            label_title.grid(row=0, column=0, columnspan=6, sticky='we')

            # progress
            self.progress = Progressbar(self) 
            self.progress.config(orient='horizontal', length=100, mode='determinate')
            self.progress.grid(row=2, column=0, columnspan=5, sticky='we')

            self.var_progress = StringVar()
            self.var_progress.set('0%')
            self.label_show_progress = Label(self) 
            self.label_show_progress.config(textvariable=self.var_progress, anchor='center')
            self.label_show_progress.var = self.var_progress
            self.label_show_progress.grid(row=2, column=5, sticky='w')

            # query
            self.label_query = Label(self, text='Query')
            self.label_query.grid(row=1, column=0, sticky='e')

            self.var_entry_query = StringVar()
            self.entry_query = Entry(self)
            self.entry_query.config(textvariable=self.var_entry_query, state='readonly')
            self.entry_query.grid(row=1, column=1, sticky='w')

            # total
            self.var_total = StringVar()
            self.var_total.set('Total')
            self.label_total = Label(self, textvariable=self.var_total)
            self.label_total.grid(row=1, column=2, sticky='e')

            self.var_entry_total = IntVar()
            self.entry_total = Entry(self)
            self.entry_total.config(textvariable=self.var_entry_total, state='readonly')
            self.entry_total.grid(row=1, column=3, sticky='w')

            # total pages
            self.label_total_page = Label(self, text='Total pages:')
            self.label_total_page.grid(row=1, column=4, sticky='e')

            self.var_entry_total_pages = IntVar()
            self.entry_total_page = Entry(self)
            self.entry_total_page.config(textvariable=self.var_entry_total_pages, state='readonly')
            self.entry_total_page.grid(row=1, column=5, sticky='w')

            # show image is downloaded
            self.label_image_downloaded = Label(self, anchor='center')
            self.label_image_downloaded.grid(row=3, column=0, columnspan=6, sticky='wesn')
            
            # self.change_ui()

        elif self.option[2] == LIST:
            # title window
            label_title = Label(self, text='List of Photos')
            label_title.config(
                anchor='center', foreground='white', background='#2c3e50')
            label_title.grid(row=0, column=0, columnspan=4, sticky='we')

            # progress
            self.progress = Progressbar(self)
            self.progress.config(orient='horizontal',
                                 length=100, mode='determinate')
            self.progress.grid(row=2, column=0, columnspan=3, sticky='we')

            self.var_progress = StringVar()
            self.var_progress.set('0%')
            self.label_show_progress = Label(self)
            self.label_show_progress.config(
                textvariable=self.var_progress, anchor='center')
            self.label_show_progress.var = self.var_progress
            self.label_show_progress.grid(row=2, column=3, sticky='w')

            # query
            self.label_query = Label(self, text='Query:')
            self.label_query.grid(row=1, column=0, sticky='e')

            self.entry_query = Entry(self)
            self.entry_query.insert(0,'LIST')
            self.entry_query.config(state='readonly')
            self.entry_query.grid(row=1, column=1, sticky='w')

            # amount
            self.label_total = Label(self, text='Amount:')
            self.label_total.grid(row=1, column=2, sticky='e')

            self.entry_total = Entry(self)
            self.entry_total.insert(0,self.option[3]['per_page'])
            self.entry_total.config(state='readonly')
            self.entry_total.grid(row=1, column=3, sticky='w')

            # show image is downloaded
            self.label_image_downloaded = Label(self, anchor='center')
            self.label_image_downloaded.grid(
                row=3, column=0, columnspan=4, sticky='wesn')

            # self.change_ui()

        elif self.option[2] == RANDOM:
            # title window
            label_title = Label(self, text='Random Photos')
            label_title.config(
                anchor='center', foreground='white', background='#16a085')
            label_title.grid(row=0, column=0, columnspan=4, sticky='we')

            # progress
            self.progress = Progressbar(self)
            self.progress.config(orient='horizontal',
                                 length=100, mode='determinate')
            self.progress.grid(row=2, column=0, columnspan=3, sticky='we')

            self.var_progress = StringVar()
            self.var_progress.set('0%')
            self.label_show_progress = Label(self)
            self.label_show_progress.config(
                textvariable=self.var_progress, anchor='center')
            self.label_show_progress.var = self.var_progress
            self.label_show_progress.grid(row=2, column=3, sticky='w')

            # query
            self.label_query = Label(self, text='Query')
            self.label_query.grid(row=1, column=0, sticky='e')

            self.entry_query = Entry(self)
            self.entry_query.insert(0,'RANDOM')
            self.entry_query.config(state='readonly')
            self.entry_query.grid(row=1, column=1, sticky='w')

            # amount
            self.label_total = Label(self, text='Amount')
            self.label_total.grid(row=1, column=2, sticky='e')

            self.var_entry_total = IntVar()
            if self.option[3]['count'] > 30:
                self.var_entry_total.set(30)
            else:
                self.var_entry_total.set(self.option[3]['count'])
            self.entry_total = Entry(self)
            self.entry_total.config(textvariable=self.var_entry_total, state='readonly')
            self.entry_total.grid(row=1, column=3, sticky='w')
            

            # show image is downloaded
            self.label_image_downloaded = Label(self, anchor='center')
            self.label_image_downloaded.grid(
                row=3, column=0, columnspan=4, sticky='wesn')

    def change_ui(self):
        if self.option[2] == SEARCH:
            r = requests.get(self.option[2], params=self.option[3])
            if r.status_code == 200:
                # get urls based on quality
                j = json.loads(r.text)
                total = j['total']
                total_pages = j['total_pages']
                results = j['results']

                self.var_entry_query.set(self.option[3]['query'])
                self.var_entry_total.set(total)
                self.var_entry_total_pages.set(total_pages)

                self.entry_query.update_idletasks()
                self.entry_total.update_idletasks()
                self.entry_total_page.update_idletasks()

        # random photos
        elif self.option[2] == RANDOM:
            r = requests.get(self.option[2], params=self.option[3])
            if r.status_code == 200:

                # get result
                j = json.loads(r.text)
                results = j

        elif self.option[2] == LIST:
            r = requests.get(self.option[2], params=self.option[3])
            if r.status_code == 200:

                # get result
                j = json.loads(r.text)
                results = j

        self.download(results)

    def download(self, results):
        for i in results:
            name = i['id']
            url = i['urls'][self.option[1]]
            time.sleep(1)  # delay time to send request
            try:
                request.urlretrieve(url, self.option[0]+'/'+name+'.jpg')
            except Exception as x:  # re download if have a problem
                print('have problem', x)
                time.sleep(1)

            self.progress['value'] += 100/len(results)
            self.var_progress.set('{}%'.format(self.progress['value']))

            # show image downloaded
            image = Image.open(self.option[0]+'/'+name+'.jpg')
            width = int(self.winfo_width())
            height = int(width*image.height/image.width)
            self.photo = ImageTk.PhotoImage(
                image.resize((width, height), Image.ANTIALIAS))
            self.label_image_downloaded.config(image=self.photo)
            self.label_image_downloaded.image = self.photo

            self.progress.update_idletasks()
            
        self.message_done = messagebox.showinfo('Info', 'Done')
        self.master.destroy()
Пример #16
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()
Пример #17
0
class DbFrame(Frame):
    def __init__(self, master):
        super(DbFrame, self).__init__(master)
        self.root = master
        self.client = db_utils.get_client()

        # get any previous data on last.json
        previous_data = read_write.read_last()

        # Two frames will hold the widgets
        label_frm = Frame(self)  # the labels and entries
        label_frm.grid(row=0, pady=10, padx=50)
        button_frm = Frame(self)  # the buttons
        button_frm.grid(row=1, pady=5, padx=50)

        # Build the widgets for label_frm
        Label(label_frm, text="Database:").grid(column=2,
                                                row=0,
                                                pady=10,
                                                padx=5)
        Label(label_frm, text="Collection:").grid(column=2, row=1, padx=5)
        self.db_entry = Entry(label_frm, width=30)
        self.db_entry.grid(column=3, row=0, pady=10)
        self.collection_entry = Entry(label_frm, width=30)
        self.collection_entry.grid(column=3, row=1)

        # Add data to entries if any data on last.json
        try:
            if previous_data["database"] is not "":
                self.db_entry.insert(0, previous_data["database"])
        except KeyError as e:
            message = "[ERROR] (frames.DbFrame) : KeyError: " + str(e)
            read_write.log_message(message)
        try:
            if previous_data["collection"] is not "":
                self.collection_entry.insert(0, previous_data["collection"])
        except KeyError as e:
            message = "[ERROR] (frames.DbFrame) : KeyError: " + str(e)
            read_write.log_message(message)

        # Build the widgets for button_frm
        self.next_btn = Button(button_frm, text="Next")
        self.next_btn.grid(column=2, row=0, pady=10, padx=4, ipadx=2, ipady=2)
        self.back_btn = Button(button_frm, text="Back")
        self.back_btn.grid(column=4, row=0, pady=10, padx=4, ipadx=2, ipady=2)
        self.previous_dbs_btn = Button(button_frm,
                                       text="Show databases",
                                       command=self.show_dbs)
        self.previous_dbs_btn.grid(column=2, row=1, ipadx=2, ipady=2)
        self.previous_collection_btn = Button(button_frm,
                                              text="Show collections",
                                              command=self.show_collections)
        self.previous_collection_btn.grid(column=4, row=1, ipadx=2, ipady=2)

        # Build the widgets for dbs_frm
        self.selected_db_var = StringVar()
        self.selected_collection_var = StringVar()

    # this method populates the dbs radio-buttons. This happen every time, show_dbs method runs
    def populate_dbs(self):
        def select_db():
            self.selected_db_var = db_var
            selected_db = str(db_var.get())
            self.db_entry.delete(0, "end")
            self.db_entry.insert(0, selected_db)
            # we add the drop button, only if a radio-button is pressed
            self.drop_db_btn = Button(self.dbs_frm,
                                      text="Drop database",
                                      command=self.drop_db)
            self.drop_db_btn.grid(row=db_counter,
                                  column=2,
                                  pady=10,
                                  ipadx=5,
                                  ipady=2)

        db_var = StringVar()

        db_list = self.client.database_names(
        )  # we get the available database names of this connection

        db_counter = 0
        read_write.log_message("[INFO] (frames.DbFrame) : DBs found: " +
                               str(db_list))
        for name in db_list:
            r = Radiobutton(self.dbs_frm,
                            text=name,
                            variable=db_var,
                            value=name,
                            command=select_db)
            r.grid(row=db_counter, column=2, pady=2)
            db_counter += 1

    # this method populates the collection radio-buttons. This happen every time, show_collections method runs
    def populate_collections(self):
        def select_collection():
            self.selected_collection_var = collection_var
            selected_collection = str(collection_var.get())
            self.collection_entry.delete(0, "end")
            self.collection_entry.insert(0, selected_collection)
            # we add the drop button, only if a radio-button is pressed
            self.drop_collection_btn = Button(self.collections_frm,
                                              text="Drop collection",
                                              command=self.drop_collection)
            self.drop_collection_btn.grid(row=collection_counter,
                                          column=2,
                                          pady=10,
                                          ipadx=5,
                                          ipady=2)

        collection_var = StringVar()
        collection_list = [
        ]  # we get the available collection names of this connection but
        # only if a database name already exists
        if self.db_entry.get() is not "":
            collection_list = self.client[self.db_entry.get(
            )].collection_names(include_system_collections=False)

        collection_counter = 0  # this counter is responsible to place the radio-buttons into correct row
        for name in collection_list:
            r = Radiobutton(self.collections_frm,
                            text=name,
                            variable=collection_var,
                            value=name,
                            command=select_collection)
            r.grid(row=collection_counter, column=2, pady=2)
            collection_counter += 1

    def show_dbs(self):
        # create the frame
        self.dbs_frm = Frame(self)  # the frame that will show the dbs
        self.dbs_frm.grid(row=2, pady=5, padx=50)
        try:
            self.populate_dbs()
        except ServerSelectionTimeoutError as e:
            read_write.log_message("[ERROR]" + LOG_NAME +
                                   "ServerSelectionTimeoutError: " + str(e))
            messagebox.showerror("Error", "Lost Connection to the DB")
        except AutoReconnect as e:
            read_write.log_message("[ERROR]" + LOG_NAME + "AutoReconnect: " +
                                   str(e))
            messagebox.showerror("Error", "Lost Connection to the DB")

        try:  # if collections already shown, we need to hide them, but if not, this will raise an exception
            self.hide_collections()
        except AttributeError:
            pass

        # change the button's text and grid the frame
        self.previous_dbs_btn.config(command=self.hide_dbs,
                                     text="Hide databases")
        self.dbs_frm.grid()

    def hide_dbs(self):
        self.previous_dbs_btn.config(command=self.show_dbs,
                                     text="Show databases")
        self.dbs_frm.grid_remove()

    def show_collections(self):
        # create the frame
        self.collections_frm = Frame(
            self)  # the frame that will show the collections
        self.collections_frm.grid(row=2, pady=5, padx=50)
        try:
            self.populate_collections()
        except ServerSelectionTimeoutError as e:
            read_write.log_message("[ERROR]" + LOG_NAME +
                                   "ServerSelectionTimeoutError: " + str(e))
            messagebox.showerror("Error", "Lost Connection to the DB")
        except AutoReconnect as e:
            read_write.log_message("[ERROR]" + LOG_NAME + "AutoReconnect: " +
                                   str(e))
            messagebox.showerror("Error", "Lost Connection to the DB")

        try:  # if dbs already shown, we need to hide them, but if not, this will raise an exception
            self.hide_dbs()
        except AttributeError:
            pass

        # change the button's text and grid the frame
        self.previous_collection_btn.config(command=self.hide_collections,
                                            text="Hide collections")
        self.collections_frm.grid()

    def hide_collections(self):
        self.previous_collection_btn.config(command=self.show_collections,
                                            text="Show collections")
        self.collections_frm.grid_remove()

    def drop_db(self):
        name = self.selected_db_var.get()
        answer = messagebox.askokcancel(
            title="Are you sure?",
            message="Are you sure you want to delete " + name,
            default="cancel",
            parent=self.root)
        if answer:
            read_write.log_message(
                "[INFO] (frames.DbFrame) : Dropping database '" + name + "'")
            try:
                self.client.drop_database(name)
            except ServerSelectionTimeoutError as e:
                read_write.log_message("[ERROR]" + LOG_NAME +
                                       "ServerSelectionTimeoutError: " +
                                       str(e))
                messagebox.showerror("Error", "Lost Connection to the DB")
                return
            self.hide_dbs()
            self.show_dbs()

    def drop_collection(self):
        name = self.selected_collection_var.get()
        answer = messagebox.askokcancel(
            title="Are you sure?",
            message="Are you sure you want to delete " + name,
            default="cancel",
            parent=self.root)
        if answer:
            read_write.log_message(
                "[INFO] (frames.DbFrame) : Dropping collection '" + name + "'")
            db_name = self.db_entry.get()
            try:
                self.client[db_name].drop_collection(name)
            except ServerSelectionTimeoutError as e:
                read_write.log_message("[ERROR]" + LOG_NAME +
                                       "ServerSelectionTimeoutError: " +
                                       str(e))
                messagebox.showerror("Error", "Lost Connection to the DB")
                return
            self.hide_collections()
            self.show_collections()
Пример #18
0
class qbtConvertor(Tk):
    """ GUI Application for migration from uTorrent to qBittorrent """
    def __init__(self):
        Tk.__init__(self)
        self.title("uT to qBt convertor")

        #main frame
        self.main_frame = Frame(self, padding="3 3 12 12")
        self.main_frame.grid(column=0, row=0, sticky=(N, W, E, S))
        self.main_frame.columnconfigure(0, weight=1)
        self.main_frame.rowconfigure(0, weight=1)

        #uT part
        self.ut_data = StringVar()
        self.ut_label = Label(self.main_frame, text="uT data")
        self.ut_label.grid(column=0, row=1, sticky=(W))
        self.ut_entry = Entry(self.main_frame, width=100, textvariable=self.ut_data)
        self.ut_entry.grid(column=1, row=1, sticky=(W))
        self.ut_button = Button(self.main_frame, text="Browse", command=self.load_file)
        self.ut_button.grid(column=2, row=1)

        #qBt part
        self.qbt_folder = StringVar()
        self.qbt_label = Label(self.main_frame, text="qBt folder")
        self.qbt_label.grid(column=0, row=4, sticky=(W))
        self.qbt_entry = Entry(self.main_frame, width=100, textvariable=self.qbt_folder)
        self.qbt_entry.grid(column=1, row=4, sticky=(W))
        self.qbt_button = Button(self.main_frame, text="Browse", command=self.open_dir)
        self.qbt_button.grid(column=2, row=4, sticky=(W, E))


        #convertor
        self.convertor_button = Button(self.main_frame, text="Convert", command=self.convert,
                                       width=50)
        self.convertor_button.grid(column=1, columnspan=2, row=5)

        self.progress_bar = Progressbar(self.main_frame, orient=HORIZONTAL, length=300, mode="indeterminate")
        self.progress_bar.grid(column=1, columnspan=3, row=6)

        #set padding for each element
        for child in self.main_frame.winfo_children():
            child.grid_configure(padx=5, pady=5)

    def convert(self):
        message = messagebox
        if not self.qbt_folder.get() or not self.ut_data.get():
            message.showerror("ERROR", "Specify paths!")
            return
        self.progress_bar.start()
        convertor(self.ut_data.get(), self.qbt_folder.get())
        self.progress_bar.stop()

    def load_file(self):
        file_name = filedialog.askopenfilename(filetypes=(("UT resume file", "*.dat"),
                                                          ("All", "*")))
        if file_name:
            self.ut_data.set(file_name)

    def open_dir(self):
        dir_name = filedialog.askdirectory()

        if dir_name:
            self.qbt_folder.set(dir_name)
Пример #19
0
class Example(Frame):
    def __init__(self, parent, q):
        Frame.__init__(self, parent)
        self.queue = q
        self.parent = parent
        self.initUI()

    def initUI(self):
        self.parent.title("Pi computation")
        self.pack(fill=BOTH, expand=True)

        self.grid_columnconfigure(4, weight=1)
        self.grid_rowconfigure(3, weight=1)

        lbl1 = Label(self, text="Digits:")
        lbl1.grid(row=0, column=0, sticky=E, padx=10, pady=10)

        self.ent1 = Entry(self, width=10)
        self.ent1.insert(END, "4000")
        self.ent1.grid(row=0, column=1, sticky=W)

        lbl2 = Label(self, text="Accuracy:")
        lbl2.grid(row=0, column=2, sticky=E, padx=10, pady=10)

        self.ent2 = Entry(self, width=10)
        self.ent2.insert(END, "100")
        self.ent2.grid(row=0, column=3, sticky=W)

        self.startBtn = Button(self, text="Start",
                               command=self.onStart)
        self.startBtn.grid(row=1, column=0, padx=10, pady=5, sticky=W)

        self.pbar = Progressbar(self, mode='indeterminate')
        self.pbar.grid(row=1, column=1, columnspan=3, sticky=W+E)

        self.txt = scrolledtext.ScrolledText(self)
        self.txt.grid(row=2, column=0, rowspan=4, padx=10, pady=5,
                      columnspan=5, sticky=E+W+S+N)

    def onStart(self):
        self.startBtn.config(state=DISABLED)
        self.txt.delete("1.0", END)

        self.digits = int(self.ent1.get())
        self.accuracy = int(self.ent2.get())

        self.p1 = Process(target=self.generatePi, args=(self.queue,))
        self.p1.start()
        self.pbar.start(DELAY2)
        self.after(DELAY1, self.onGetValue)

    def onGetValue(self):
        if (self.p1.is_alive()):
            self.after(DELAY1, self.onGetValue)
            return
        else:
            try:
                self.txt.insert('end', self.queue.get(0))
                self.txt.insert('end', "\n")
                self.pbar.stop()
                self.startBtn.config(state=NORMAL)
            except queue.Empty:
                print("queue is empty")

    def generatePi(self, queue):
        getcontext().prec = self.digits
        time.sleep(10)

        pi = Decimal(0)
        k = 0
        n = self.accuracy

        while k < n:
            pi += (Decimal(1)/(16**k))*((Decimal(4)/(8*k+1)) -
                                        (Decimal(2)/(8*k+4)) -
                                        (Decimal(1)/(8*k+5)) -
                                        (Decimal(1)/(8*k+6)))
            k += 1
            print(self.p1.is_alive())

        queue.put(pi)
        print("end")
Пример #20
0
class BookManagerUi(Frame):

    def __init__(self, parent):
        Frame.__init__(self, parent)

        self.parent = parent

        self.initUI()

        self.db = dao('blist') #데이터베이스 관리 클래스 생성


    def initUI(self):

        self.parent.title("Book Manager")
        self.style = Style()
        self.style.theme_use("default")
        self.pack(fill=BOTH, expand=1)

        self.columnconfigure(0, pad=3)
        self.columnconfigure(1, pad=3)
        self.columnconfigure(2, 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.rowconfigure(5, pad=3)
        self.rowconfigure(6, pad=3)


        self.input_bname=''
        self.input_aname=''
        self.input_price=0
        self.delete=''

        lb_bookname = Label(self, text="bookname:")
        lb_bookname.grid(row=0, column =0 ,sticky=W, pady=4, padx=5)

        self.entry_bookname = Entry(self)
        self.entry_bookname.grid(row=0, column = 1 )

        lb_author = Label(self, text="author:")
        lb_author.grid(row=0, column =2,sticky=W, pady=4, padx=5)

        self.entry_author = Entry(self)
        self.entry_author.grid(row=0, column = 3 )


        lb_price = Label(self, text="price:")
        lb_price.grid(row=0, column =4 ,sticky=W, pady=4, padx=5)

        self.entry_price = Entry(self)
        self.entry_price.grid(row=0, column = 5 ,padx=15)


        abtn = Button(self, text="Add", command=lambda:self.clicked_add())
        abtn.grid(row=0, column=6)

        sbtn = Button(self, text="Serach", command = lambda:self.clicked_search())
        sbtn.grid(row=1, column=6, pady=4)

        dbtn = Button(self, text="Delete", command = lambda:self.clicked_delete())
        dbtn.grid(row=2, column=6, pady=4)

        self.lb = Listbox(self)

        self.lb.grid(row=3,column = 0, columnspan = 6,rowspan= 4, sticky = E+W+S+N)
        self.lb.bind("<<ListboxSelect>>", self.onSelect)


    #삭제를 위한 select부분
    def onSelect(self,val):
        sender = val.widget
        idx = sender.curselection()
        value = sender.get(idx)

        self.delete = value

    # 데이터 추가 버튼
    def clicked_add(self):
        bname =self.entry_bookname.get()
        aname = self.entry_author.get()
        price = self.entry_price.get()

        self.lb.delete(0,END)


        # 입력받을 데이터가 모자란지 검사
        if(len(bname) >0 and len(aname)>0 and len(price)>0 ):
            #가격에 문자를 입력했을 경우 처리
            try:
                priceI = eval(price)
            except:
                self.lb.insert(END,"you input wrong price. it must be integer")

            #사용자가 입력한 내용중 중복된 책이름이 있을 경우(저자는 책이 여러가지일 수 있으니 제외)
            rec = self.db.excute_select(bname,'')
            if ( len(rec) >0):
                self.lb.insert(END,bname +" is already in the database")
            else:
                self.db.insert_data(bname,aname,priceI) # 모든 조건 만족시 데이터 입력 수행
                r =self.db.excute_select(bname,aname)
                for rs in r:
                    self.lb.insert(END,str(rs))


        else:
            s = StringVar()
            self.entry_price.config(textvariable = s)
            self.lb.insert(END,"you have to input more values")


    #검색버튼
    def clicked_search(self):
        bname =self.entry_bookname.get()
        aname = self.entry_author.get()

        self.lb.delete(0,END)

        #책이름 또는 저자이름 둘중 하나만입력 되어도 검색 가능하도록
        if(len(bname)>0 or len(aname)>0 ):
            rec = self.db.excute_select(bname,aname)

            for r in rec:
                self.lb.insert(END,str(r))
        else:
            self.lb.insert(END,"you have to input more values(bookname or author")

    #삭제 버튼
    def clicked_delete(self):
        self.lb.delete(0,END)
        q = self.db.excute_delete(self.delete)
        self.lb.insert(END,q+' is delete from database')
class MarkovDemo(Frame):

    "MarkovDemo(master=None, **kw) -> MarkovDemo instance"

    TEXT = dict(height=2, width=46, wrap=WORD)  # Text Options
    GRID = dict(padx=5, pady=5)  # Grid Options

    # Initialize a MarkovDemo instance with a GUI for interaction.

    def __init__(self, master=None, **kw):
        "Initialize the MarkovDemo instance's widgets and settings."
        super().__init__(master, **kw)
        self.build_widgets()
        self.place_widgets()
        self.setup_widgets()
        self.grid_rowconfigure(2, weight=1)
        self.grid_rowconfigure(3, weight=1)
        self.grid_columnconfigure(0, weight=1)
        self.key = self.primer = None

    def build_widgets(self):
        "Build the various widgets that will be used in the program."
        # Create processing frame widgets.
        self.processing_frame = LabelFrame(self, text='Processing Mode:')
        self.mode_var = StringVar(self, 'encode')
        self.decode_button = Radiobutton(self.processing_frame,
                                         text='Decode Cipher-Text',
                                         command=self.handle_radiobuttons,
                                         value='decode',
                                         variable=self.mode_var)
        self.encode_button = Radiobutton(self.processing_frame,
                                         text='Encode Plain-Text',
                                         command=self.handle_radiobuttons,
                                         value='encode',
                                         variable=self.mode_var)
        self.freeze_var = BooleanVar(self, False)
        self.freeze_button = Checkbutton(self.processing_frame,
                                         text='Freeze Key & Primer',
                                         command=self.handle_checkbutton,
                                         offvalue=False,
                                         onvalue=True,
                                         variable=self.freeze_var)
        # Create encoding frame widgets.
        self.encoding_frame = LabelFrame(self, text='Encoding Options:')
        self.chain_size_label = Label(self.encoding_frame, text='Chain Size:')
        self.chain_size_entry = Entry(self.encoding_frame)
        self.plain_text_label = Label(self.encoding_frame, text='Plain-Text:')
        self.plain_text_entry = Entry(self.encoding_frame)
        # Create input frame widgets.
        self.input_frame = LabelFrame(self, text='Input Area:')
        self.input_text = ScrolledText(self.input_frame, **self.TEXT)
        # Create output frame widgets.
        self.output_frame = LabelFrame(self, text='Output Area:')
        self.output_text = ScrolledText(self.output_frame, **self.TEXT)

    def place_widgets(self):
        "Place the widgets where they belong in the MarkovDemo frame."
        # Locate processing frame widgets.
        self.processing_frame.grid(sticky=EW, **self.GRID)
        self.decode_button.grid(row=0, column=0, **self.GRID)
        self.encode_button.grid(row=0, column=1, **self.GRID)
        self.freeze_button.grid(row=0, column=2, **self.GRID)
        # Locate encoding frame widgets.
        self.encoding_frame.grid(sticky=EW, **self.GRID)
        self.chain_size_label.grid(row=0, column=0, sticky=W, **self.GRID)
        self.chain_size_entry.grid(row=0, column=1, sticky=EW, **self.GRID)
        self.plain_text_label.grid(row=1, column=0, sticky=W, **self.GRID)
        self.plain_text_entry.grid(row=1, column=1, sticky=EW, **self.GRID)
        self.encoding_frame.grid_columnconfigure(1, weight=1)
        # Locate input frame widgets.
        self.input_frame.grid(sticky=NSEW, **self.GRID)
        self.input_text.grid(sticky=NSEW, **self.GRID)
        self.input_frame.grid_rowconfigure(0, weight=1)
        self.input_frame.grid_columnconfigure(0, weight=1)
        # Locate output frame widgets.
        self.output_frame.grid(sticky=NSEW, **self.GRID)
        self.output_text.grid(sticky=NSEW, **self.GRID)
        self.output_frame.grid_rowconfigure(0, weight=1)
        self.output_frame.grid_columnconfigure(0, weight=1)

    def setup_widgets(self):
        "Setup each widget's configuration for the events they handle."
        self.input_text.bind('<Key>', self.handle_key_events)
        self.input_text.bind('<Control-Key-a>', self.handle_control_a)
        self.input_text.bind('<Control-Key-/>', lambda event: 'break')
        self.output_text['state'] = DISABLED
        self.output_text.bind('<Control-Key-a>', self.handle_control_a)
        self.output_text.bind('<Control-Key-/>', lambda event: 'break')

    ########################################################################

    # Take care of any special event needing dedicated processing.

    def handle_radiobuttons(self):
        "Change the interface based on the encoding / decoding setting."
        if self.encrypting:
            self.freeze_button.grid()
            if not self.freeze_var.get():
                self.encoding_frame.grid()
        else:
            self.freeze_button.grid_remove()
            if not self.freeze_var.get():
                self.encoding_frame.grid_remove()
        self.handle_key_events(None)

    def handle_checkbutton(self):
        "Change the interface based on the key / primer freeze setting."
        if self.freeze_var.get():
            self.encoding_frame.grid_remove()
        else:
            self.encoding_frame.grid()

    def handle_key_events(self, event):
        "Schedule refreshing the output area after an input area event."
        if event is None or event.char and event.state | 0o11 == 0o11:
            self.after_idle(self.refresh)

    @staticmethod
    def handle_control_a(event):
        "Select all text in the widget associated with the given event."
        event.widget.tag_add(SEL, 1.0, END + '-1c')
        return 'break'

    ########################################################################

    # Handle interface's updates when either encoding or decoding.

    def refresh(self):
        "Refresh the output based on the value of the input."
        text = self.input_text.get(1.0, END + '-1c')
        if not text:
            self.output = text
        elif self.encrypting:
            self.encode(text)
        else:
            self.decode(text)

    def output(self, value):
        "Set the text in the output area to the string value."
        self.output_text['state'] = NORMAL
        self.output_text.delete(1.0, END)
        self.output_text.insert(END, value)
        if self.encrypting and self.freeze_var.get():
            self.output_text.see(END)
        self.output_text['state'] = DISABLED

    output = property(fset=output, doc='Output area property.')

    @property
    def chain_size(self):
        "Chain size for the Markov chains used when encrypting."
        try:
            value = ast.literal_eval(self.chain_size_entry.get())
            assert isinstance(value, int) and 2 <= value <= 256
            return value
        except:
            self.chain_size_entry.delete(0, END)
            self.chain_size_entry.insert(0, '2')
            return 2

    @property
    def plain_text(self):
        "Plain text or ignored characters in encryption process."
        try:
            value = self.repr_to_obj(self.plain_text_entry.get(), '')
            assert isinstance(value, str)
            return value
        except:
            self.plain_text_entry.delete(0, END)
            return ''

    ########################################################################

    # Encrypt a string for display in the interface's output area.

    def encode(self, string):
        "Encode the string and show the cipher-text in the output."
        try:
            cipher = self.build_cipher(string)
        except ValueError:
            self.output = ''
        except:
            self.output = traceback.format_exc()
        else:
            self.output = self.build_header() + '\n\n' + cipher

    def build_cipher(self, string):
        "Build cipher-text based on plain-text and return answer."
        if self.key and self.freeze_var.get():
            cipher, primer = me.encrypt_str(string, self.key, self.primer)
        else:
            args = string, self.chain_size, self.plain_text
            cipher, self.key, self.primer = me.auto_encrypt_str(*args)
        return cipher

    def build_header(self):
        "Build header from key and primer values in current use."
        header = '\n'.join(map(self.bytes_to_repr, self.key.data))
        header += '\n' + self.bytes_to_repr(self.primer.data)
        return header

    ########################################################################

    # Decrypt a string for display in the interface's output area.

    def decode(self, string):
        "Decode encrypted message and display plain-text in output."
        try:
            cipher = self.extract_keys(string)
            text = self.extract_text(cipher)
        except ValueError:
            self.output = ''
        except:
            self.output = traceback.format_exc()
        else:
            self.output = text

    def extract_keys(self, string):
        "Extract keys to decryption and return the cipher-text area."
        header, cipher = string.split('\n\n', 1)
        *key, primer = map(self.repr_to_obj, header.split('\n'))
        self.key, self.primer = me.Key(tuple(key)), me.Primer(primer)
        return cipher

    def extract_text(self, string):
        "Extract text message from string using built key and primer."
        text, primer = me.decrypt_str(string, self.key, self.primer)
        return text

    ########################################################################

    # Provide some special methods to simplify the program's code.

    @property
    def encrypting(self):
        "Encrypting boolean stating current operations mode."
        return {'encode': True, 'decode': False}[self.mode_var.get()]

    @staticmethod
    def bytes_to_repr(obj):
        "Convert bytes object into suitable representation."
        if not isinstance(obj, bytes):
            raise TypeError('Object must be a bytes instance!')
        return repr(obj)[2:-1]

    @staticmethod
    def repr_to_obj(string, prefix='b'):
        "Convert representation into an equivalent object."
        for template in '{}"{}"', "{}'{}'":
            try:
                return ast.literal_eval(template.format(prefix, string))
            except:
                pass
        raise ValueError('Cannot convert {!r} to object!'.format(string))

    @classmethod
    def main(cls):
        "Create context for demo and run a test instance."
        NoDefaultRoot()
        root = Tk()
        root.minsize(420, 330)
        root.title('Markov Demo 2')
        test = cls(root)
        test.grid(sticky=NSEW)
        root.grid_rowconfigure(0, weight=1)
        root.grid_columnconfigure(0, weight=1)
        root.mainloop()
Пример #22
0
class HelpSource(Query):
    "Get menu name and help source for Help menu."

    # Used in ConfigDialog.HelpListItemAdd/Edit, (941/9)

    def __init__(self,
                 parent,
                 title,
                 *,
                 menuitem='',
                 filepath='',
                 used_names={},
                 _htest=False,
                 _utest=False):
        """Get menu entry and url/local file for Additional Help.

        User enters a name for the Help resource and a web url or file
        name. The user can browse for the file.
        """
        self.filepath = filepath
        message = 'Name for item on Help menu:'
        super().__init__(parent,
                         title,
                         message,
                         text0=menuitem,
                         used_names=used_names,
                         _htest=_htest,
                         _utest=_utest)

    def create_widgets(self):
        super().create_widgets()
        frame = self.frame
        pathlabel = Label(frame,
                          anchor='w',
                          justify='left',
                          text='Help File Path: Enter URL or browse for file')
        self.pathvar = StringVar(self, self.filepath)
        self.path = Entry(frame, textvariable=self.pathvar, width=40)
        browse = Button(frame,
                        text='Browse',
                        width=8,
                        command=self.browse_file)
        self.path_error = Label(frame,
                                text=' ',
                                foreground='red',
                                font=self.error_font)

        pathlabel.grid(column=0,
                       row=10,
                       columnspan=3,
                       padx=5,
                       pady=[10, 0],
                       sticky=W)
        self.path.grid(column=0,
                       row=11,
                       columnspan=2,
                       padx=5,
                       sticky=W + E,
                       pady=[10, 0])
        browse.grid(column=2, row=11, padx=5, sticky=W + S)
        self.path_error.grid(column=0,
                             row=12,
                             columnspan=3,
                             padx=5,
                             sticky=W + E)

    def askfilename(self, filetypes, initdir, initfile):  # htest #
        # Extracted from browse_file so can mock for unittests.
        # Cannot unittest as cannot simulate button clicks.
        # Test by running htest, such as by running this file.
        return filedialog.Open(parent=self, filetypes=filetypes)\
               .show(initialdir=initdir, initialfile=initfile)

    def browse_file(self):
        filetypes = [("HTML Files", "*.htm *.html", "TEXT"),
                     ("PDF Files", "*.pdf", "TEXT"),
                     ("Windows Help Files", "*.chm"),
                     ("Text Files", "*.txt", "TEXT"), ("All Files", "*")]
        path = self.pathvar.get()
        if path:
            dir, base = os.path.split(path)
        else:
            base = None
            if platform[:3] == 'win':
                dir = os.path.join(os.path.dirname(executable), 'Doc')
                if not os.path.isdir(dir):
                    dir = os.getcwd()
            else:
                dir = os.getcwd()
        file = self.askfilename(filetypes, dir, base)
        if file:
            self.pathvar.set(file)

    item_ok = SectionName.entry_ok  # localize for test override

    def path_ok(self):
        "Simple validity check for menu file path"
        path = self.path.get().strip()
        if not path:  #no path specified
            self.showerror('no help file path specified.', self.path_error)
            return None
        elif not path.startswith(('www.', 'http')):
            if path[:5] == 'file:':
                path = path[5:]
            if not os.path.exists(path):
                self.showerror('help file path does not exist.',
                               self.path_error)
                return None
            if platform == 'darwin':  # for Mac Safari
                path = "file://" + path
        return path

    def entry_ok(self):
        "Return apparently valid (name, path) or None"
        self.entry_error['text'] = ''
        self.path_error['text'] = ''
        name = self.item_ok()
        path = self.path_ok()
        return None if name is None or path is None else (name, path)
Пример #23
0
class HostFrame(Frame):
    def __init__(self, master):
        super(HostFrame, self).__init__(master)
        self.root = master

        # get any previous data on last.json
        previous_data = read_write.read_last()

        # Three frames will hold the widgets
        label_frm = Frame(self)  # this will hold the labels
        label_frm.grid(row=0, pady=10, padx=50)
        button_frm = Frame(self)  # this will hold the buttons
        button_frm.grid(row=1, pady=5, padx=50)
        self.hosts_frm = Frame(self)  # this will hold the previous hosts
        self.hosts_frm.grid(row=2, pady=5, padx=50)
        self.hosts_frm.grid_remove(
        )  # but we need to show it, only if user wants

        # Build the widgets for label_frm
        Label(label_frm, text="Host:").grid(column=2, row=0, pady=10, padx=5)
        Label(label_frm, text="Port:").grid(column=2, row=1, padx=5)
        self.host_entry = Entry(label_frm, width=30)
        self.host_entry.grid(column=3, row=0, pady=10)
        self.port_entry = Entry(label_frm, width=30)
        self.port_entry.grid(column=3, row=1)

        # Add data to entries if any data on last.json
        try:
            if previous_data["host"] is not "":
                self.host_entry.insert(0, previous_data["host"])
                self.port_entry.insert(0, previous_data["port"])
        except KeyError as e:
            message = "[ERROR] (frames.HostFrame): KeyError: " + str(e)
            read_write.log_message(message)

        # Build the widgets for button_frm
        self.next_btn = Button(button_frm, text="Next")
        self.next_btn.grid(column=2, row=0, pady=10, padx=4, ipadx=2, ipady=2)
        self.exit_btn = Button(button_frm,
                               text="Exit",
                               command=self.root.destroy)
        self.exit_btn.grid(column=4, row=0, pady=10, padx=4, ipadx=2, ipady=2)
        self.show_previous_btn = Button(button_frm,
                                        text="Show previous hosts",
                                        command=self.show_hosts)
        self.show_previous_btn.grid(column=2,
                                    row=1,
                                    columnspan=3,
                                    ipadx=2,
                                    ipady=2)

        # Build the widgets for hosts_frm
        def select_host():
            selected_data = str(var.get()).split(":")
            self.host_entry.delete(0, "end")
            self.host_entry.insert(0, selected_data[0])
            self.port_entry.delete(0, "end")
            self.port_entry.insert(0, selected_data[1])

        # populate the hosts_frm with Radio-buttons that show previous connections
        data = read_write.read_mongo()

        var = StringVar()
        counter = 0  # this will show in which row each radio-button will be on the frame
        for json_object in data:
            if json_object["host"] is not "":
                option = json_object["host"] + ":" + str(
                    json_object["port"])  # format host:port
                r = Radiobutton(self.hosts_frm,
                                text=option,
                                variable=var,
                                value=option,
                                command=select_host)
                r.grid(row=counter, column=2, pady=2)
                counter += 1

    # these 2 methods, will show or hide the populated hosts on hosts_frm radio-buttons
    def show_hosts(self):
        self.show_previous_btn.config(command=self.hide_hosts,
                                      text="Hide previous hosts")
        self.hosts_frm.grid()

    def hide_hosts(self):
        self.show_previous_btn.config(command=self.show_hosts,
                                      text="Show previous hosts")
        self.hosts_frm.grid_remove()
Пример #24
0
class MainWindow(mp.Process):
    """Defines the main control window and all its control logic.

    As Tkinter only allows to create root windwo (Tk()) in the main process, this is implemented as its own
    subprocess that will open the window with a call to self.run()

    Args:
        connector_dict: Dictionary create by calling multiprocessing.Manger().dict()
        message_q: Queue that will be polled every few seconds. Elements in queue will be plotted to the internal
            text field.
        start_analysis_e: Event signaling if analysis can be started
        connected_e: Event signaling that LSL streams are connected
        ready_for_connection_e: Event signaling that LSL streams have been selected in GUI
        save_e: Event signaling that data should be saved.

    """
    def __init__(self, connector_dict: Dict, message_q: mp.Queue,
                 start_recording_e: mp.Event, start_analysis_e: mp.Event,
                 connected_e: mp.Event, ready_for_connection_e: mp.Event,
                 save_e: mp.Event):
        super().__init__()
        self.connector_dict = connector_dict
        self.message_q = message_q
        self.start_recording_e = start_recording_e
        self.start_analysis_e = start_analysis_e
        self.ready_for_connection_e = ready_for_connection_e
        self.connected_e = connected_e
        self.save_e = save_e

        self.master = None

        # Parameters
        self.eeg_stream = None
        self.eeg_streams_dict = None
        self.marker_stream = None
        self.marker_streams_dict = None
        self.channel_select = None
        self.update_interval = None
        self.record_time = None
        self.y_min = None
        self.y_max = None
        self.save_filename = None
        self.filter_check = None
        self.squared_check = None
        self.connected = None

        # Widgets
        self.eeg_stream_label = None
        self.eeg_stream_combobox = None
        self.eeg_stream_button = None
        self.marker_stream_label = None
        self.marker_stream_combobox = None
        self.marker_stream_button = None
        self.filter_checkbutton_label = None
        self.filter_checkbutton = None
        self.connect_button = None
        self.seperator = None
        self.start_recording_btn = None
        self.record_time_label = None
        self.Separator_2 = None
        self.update_interval_label = None
        self.update_interval_combobox = None
        self.start_analysis_btn = None
        self.channel_select_label = None
        self.channel_select_combobox = None
        self.squared_label = None
        self.squared_checkbtn = None
        self.update_ylim_btn = None
        self.y_min_label = None
        self.y_min_entry = None
        self.y_max_label = None
        self.y_max_entry = None
        self.seperator = None
        self.save_label = None
        self.save_entry = None
        self.save_btn = None
        self.text_console = None

    def build_main_window(self):
        # Hack to make tkinter work in other process than main
        from tkinter import Tk, StringVar, Text, HORIZONTAL, EW, IntVar
        from tkinter.ttk import Separator, Combobox, Button, Label, Entry, Checkbutton

        self.master = Tk()

        # Parameters
        self.eeg_stream = StringVar()
        self.eeg_streams_dict = {}
        self.marker_stream = StringVar()
        self.marker_streams_dict = {}
        self.channel_select = IntVar()
        self.channel_select.set(0)
        self.update_interval = IntVar()
        self.update_interval.set(0)
        self.record_time = StringVar()
        self.record_time.set("00:00 minutes recorded")
        self.y_min = IntVar()
        self.y_min.set(-10)
        self.y_max = IntVar()
        self.y_max.set(10)
        self.save_filename = StringVar()
        self.save_filename.set("1")
        self.filter_check = IntVar()
        self.filter_check.set(1)
        self.squared_check = IntVar()
        self.squared_check.set(0)

        self.connected = False

        self.print_from_queue()

        # Widgets
        self.eeg_stream_label = Label(self.master, text='EEG LSL-stream:')
        self.eeg_stream_label.grid(row=0, column=0)

        self.eeg_stream_combobox = Combobox(self.master,
                                            textvariable=self.eeg_stream)
        self.eeg_stream_combobox.configure(state='disabled')
        self.eeg_stream_combobox.grid(row=0, column=1)

        self.eeg_stream_button = Button(
            self.master,
            text='Refresh',
            command=lambda: self.find_streams('EEG', self.eeg_stream_combobox,
                                              self.eeg_streams_dict, self.
                                              eeg_stream))
        self.eeg_stream_button.grid(row=0, column=2)

        self.marker_stream_label = Label(self.master,
                                         text='Marker LSL-stream:')
        self.marker_stream_label.grid(row=1, column=0)

        self.marker_stream_combobox = Combobox(self.master,
                                               textvariable=self.marker_stream)
        self.marker_stream_combobox.configure(state='disabled')
        self.marker_stream_combobox.grid(row=1, column=1)

        self.marker_stream_button = Button(
            self.master,
            text='Refresh',
            command=lambda: self.find_streams(
                'P300_Marker', self.marker_stream_combobox, self.
                marker_streams_dict, self.marker_stream))
        self.marker_stream_button.grid(row=1, column=2)

        self.filter_checkbutton_label = Label(
            self.master, text='Filter (Butter, Order 4, Cutoff: 1, 30):')
        self.filter_checkbutton_label.grid(row=2, column=0)

        self.filter_checkbutton = Checkbutton(self.master,
                                              variable=self.filter_check,
                                              text='')
        self.filter_checkbutton.grid(row=2, column=1)

        self.connect_button = Button(self.master,
                                     text='Connect',
                                     command=self.connect_streams)
        self.connect_button.grid(row=2, column=2)
        self.connect_button.configure(state='disabled')

        self.seperator = Separator(self.master, orient=HORIZONTAL)
        self.seperator.grid(row=3, column=0, columnspan=3, sticky=EW)

        self.start_recording_btn = Button(self.master,
                                          text='Start recoding',
                                          command=self.start_recording)
        self.start_recording_btn.grid(row=4, column=2)
        self.start_recording_btn.configure(state='disabled')

        self.record_time_label = Label(self.master,
                                       textvariable=self.record_time)
        self.record_time_label.grid(row=4, column=1)

        self.Separator_2 = Separator(self.master)
        self.Separator_2.grid(row=5, column=0, columnspan=3, sticky=EW)

        self.update_interval_label = Label(self.master,
                                           text='Update interval (seconds):')
        self.update_interval_label.grid(row=6, column=0)

        self.update_interval_combobox = Combobox(
            self.master, textvariable=self.update_interval)
        self.update_interval_combobox.bind('<<ComboboxSelected>>',
                                           self.update_connector_dict)
        self.update_interval_combobox.grid(row=6, column=1)
        self.update_interval_combobox['values'] = list(range(10))
        self.update_interval_combobox.configure(state='disabled')

        self.start_analysis_btn = Button(self.master,
                                         text='Start analysis',
                                         command=self.start_analysis)
        self.start_analysis_btn.grid(row=6, column=2)
        self.start_analysis_btn.configure(state='disabled')

        self.channel_select_label = Label(self.master,
                                          text='Channel to display:')
        self.channel_select_label.grid(row=7, column=0)

        self.channel_select_combobox = Combobox(
            self.master, textvariable=self.channel_select)
        self.channel_select_combobox.bind('<<ComboboxSelected>>',
                                          self.update_connector_dict)
        self.channel_select_combobox.grid(row=7, column=1)
        self.channel_select_combobox.configure(state='disabled')

        self.squared_label = Label(self.master, text='squared')
        self.squared_label.grid(row=8, column=0)

        self.squared_checkbtn = Checkbutton(self.master,
                                            variable=self.squared_check)
        self.squared_checkbtn.grid(row=8, column=1)
        self.squared_checkbtn.configure(state='disabled')

        self.update_ylim_btn = Button(self.master,
                                      text='Update',
                                      command=self.update_connector_dict)
        self.update_ylim_btn.grid(row=8, column=2)
        self.update_ylim_btn.configure(state='disabled')

        self.y_min_label = Label(self.master, text='Y min:')
        self.y_min_label.grid(row=9, column=0)

        self.y_min_entry = Entry(self.master, textvariable=self.y_min)
        self.y_min_entry.grid(row=9, column=1)
        self.y_min_entry.configure(state='disabled')

        self.y_max_label = Label(self.master, text='Y max:')
        self.y_max_label.grid(row=10, column=0)

        self.y_max_entry = Entry(self.master, textvariable=self.y_max)
        self.y_max_entry.grid(row=10, column=1)
        self.y_max_entry.configure(state='disabled')

        self.seperator = Separator(self.master, orient=HORIZONTAL)
        self.seperator.grid(row=11, column=0, columnspan=3, sticky=EW)

        self.save_label = Label(self.master, text='Filename:')
        self.save_label.grid(row=12, column=0)

        self.save_entry = Entry(self.master, textvariable=self.save_filename)
        self.save_entry.grid(row=12, column=1)
        self.save_entry.configure(state='disabled')

        self.save_btn = Button(self.master, text='Save', command=self.save)
        self.save_btn.grid(row=12, column=2)
        self.save_btn.configure(state='disabled')

        self.text_console = Text(self.master)
        self.text_console.grid(row=15, column=0, rowspan=3, columnspan=3)
        self.text_console.configure(state='disabled')

    def save(self):
        self.update_connector_dict()
        self.save_e.set()

    def update_channel_select(self):
        num_channels = self.connector_dict['number of channels']
        self.channel_select_combobox['values'] = list(range(num_channels))

    def start_recording(self):
        self.connect_button.configure(state='disabled')
        self.start_recording_btn.configure(state='disabled')
        self.channel_select_combobox.configure(state='normal')
        self.update_interval_combobox.configure(state='normal')
        self.y_min_entry.configure(state='normal')
        self.y_max_entry.configure(state='normal')
        self.update_ylim_btn.configure(state='normal')
        self.squared_checkbtn.configure(state='normal')

        self.update_channel_select()
        self.update_recording_time()

        self.start_recording_e.set()

        self.start_analysis_btn.configure(state='normal')

    def update_recording_time(self):
        num_samples = self.connector_dict['sample count']
        samplerate = self.connector_dict['samplerate']
        number_of_seconds = int(num_samples / samplerate)

        minutes = number_of_seconds // 60
        remaining_seconds = number_of_seconds % 60

        result_string = '{:02}:{:02} minutes recorded'.format(
            minutes, remaining_seconds)

        self.record_time.set(result_string)
        self.master.after(1000, self.update_recording_time)

    def start_analysis(self):
        self.start_analysis_btn.configure(state='disabled')
        self.save_btn.configure(state='normal')
        self.save_entry.configure(state='normal')

        self.update_connector_dict()
        self.start_analysis_e.set()

    def find_streams(self, stream_type, widget, stream_dict, var):
        stream_dict.clear()
        timeout = 3
        self.print_to_console('Searching for ' + stream_type +
                              ' streams... (timeout = ' + str(timeout) +
                              ' seconds)')

        streams = resolve_byprop('type', stream_type, timeout=timeout)
        if not streams:
            self.print_to_console('No stream found.')
            return

        widget.configure(state='normal')

        stream_list = []
        for stream in streams:
            stream_dict[stream.name()] = stream
            stream_list.append(stream.name())

        widget['values'] = stream_list

        if len(streams) >= 1:
            var.set(streams[0].name())

        self.print_to_console(str(len(streams)) + ' Stream(s) found!')
        self.test_if_two_streams()

    def test_if_two_streams(self):
        if self.eeg_stream.get() is not '' and self.marker_stream.get(
        ) is not '':
            self.connect_button.configure(state='normal')
        else:
            self.connect_button.configure(state='disabled')

    def print_to_console(self, text_to_print):
        text_to_print = str(text_to_print)

        self.text_console.configure(state='normal')
        self.text_console.insert('end', text_to_print + '\n')
        self.text_console.configure(state='disabled')

    def print_from_queue(self):
        if not self.message_q.empty():
            self.print_to_console(self.message_q.get())
        self.master.after(500, self.print_from_queue)

    # noinspection PyUnusedLocal
    def update_connector_dict(self, event=None):
        self.connector_dict['update interval'] = self.update_interval.get()
        self.connector_dict['channel select'] = self.channel_select.get()
        self.connector_dict['eeg streamname'] = self.eeg_stream.get()
        self.connector_dict['marker streamname'] = self.marker_stream.get()
        self.connector_dict['y lim'] = [self.y_min.get(), self.y_max.get()]
        self.connector_dict['savefile'] = self.save_filename.get()
        self.connector_dict['filter'] = self.filter_check.get()
        self.connector_dict['squared'] = self.squared_check.get()

    def connect_streams(self):
        self.eeg_stream_combobox.configure(state='disabled')
        self.eeg_stream_button.configure(state='disabled')
        self.marker_stream_combobox.configure(state='disabled')
        self.marker_stream_button.configure(state='disabled')
        self.filter_checkbutton.configure(state='disabled')
        self.connect_button.configure(state='disabled')

        self.update_connector_dict()
        self.ready_for_connection_e.set()

        self.connected_e.wait()

        self.start_recording_btn.configure(state='normal')

    def run(self):
        self.build_main_window()
        self.master.mainloop()
Пример #25
0
def init(metrics_data: dict):
    top_window = Tk()

    # main widget properties
    top_window.geometry(f'{metrics_data["width"]}x{metrics_data["height"]}')
    top_window.iconphoto(False, PhotoImage(file=f'../{metrics_data["icon"]}'))
    top_window.configure(bg=metrics_data['background'])
    top_window.title(metrics_data['title'])

    def play(track_path: str, duration: int) -> None:
        playsound(track_path, False)
        top_window.after(duration * 1000, lambda: play(track_path, duration))

    def pick_directory():
        # TODO: set $HOME directory as default (may be in config)
        path_save = filedialog.askdirectory().strip()

        if path_save:
            input_directory.delete(0, END)
            input_directory.insert(0, path_save)

    def make_request():
        author: str = input_author.get().strip()
        path_save: str = input_directory.get().strip()

        if not author.strip():
            messagebox.showerror('🚫 Error occurred!', 'Empty string is not allowed as author\'s name.')

            return 1

        # directory to save should be present -- chosen or default
        print('author:', author)
        print('directory to save:', path_save)

        pass

    def close():
        top_window.destroy()
        top_window.quit()

    # UI
    label_guide = Label(top_window, text=metrics_data['guide'], font=('Arial Bold', 23))
    label_guide.grid(column=0, row=0, padx=(14, 5), pady=(20, 50))

    input_author = Entry(top_window, width=50)
    input_author.grid(row=8, column=0)
    input_author.focus()

    input_directory = Entry(top_window, width=50)
    input_directory.grid(row=9, column=0)

    button_choose = Button(top_window, text='Choose', command=pick_directory)
    button_choose.grid(row=9, column=1)

    Separator(orient='horizontal')

    button_go = Button(top_window, text='Go!', command=make_request)
    button_go.grid(row=10, column=0)

    top_window.protocol('WM_DELETE_WINDOW', close)
    play(f'../{metrics_data["track"]}', 83)

    top_window.mainloop()
Пример #26
0
def _gui():
  try:
    from tkinter import Tk, ttk, filedialog, messagebox, StringVar, IntVar
    from tkinter.ttk import Button, Entry, Frame, Label, LabelFrame, Notebook, Radiobutton, Style
  except:
    sys.exit("Unable to load tkinter. Aborting.")
  
  def _check_single(): #check the input and accordingly give the output... for the f_single tab
    if txt_f_single_entry.get()=="":
      lbl_f_single_result.config(text="", style="TLabel")
    elif check_afm(txt_f_single_entry.get()):
      lbl_f_single_result.config(text="Έγκυρο ΑΦΜ.", style="valid.TLabel")
    else:
      lbl_f_single_result.config(text="Άκυρο ΑΦΜ.", style="invalid.TLabel")
  
  def _select_input_file():
    strv_f_file_input.set(filedialog.askopenfilename(title="Άνοιγμα αρχείου"))
    if strv_f_file_input.get() != "" and strv_f_file_output.get() != "":
      btn_f_file_submit.config(state="normal")
    else: btn_f_file_submit.config(state="disabled")
#TODO a much better mechanism to enable / disable btn_f_file_submit is needed.
  def _select_output_file():
    strv_f_file_output.set(filedialog.asksaveasfilename(title="Αποθήκευση ως..."))
    if strv_f_file_input.get() != "" and strv_f_file_output.get() != "":
      btn_f_file_submit.config(state="normal")
    else: btn_f_file_submit.config(state="disabled")
  
  def _check_file():#TODO this could / should be merged with the TUI version...
    input_filepath = strv_f_file_input.get()
    output_filepath = strv_f_file_output.get()
    filter_output = intvar_filter_sel.get()
    try:
      input_file = open(input_filepath, "r")
      output_file = open(output_filepath, "w")
    except:
      messagebox.showerror(title="Σφάλμα", message="Αδυναμία διαχείρησης των αρχείων που ορίσατε.\n\nΠαρακαλώ επιβεβαιώστε πως το αρχείο με τα δεδομένα υπάρχει, πως έχετε δικαιώματα ανάγνωσης, και πως έχετε δικαιώματα εγγραφής στον κατάλογο εξαγωγής των αποτελεσμάτων.")
      return
    counter = {True:0, False:0}
    for entry in input_file:
      validation = check_afm(entry.strip())
      counter[validation]+=1
      if filter_output == 3 and validation == False:
        output_file.write(entry)
      elif filter_output == 2 and validation == True:
        output_file.write(entry)
      elif filter_output == 1:
        output_file.write(entry.strip() + "\t" + str(validation) + "\n\r")
    lbl_f_file_result.config(text="Σύνολο: "+str(counter[True]+counter[False])+"\nΈγκυρα: "+str(counter[True])+"\nΆκυρα: "+str(counter[False]))

  #create the window
  main_window = Tk()
  main_window.title("Έλεγχος εγκυρότητας Α.Φ.Μ. (v 2.0)")
  main_window.geometry("600x180")
  main_window.minsize(600,180)

  #fool arround with styling
  style = ttk.Style()
  style.configure("valid.TLabel", background="green")
  style.configure("empty.TLabel", background="white")
  style.configure("invalid.TLabel", background="red")
  style.configure("TNotebook", padding = 10)
  
  #create the Notebook
  tabs = Notebook(main_window)
  f_single = Frame(tabs)
  f_file = Frame(tabs)
  tabs.add(f_single, text="Μεμονομένα Α.Φ.Μ.")
  tabs.add(f_file, text="Λίστα από αρχείο")#add state="disabled" prior to git push until ready
  tabs.pack(anchor="nw")
  
  #add some widgets in f_single tab
  lbl_f_single_instructions = Label(f_single, text="Εισάγετε έναν ΑΦΜ για έλεγχο")
  lbl_f_single_instructions.grid(column=0, row=0)

  lbl_f_single_result = Label(f_single, text="", width=10, justify="center")
  lbl_f_single_result.grid(column=1, row=0, rowspan=2, sticky="ewns")

  txt_f_single_entry = Entry(f_single, width=11)
  txt_f_single_entry.focus()
  txt_f_single_entry.bind("<KeyRelease>", lambda e: _check_single() )
  txt_f_single_entry.grid(column=0,row=1)

  #btn_f_single_submit = Button(f_single, text="Έλεγχος", command=_check_single)
  #btn_f_single_submit.grid(column=0,row=2)
    
  #add some widgets in f_file tab
  lbl_f_file_finput = Label(f_file, text="Άνοιγμα...")
  lbl_f_file_finput.grid(column=0, row=0)
  strv_f_file_input = StringVar()
  txt_f_file_finput = Entry(f_file, textvariable = strv_f_file_input)
  txt_f_file_finput.grid(column=1, row=0)
  btn_f_file_finput = Button(f_file, text="...", width=3, command=_select_input_file)
  btn_f_file_finput.grid(column=2, row=0, sticky="W")
  
  lbl_f_file_foutput = Label(f_file, text="Αποθήκευση ως...")
  lbl_f_file_foutput.grid(column=0, row=1)
  strv_f_file_output = StringVar()
  txt_f_file_foutput = Entry(f_file, textvariable = strv_f_file_output)
  txt_f_file_foutput.grid(column=1, row=1)
  btn_f_file_foutput = Button(f_file, text="...", width=3, command=_select_output_file)
  btn_f_file_foutput.grid(column=2, row=1, sticky="W")
  
  lf_filter = LabelFrame(f_file, text="Επιστροφή")
  lf_filter.grid(column=3, row=0, rowspan=2, sticky="ewns")
  intvar_filter_sel = IntVar()
  rb_filter_all = Radiobutton(lf_filter, text="Όλων", variable=intvar_filter_sel, value=1) #TODO maybe add command
  rb_filter_all.pack(anchor="w")
  rb_filter_all.invoke()
  rb_filter_true = Radiobutton(lf_filter, text="Έγκυρων", variable=intvar_filter_sel, value=2)
  rb_filter_true.pack(anchor="w")
  rb_filter_false = Radiobutton(lf_filter, text="Άκυρων", variable=intvar_filter_sel, value=3)
  rb_filter_false.pack(anchor="w")
  
  lf_result = LabelFrame(f_file, text="Σύνοψη")
  lf_result.grid(column=4, row=0, rowspan=2, sticky="ewns")
  lbl_f_file_result = Label(lf_result, text="", width=12)#TODO bring results
  lbl_f_file_result.pack()
  
  btn_f_file_submit = Button(f_file, text="Επεξεργασία", state="disabled", command=_check_file)
  btn_f_file_submit.grid(column=0, row=2, columnspan=3)
  
  btn_main_exit = Button(main_window, text="Έξοδος", command=sys.exit)
  btn_main_exit.pack(anchor="se")

  main_window.mainloop()
Пример #27
0
class Example(Frame):
    def __init__(self, parent):
        Frame.__init__(self, parent, name="frame")

        self.parent = parent
        self.initUI()

    def initUI(self):

        self.parent.title("Pi computation")
        self.pack(fill=BOTH, expand=True)

        self.grid_columnconfigure(4, weight=1)
        self.grid_rowconfigure(3, weight=1)

        lbl1 = Label(self, text="Digits:")
        lbl1.grid(row=0, column=0, sticky=E, padx=10, pady=10)

        self.ent1 = Entry(self, width=10)
        self.ent1.insert(END, "4000")
        self.ent1.grid(row=0, column=1, sticky=W)

        lbl2 = Label(self, text="Accuracy:")
        lbl2.grid(row=0, column=2, sticky=E, padx=10, pady=10)

        self.ent2 = Entry(self, width=10)
        self.ent2.insert(END, "100")
        self.ent2.grid(row=0, column=3, sticky=W)

        self.startBtn = Button(self, text="Start", command=self.onStart)
        self.startBtn.grid(row=1, column=0, padx=10, pady=5, sticky=W)

        self.pbar = Progressbar(self, mode='indeterminate')
        self.pbar.grid(row=1, column=1, columnspan=3, sticky=W + E)

        self.txt = scrolledtext.ScrolledText(self)
        self.txt.grid(row=2,
                      column=0,
                      rowspan=4,
                      padx=10,
                      pady=5,
                      columnspan=5,
                      sticky=E + W + S + N)

    def onStart(self):

        self.startBtn.config(state=DISABLED)
        self.txt.delete("1.0", END)

        #self.p1 = Process(target=generatePi, args=(q, digits, accuracy))
        self.p1 = Process(target=lengthy_function)
        self.p1.start()
        self.pbar.start(DELAY2)  #20
        self.after(
            DELAY1,
            self.listen_for_results)  # after 80 ms, start checking for results

    # consumer function is in the GUI class
    def listen_for_results(self):

        # if the worker process is still running, delay a bit and check again
        if (self.p1.is_alive()):
            print('p1 is still alive')
            self.after(DELAY1, self.listen_for_results)
            return

        else:  # the worker process has finished and put the result in the queue
            print('p1 is NOT alive')
            print(f'Checking if queue.Empty(): {q.empty()}')
            print(f'Checking queue.qsize(): {q.qsize()}')
            while q.qsize() > 0:
                print('something in the queue')
                record = q.get()
                print(record)
                time.sleep(1)

            print('queue is empty')
            self.pbar.stop()
            self.startBtn.config(state=NORMAL)
            '''while True:
Пример #28
0
class GUI(object):
    '''Stellt die Oberflaeche dar.
    
    Alle steuerden Taetigkeiten werden (sollten) vom
    Controller Objekt uebernommen werden.
    '''


    def __init__(self):
        '''
        Constructor
        '''
        self.root = Tk()
        
        self.root.title("DinnerLog")
        self.root.minsize(800, 600)
        self.root.grid_columnconfigure(0, weight=1)
        self.root.grid_rowconfigure(0, weight=1)
        self.root.grid_rowconfigure(1, weight=3)
        
        # Ein Frame für alles, das mit Zutaten zu tun hat
        self.fr_zutaten = Labelframe(self.root, borderwidth=2, relief=GROOVE, text="Zutaten")
        self.fr_zutaten.grid_columnconfigure(0, weight=1)
        self.fr_zutaten.grid_rowconfigure(0, weight=1)
        self.fr_zutaten.grid(row=0, column=0, sticky="NSWE")
        

        self.lb_zutaten = Listbox(self.fr_zutaten)
        sb_zutaten = Scrollbar(self.lb_zutaten, orient=VERTICAL)
        self.lb_zutaten.configure(yscrollcommand=sb_zutaten.set)
        sb_zutaten.config(command=self.lb_zutaten.yview)
        sb_zutaten.pack(side="right", fill="both")
        self.lb_zutaten.grid(row=0, column=0, sticky="NSEW")
        
        self._addNeueZutatFrame()    

        # Ein Frame in den alles, das mit Mahlzeiten zu tun hat, kommt
        self.fr_mahlzeit = Labelframe(self.root, borderwidth=2, relief=GROOVE, text="Mahlzeiten")
        self.fr_mahlzeit.grid_columnconfigure(0, weight=1)
        self.fr_mahlzeit.grid_rowconfigure(0, weight=1)
        self.fr_mahlzeit.grid(row=1, column=0, sticky="NSWE")
        
        self._addNeueMahlzeitFrame()
        

        self.lb_mahlzeiten = Listbox(self.fr_mahlzeit, selectmode=SINGLE)
        sb_mahlzeiten = Scrollbar(self.lb_mahlzeiten, orient=VERTICAL)
        sb_mahlzeiten.configure(command=self.lb_mahlzeiten.yview)
        self.lb_mahlzeiten.configure(yscrollcommand=sb_mahlzeiten.set)
        sb_mahlzeiten.pack(side="right", fill="both")
        self.lb_mahlzeiten.grid(row=0, column=0, sticky="NSEW")
        
        fr_neu_ok = Frame(self.fr_mahlzeit)
        fr_neu_ok.grid(row=1, column=0, columnspan=2, sticky="E")
    
        self.btn_neu = Button(fr_neu_ok, text="Neu")
        self.btn_neu.pack(side="left")
        
        self.btn_mahlzeit_als_zt = Button(fr_neu_ok, text="Als Zutat")
        self.btn_mahlzeit_als_zt.pack(anchor=E, side="right")
        
        self.btn_insert = Button(fr_neu_ok, text="Hinzufuegen")
        self.btn_insert.pack(anchor=E, side="right")
        
        self.btn_update = Button(fr_neu_ok, text="Update")
        self.btn_update.pack(anchor=E, side="right")
        
        self.btn_delete = Button(fr_neu_ok, text="Loeschen")
        self.btn_delete.pack(anchor=E, side="right")
        
        # Ein Frame der Statistiken darstellt
        self.fr_stats = Labelframe(self.root, borderwidth=2, relief=GROOVE, text="Statistik")
        self.fr_stats.grid(row=3, column=0, sticky="NSWE")

        #self.cv_stats = Canvas(self.fr_stats, height=80, width=600)
        #self.cv_stats.create_line(2,5,598,5, fill="#bbb")
        
    def _addNeueMahlzeitFrame(self):
        self.fr_neue_mz = Frame(self.fr_mahlzeit)
        self.fr_neue_mz.grid_rowconfigure(2, weight=1)
        self.fr_neue_mz.grid(row=0, column=1, sticky="WSNE")
        
        lbl_name = Label(self.fr_neue_mz, text="Name:")
        lbl_name.grid(row=0, column=0, sticky="NW")
        
        self.en_name = Entry(self.fr_neue_mz)
        self.en_name.grid(row=0, column=1, columnspan=2, sticky="WNE")
        
        lbl_zutat = Label(self.fr_neue_mz, text="Zutaten:")
        lbl_zutat.grid(row=1, column=0, sticky="NW")
        

        self.lb_zutat = Listbox(self.fr_neue_mz)
        sb_zutat = Scrollbar(self.lb_zutat, orient=VERTICAL)
        self.lb_zutat.configure(yscrollcommand=sb_zutat.set)
        sb_zutat.configure(command=self.lb_zutat.yview)
        sb_zutat.pack(side="right", fill="both")
        self.lb_zutat.grid(row=2, column=0, columnspan=3, sticky="NWSE")
        
        self.var_zutat = StringVar(self.fr_neue_mz)
        
        self.opt_zutat = OptionMenu(self.fr_neue_mz, self.var_zutat, "Auswahl")
        self.opt_zutat.grid(row=3, column=0)
        
        self.en_menge = Entry(self.fr_neue_mz)
        self.en_menge.grid(row=3, column=1)
        
        self.btn_mahlzeit_hinzu = Button(self.fr_neue_mz, text="Hinzu")
        self.btn_mahlzeit_hinzu.grid(row=3, column=2, sticky="E")
        
    def _addNeueZutatFrame(self):
        fr_neue_zt = Frame(self.fr_zutaten)
        fr_neue_zt.grid(row=0, column=2,sticky="NWSE")
        
        lbl_name = Label(fr_neue_zt, text="Name:")
        lbl_name.grid(row=0, column=0, sticky="W")
        
        self.en_name_zt = Entry(fr_neue_zt)
        self.en_name_zt.grid(row=0, column=1, columnspan=2, sticky="WE")
        
        lbl_fett = Label(fr_neue_zt, text="Fett:")
        lbl_fett.grid(row=1, column=0, sticky="W")        
        
        self.en_fett = Entry(fr_neue_zt)
        self.en_fett.grid(row=1, column=1, columnspan=2)
        
        lbl_eiweiss = Label(fr_neue_zt, text="Eiweiss:")
        lbl_eiweiss.grid(row=2, column=0, sticky="W")        
        
        self.en_eiweiss = Entry(fr_neue_zt)
        self.en_eiweiss.grid(row=2, column=1, columnspan=2)
        
        lbl_kh = Label(fr_neue_zt, text="Kohlenhy.:")
        lbl_kh.grid(row=3, column=0, sticky="W")        
        
        self.en_kh = Entry(fr_neue_zt)
        self.en_kh.grid(row=3, column=1, columnspan=2)
        
        self.btn_zutat_insert = Button(fr_neue_zt, text="Hinzu")
        self.btn_zutat_insert.grid(row=4, column=1, sticky="E")
        
        self.btn_zutat_update = Button(fr_neue_zt, text="Update")
        self.btn_zutat_update.grid(row=5, column=1, sticky="E")
        
        self.btn_zutat_delete = Button(fr_neue_zt, text="Loeschen")
        self.btn_zutat_delete.grid(row=6, column=1, sticky="E")
Пример #29
0
    def init_ui(self):  # pylint: disable=R0915
        """
        Initialize the UI widgets. Refactored to separate method,
        since the tkroot UI might be required before
        information on the widgets are available.
         ------------------------------------
        | GEL file:  |____________| |Browse| |
        | Lane file: |____________| |Browse| |
        | YAML file: |____________| |Browse| | << fileinfo frame, column=0, row=0
         ------------------------------------
        |          |  ANNOTATE!  |           | << button frame, column=0, row=0
         ------------------------------------
        | Lane names:     | YAML config:     |
        |  -------------  |  --------------  | << text input frame
        | |             | | |              | |
        | |             | | |              | | << lanenames frame
        | |             | | |              | | << yaml frame
        | |             | | |              | |
        | |             | | |              | |
        |  -------------  |  --------------  |
         ------------------------------------


Non-used:

        |  |Save|  |Load| |  |Save|  |Load|  |
        |  Autosave |_|   |  Autosave |_|    |

        |  _________   __________   ______   |
        | |OK (Keep)| |OK (Clear)| |Cancel|  | << buttonbox frame
        |  ¨¨¨¨¨¨¨¨¨   ¨¨¨¨¨¨¨¨¨¨   ¨¨¨¨¨¨   |
         ------------------------------------
        |  Shift-enter=Annotate,             |
        |  Added entry: "<product name>"     | << Info frame
        |  View page in browser              |
         ------------------------------------
        """

        # .grid column defaults to 0 and row defaults to the first unused row in the grid.

        # Make sure mainframe expands:
        self.columnconfigure(0, weight=1)
        self.rowconfigure(0, weight=1)

        # MAINFRAME:
        mainframe = Frame(self)
        mainframe.grid(sticky='news', row=0, column=0)          # Defaults to 0
        mainframe.columnconfigure(0, weight=1)
        mainframe.rowconfigure(2, weight=1)     # Row 2 is textinput frame
        mainframe.rowconfigure(1, minsize=40)   # Button frame.

        # FILE FRAME - has filenames/paths:
        fileframe = Frame(mainframe)
        fileframe.grid(sticky='news', row=0, column=0)           # All vertical frames are placed implicitly
        fileframe.columnconfigure(1, weight=1, minsize=30)

        # Filepath labels:
        lbl = Label(fileframe, text="Directory: ")
        lbl.grid(sticky='w', row=0, column=0)
        lbl = Label(fileframe, text="Gel file: ")
        lbl.grid(sticky='w', row=1, column=0)
        lbl = Label(fileframe, text="Lane file:")
        lbl.grid(sticky='w', row=2, column=0)
        lbl = Label(fileframe, text="Yaml file:")
        lbl.grid(sticky='w', row=3, column=0)
        # self.GelfileEntry = entry = Entry(fileframe, textvariable=self.Gelfilepath)
        # How to make the right-most text visible? , justify='right' does not have the desired effect...

        # Filepath entries:
        entry = Entry(fileframe, textvariable=self.Gelfiledirectory, state='readonly')
        entry.grid(row=0, column=1, sticky='ew')
        entry = Entry(fileframe, textvariable=self.Gelfilepath)     # = self.GelfilepathEntry
        entry.grid(row=1, column=1, sticky='ew')
        entry = Entry(fileframe, textvariable=self.Annotationsfilepath)
        entry.grid(row=2, column=1, sticky='ew')
        entry = Entry(fileframe, textvariable=self.Yamlfilepath)
        entry.grid(row=3, column=1, sticky='ew')

        # BROWSE buttons:
        btn = Button(fileframe, text='Help...', command=self.App.show_help)
        btn.grid(row=0, column=2)
        btn = Button(fileframe, text='Browse', command=self.App.browse_for_gelfile)
        btn.grid(row=1, column=2)
        btn = Button(fileframe, text='Browse', command=self.App.browse_for_annotationsfile)
        btn.grid(row=2, column=2)
        btn = Button(fileframe, text='Browse', command=self.App.browse_for_yamlfile)
        btn.grid(row=3, column=2)

        # BUTTON FRAME:
        buttonframe = Frame(mainframe)
        buttonframe.grid(sticky='news', column=0, row=1)
        btn = self.AnnotateBtn = Button(buttonframe, text="ANNOTATE!", command=self.App.annotate)
        btn.grid(sticky='news', row=1, column=2)
        buttonframe.rowconfigure(1, minsize=40)  # mainframe row 1 must also be set to minsize.
        buttonframe.columnconfigure(2, weight=2)
        buttonframe.columnconfigure((1, 3), weight=1)
        # self.ProcessBtn = btn = Button(fileframe, text="Process!")
        # btn.grid(row=3, column=1, columnspan=2, sticky='news')

        # Outer textinputs FRAME - Contains both annotationsframe and yamlframe. ###
        textinput = Frame(mainframe)     # Specify starting width and height
        textinput.grid(sticky="news", column=0, row=2)  # Make sure it expands
        textinput.rowconfigure(0, weight=1)             # Make sure it expands vertically
        textinput.columnconfigure((0, 1), weight=1)

        def loose_focus(event=None):
            self.AnnotateBtn.focus_set()

        def dont_propagate(event=None):
            # prevent Tkinter from propagating the event by returning the string "break"
            print("dont_propagate called...")
            return "break"

        self.bind_all("<Escape>", loose_focus)

        # ANNOTATIONS FRAME:
        annotationsframe = Frame(textinput, borderwidth=1)
        annotationsframe.grid(sticky='news', column=0, row=0)
        annotationsframe.rowconfigure(1, weight=1)             # row 1 column 0 has text input
        annotationsframe.columnconfigure(0, weight=1)
        lbl = Label(annotationsframe, text="Lane annotations file:")
        lbl.grid(sticky='w', column=0, row=0)
        # undo ref: http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/text-undo-stack.html
        # http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/text.html
        # default: width=80, height=24   # pylint: disable=W0201
        text = self.AnnotationsText = Text(annotationsframe, width=40, height=20, undo=True, maxundo=-1)
        text.grid(sticky='news', column=0, row=1)
        text.bind(sequence='<Control-s>', func=self.App.save_annotations)
        # text.bind("<Control-Return>", dont_propagate)
        # More cheat-sheet: http://stackoverflow.com/questions/16082243/how-to-bind-ctrl-in-python-tkinter

        # YAML FRAME:
        yamlframe = Frame(textinput, borderwidth=1)
        yamlframe.grid(sticky='news', column=1, row=0)
        yamlframe.rowconfigure(1, weight=1)             # row 1 has text input
        yamlframe.columnconfigure(0, weight=1)
        lbl = Label(yamlframe, text="Yaml (config) file:")
        lbl.grid(sticky='w', column=0, row=0)
        text = self.YamlText = Text(yamlframe, width=40, height=30, undo=True, maxundo=-1)  # pylint: disable=W0201
        text.grid(sticky='news', column=0, row=1)
        text.bind(sequence='<Control-s>', func=self.App.save_yaml)
        # text.bind("<Control-Return>", dont_propagate)

        # INFO FRAME  - displays some help to the user (status bar)
        infoframe = Frame(mainframe, borderwidth=1, relief='sunken')     # Specify starting width and height
        infoframe.grid(sticky="news", column=0, row=3)  # Make sure it expands
        # standard statusbar style:
        # Using standard tk, don't want to bother with ttk styles for now...
        # anchor='w' ??
        lbl = self.Statusbar = Label(infoframe, textvariable=self.Statustext)  # , borderwidth=1, relief='sunken')
        # text="Tip: Use CTRL+ENTER to annotate. Buffers can be saved with ctrl+s, but that's also done automatically.")
        lbl.grid(sticky='news')
        # lbl = Label(infoframe, text="(Buffers can be saved with ctrl+s, but you don't have to.)")
        # lbl.grid(sticky='news')
        # l = Label(f, text="( Shift-enter=OK (keep), Enter=OK (clear), Escape=Abort )")
        # infoframe.rowconfigure(0, weight=1)           # Make sure it expands vertically
        # infoframe.columnconfigure(0, weight=1)

        # self.bind(sequence='<Control-Return>', func=self.App.annotate) # Binding at app-level instead with bind_all

        logger.debug("Init ui done.")
class Example(Frame):
    def __init__(self, parent, q):
        Frame.__init__(self, parent)

        self.queue = q
        self.parent = parent
        self.initUI()

    def callback(self):
        self.root.quit()

    def initUI(self):

        # self.root = tk.Tk()
        # self.root.protocol("WM_DELETE_WINDOW", self.callback)

        self.parent.title("Pi Computation")
        self.pack(fill=BOTH, expand=True)

        self.grid_columnconfigure(4, weight=1)
        self.grid_rowconfigure(3, weight=1)

        lbl1 = Label(self, text="Digits:")
        lbl1.grid(row=0, column=0, sticky=E, padx=10, pady=10)

        self.ent1 = Entry(self, width=10)
        self.ent1.insert(END, "4000")
        self.ent1.grid(row=0, column=1, sticky=W)

        lbl2 = Label(self, text="Accuracy:")
        lbl2.grid(row=0, column=2, sticky=E, padx=10, pady=10)

        self.ent2 = Entry(self, width=10)
        self.ent2.insert(END, "100")
        self.ent2.grid(row=0, column=3, sticky=W)

        self.startBtn = Button(self, text="Start", command=self.onStart)
        self.startBtn.grid(row=1, column=0, padx=10, pady=5, sticky=W)

        self.pbar = Progressbar(self, mode='indeterminate')
        self.pbar.grid(row=1, column=1, columnspan=3, sticky=W + E)

        self.txt = st.ScrolledText(self)
        self.txt.grid(row=2,
                      column=0,
                      rowspan=4,
                      padx=10,
                      pady=5,
                      columnspan=5,
                      sticky=E + W + S + N)

        # self.root.mainloop()

    def onStart(self):

        self.startBtn.config(state=DISABLED)
        self.txt.delete("1.0", END)

        self.digits = int(self.ent1.get())
        self.accuracy = int(self.ent2.get())

        self.p1 = Process(target=self.generatePi, args=(self.queue, ))
        #   self.p1 = Process(target=self.generatePi, args=(self.queue ))
        self.p1.start()
        self.pbar.start(DELAY2)
        self.after(DELAY1, self.onGetValue)

    def onGetValue(self):

        if (self.p1.is_alive()):

            self.after(DELAY1, self.onGetValue)
            return
        else:

            try:
                self.txt.insert('end', self.queue.get(0))
                self.txt.insert('end', "\n")
                self.pbar.stop()
                self.startBtn.config(state=NORMAL)

            except queue.Empty:
                print("queue is empty")

    def generatePi(self, queue):

        getcontext().prec = self.digits

        pi = Decimal(0)
        k = 0
        n = self.accuracy

        while k < n:
            pi += (Decimal(1)/(16**k))*((Decimal(4)/(8*k+1)) - \
                (Decimal(2)/(8*k+4)) - (Decimal(1)/(8*k+5))- \
                (Decimal(1)/(8*k+6)))
            k += 1
            print("Example frame is still alive = ", self.p1.is_alive())
            # queue.put("Example frame is still alive = ", self.p1.is_alive())

        queue.put(pi)
        print("Example frame end")
Пример #31
0
class ClientGUI:
    def __init__(self):
        self.client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.client_socket.settimeout(5.0)
        self.port = 2345
        self.client_running = False
        self.client_connected = False
        self.root = tk.Tk()
        self.root.resizable(width=False, height=False)
        self.root.title('Chat Client')
        self.createGUI()
        self.root.protocol('WM_DELETE_WINDOW', self.onShuttingDownClient)
        self.root.mainloop()
        return

    def createGUI(self):
        tk.ttk.Style().configure('TLabel', font=('Times New Roman', 16))
        tk.ttk.Style().configure('TButton', font=('Times New Roman', 16))
        self.frame = Frame(self.root)

        self.user_name_label = Label(self.frame, text='User Name')
        self.user_name_label.grid(row=0, column=0, sticky='W')

        self.user_name_box = Entry(self.frame, font=('Times New Roman', 16), width=20)
        self.user_name_box.grid(row=0, column=1)

        self.ip_label = Label(self.frame, text='Server IP Address')
        self.ip_label.grid(row=1, column=0, sticky='W')

        self.ip_addr_box = Entry(self.frame, font=('Times New Roman', 16))
        self.ip_addr_box.grid(row=1, column=1)

        self.connect_btn = Button(self.frame, text='Connect', command=self.connectBtnClick)
        self.connect_btn.grid(row=2, column=0, sticky='W')

        self.chat_area = scrolledtext.ScrolledText(self.frame, height=10, width=42, undo=True,
                                                   font=('Times New Roman', 16))
        self.chat_area.grid(row=3, column=0, sticky='NEWS')
        self.chat_area.configure(state='disabled')

        self.client_list = Listbox(self.frame, font=('Times New Roman', 16), selectmode=tk.MULTIPLE)
        self.client_list.grid(row=3, column=1, sticky='NEWS')

        self.msg_box = scrolledtext.ScrolledText(self.frame, font=('Times New Roman', 16), height=1, width=42, undo=True)
        self.msg_box.grid(row=4, column=0, sticky='W')

        self.send_btn = Button(self.frame, text='Send', command=self.sendBtnClick)
        self.send_btn.grid(row=4, column=1, sticky='W')
        self.send_btn.state(['disabled'])

        self.frame.grid(row=0, column=0)
        return

    def connectBtnClick(self):
        self.client_name = self.user_name_box.get()
        if not (len(self.client_name) == 0):
            try:
                self.client_socket.sendto(('1111||'+ self.client_name).encode('ascii'), (self.ip_addr_box.get(), self.port))
                self.message, self.address = self.client_socket.recvfrom(2048)
                self.chat_area.config(state='normal')
                self.chat_area.insert(tk.END, self.message.decode('ascii') + '\n')
                self.chat_area.config(state='disabled')
                self.client_running = True
                threading.Thread(target=self.updateClientList).start()
                self.connect_btn.state(['disabled'])
                self.user_name_box.state(['disabled'])
                self.ip_addr_box.state(['disabled'])
                self.send_btn.state(['!disabled'])
                self.client_connected = True
            except socket.timeout as tout:
                messagebox.showerror("Message From Client", tout)
            except socket.gaierror as gerror:
                messagebox.showerror("Message From Client", gerror)
                pass
            pass
        else:
            messagebox.showerror('Message From Client', 'User Name cannot be empty')

    def sendBtnClick(self):
        recv_clients_list = self.client_list.curselection()
        msg_type = ''
        if len(recv_clients_list) > 1:
            msg_type = ' [MC]'
        recv_clients = ''
        for k in recv_clients_list:
            recv_clients = recv_clients + '||' + self.client_list.get(k)
        self.message_to_sent = self.client_name + '||' + self.msg_box.get(1.0, tk.END) + msg_type + recv_clients
        self.chat_area.config(state='normal')
        self.chat_area.insert(tk.END, 'You>>' + self.msg_box.get(1.0, tk.END) + '\n')
        self.chat_area.config(state='disabled')
        self.client_socket.sendto(self.message_to_sent.encode('ascii'), (self.ip_addr_box.get(), self.port))
        self.msg_box.delete(1.0, tk.END)
        pass

    def onShuttingDownClient(self):
        if self.client_connected:
            self.client_socket.sendto(('0000' + '||' + self.client_name).encode('ascii'), (self.ip_addr_box.get(), self.port))
        self.client_running = False
        self.root.destroy()
        pass

    def updateClientList(self):
        self.client_socket.setblocking(0)
        while self.client_running:
            try:
                self.message, self.address = self.client_socket.recvfrom(2048)
                self.message = self.message.decode('ascii')
                i = 0
                j = 0
                if self.isContain(self.message, '1111'):
                    temp_client_list = self.message.split('||')
                    self.client_list.delete(0, tk.END)
                    while i < len(temp_client_list):
                        if not (self.client_name == temp_client_list[i]) and not (temp_client_list[i] == '1111'):
                            self.client_list.insert(j, temp_client_list[i])
                            j = j + 1
                        i = i+1
                elif 'Empty List 0000' in self.message:
                    self.client_list.delete(0, tk.END)
                elif 'Server Offline 0101' in self.message:
                    self.client_connected = False
                    self.chat_area.config(state='normal')
                    self.chat_area.insert(tk.END, 'Server is Offline. Chat discontinues!!!\n')
                    self.chat_area.config(state='disabled')
                    self.send_btn.state(['disabled'])
                    self.connect_btn.state(['!disabled'])
                    self.ip_addr_box.state(['!disabled'])
                    self.user_name_box.state(['!disabled'])
                    self.client_socket.settimeout(1)
                    self.client_running = False
                else:
                    self.chat_area.config(state='normal')
                    self.chat_area.insert(tk.END, self.message + '\n')
                    self.chat_area.config(state='disabled')
            except socket.error:
                pass
        pass

    def isContain(self, str, sub_str):
        index = str.find(sub_str)
        if index == -1:
            return False
        else:
            return True
Пример #32
0
class DCSWPControllerApp(Tk):
    """DCS WP-Manager GUI layer."""
    def __init__(self):
        super().__init__()
        self.geometry("300x200")
        self.iconbitmap('icon.ico')
        self.title("DCS WP Manager")

        self.host_label = Label(self, text='Host:')
        self.host_label.grid(column=0, row=1)
        self.host = Combobox(
            values=["GAW", "PGAW", "LOCALHOST", "A-Horrible-Server"])
        self.host.insert(50, "A-Horrible-Server")
        self.host.grid(column=1, row=1)

        self.user_label = Label(self, text='Username:'******'disabled',
                           command=self.switch_status)
        self.stop.grid(column=1, row=3)

        self.label = Label(self, text='Status:')
        self.label.grid(column=0, row=5)
        self.status_value = Label(self, text="Stopped")
        self.status_value.grid(column=1, row=5)

        self.tac_proc = None
        self.coord_proc = None

    def switch_status(self):
        """Either start or stop all processes, depending on current state."""
        if str(self.stop['state']) == 'disabled':
            self.start_tac_client()
            self.start_coord_server()
            self.stop.configure(state="normal")
            self.start.configure(state="disabled")
            self.status_value.configure(text="Running")
            r.get("http://127.0.0.1:5000/set_username/" + self.user.get())
            LOG.info('Status values updated correctly...')
        else:
            self.stop_process()
            LOG.info('Process stopped...updating status values...')
            self.stop.configure(state="disabled")
            self.start.configure(state="normal")
            self.status_value.configure(text="Stopped")
            LOG.info('Status values updated correctly...')

    def start_tac_client(self):
        """Start the tacview client in a background process."""
        if self.tac_proc:
            raise ValueError("Tacview client process already exists!")
        LOG.info('Starting tacview client process...')
        host = config.presets[self.host.get()].split(":")
        self.tac_proc = Process(target=client.main, args=(
            host[0],
            host[1],
        ))
        self.tac_proc.start()
        LOG.info("Tacview client process started successfully...")

    def start_coord_server(self):
        """Start the coord server in a background process."""
        if self.coord_proc:
            raise ValueError("Coord Server process already exists!")
        LOG.info('Starting coord server process...')
        self.coord_proc = Process(target=coord_server.main)
        self.coord_proc.start()

        LOG.info("Coord server process started successfully...")

    def stop_process(self):
        """Stop both the tacview client and coord server processes."""
        if self.coord_proc:
            LOG.info('Stopping coord server process...')
            self.coord_proc.terminate()
            self.coord_proc.join()
            self.coord_proc = None
            LOG.info("Coord server process stopped successfully...")
        if self.tac_proc:
            LOG.info('Stopping tacview client process...')
            self.tac_proc.terminate()
            self.tac_proc.join()
            self.tac_proc = None
            LOG.info("tacview client process stopped successfully...")
Пример #33
0
class Program(Frame):
    """Class to represent a main window"""
    def __init__(self, parent):
        Frame.__init__(self, parent)
        self.parent = parent
        self.meters_value = StringVar()
        self.initUI()

    def initUI(self):
        self.grid(column=0, row=0, sticky=(N, W, E, S))
        self.columnconfigure(0, weight=1)
        self.rowconfigure(0, weight=1)
        self.parent.title('Feet to meter')
        self.pack(expand=True)
        self.centerWindow()
        self.initItems()

    def initItems(self):
        """Initialize all widgets here"""
        # An entry to enter feet value.
        self.feet_entry = Entry(self, width=7)
        self.feet_entry.grid(column=2, row=1, sticky=(W, E))
        # A label to display translated meters.
        self.meters_lbl = Label(self, textvariable=self.meters_value)
        self.meters_value.set(0)
        self.meters_lbl.grid(column=2, row=2, sticky=(W, E))
        # Different labels for text only.
        Label(self, text='feet').grid(column=3, row=1, sticky=W)
        Label(self, text='is equivalent to').grid(column=1, row=2, sticky=E)
        Label(self, text='meters').grid(column=3, row=2, sticky=W)
        # Button to calculate things.
        calc_btn = Button(self,
                          text='Calculate',
                          command=lambda: calculate(self))
        calc_btn.grid(column=3, row=3, sticky=W)

        # This widget is just for fun.
        # Also it shows how to get an event callback when Entry widget is modified
        def callback(str):
            print(str.get())

        entry_str = StringVar()
        entry_str.trace('w',
                        lambda name, index, mode, str=entry_str: callback(str))
        self.entry_widg = Entry(self, width=10, textvariable=entry_str)
        self.entry_widg.grid(column=1, row=4, sticky=(W, E))

        # A really simple way to change label text:
        test_lbl = Label(self)
        test_lbl.grid(column=3, row=4, sticky=E)
        test_lbl['text'] = 'hello!'

        # Handling label's events
        ev_lbl = Label(self, text='Do something with me...', width=30)
        ev_lbl.grid(column=1, row=5, columnspan=2, rowspan=2)
        ev_lbl.bind('<Enter>',
                    lambda e: ev_lbl.configure(text='Moved mouse inside'))
        ev_lbl.bind('<Leave>',
                    lambda e: ev_lbl.configure(text='Moved mouse outside'))
        ev_lbl.bind(
            '<1>',
            lambda e: ev_lbl.configure(text='Clicked left mouse button!'))
        ev_lbl.bind(
            '<Double-1>', lambda e: ev_lbl.configure(
                text='Double clicked left mouse button!'))

        # Configure pads for all grid cells
        for child in self.winfo_children():
            child.grid_configure(padx=5, pady=5)
        # As default, entry is focused
        self.feet_entry.focus()

    def centerWindow(self):
        """Place the main window in the center of screen"""
        window_w = 300
        window_h = 200
        screen_w = self.winfo_screenwidth()
        screen_h = self.winfo_screenheight()
        x = (screen_w - window_w) / 2
        y = (screen_h - window_h) / 2
        self.parent.geometry('%dx%d+%d+%d' % (window_w, window_h, x, y))
Пример #34
0
    def __init__(self, parent, title, host=None, realm=None, useOsProxy=None, urlAddr=None, urlPort=None, user=None, password=None, database=None, timeout=None, dbType=None, showUrl=False, showUser=False, showHost=True, showRealm=True, showDatabase=False):
        super(DialogUserPassword, self).__init__(parent)
        self.parent = parent
        parentGeometry = re.match("(\d+)x(\d+)[+]?([-]?\d+)[+]?([-]?\d+)", parent.geometry())
        dialogX = int(parentGeometry.group(3))
        dialogY = int(parentGeometry.group(4))
        self.accepted = False
        self.transient(self.parent)
        self.title(title)
        self.urlAddrVar = StringVar()
        self.urlAddrVar.set(urlAddr if urlAddr else "")
        self.urlPortVar = StringVar()
        self.urlPortVar.set(urlPort if urlPort else "")
        self.userVar = StringVar()
        self.userVar.set(user if user else "")
        self.passwordVar = StringVar()
        self.passwordVar.set(password if password else "")
        self.databaseVar = StringVar()
        self.databaseVar.set(database if database else "")
        self.timeoutVar = StringVar()
        self.timeoutVar.set(timeout if timeout else "")
        
        frame = Frame(self)
        y = 0
        if showHost:
            hostLabel = Label(frame, text=_("Host:"), underline=0)
            hostDisplay = Label(frame, text=host, width=30)
            if host and len(host) > 30:
                ToolTip(hostDisplay, text=host, wraplength=240)
            hostLabel.grid(row=y, column=0, sticky=W, pady=3, padx=3)
            hostDisplay.grid(row=y, column=1, columnspan=4, sticky=EW, pady=3, padx=3)
            y += 1
        if showRealm:
            realmLabel = Label(frame, text=_("Realm:"), underline=0)
            realmDisplay = Label(frame, text=realm, width=25)
            if realm and len(realm) > 30:
                ToolTip(realmDisplay, text=realm, wraplength=240)
            realmLabel.grid(row=y, column=0, sticky=W, pady=3, padx=3)
            realmDisplay.grid(row=y, column=1, columnspan=4, sticky=EW, pady=3, padx=3)
            y += 1
        self.enabledWidgets = []
        if useOsProxy is not None:
            if sys.platform.startswith("win"):
                hostProxy = _('Microsoft Windows Internet Settings')
            elif sys.platform in ("darwin", "macos"):
                hostProxy = _('Mac OS X System Configuration')
            else: # linux/unix
                hostProxy = _('environment variables')
            useOsProxyCb = checkbox(frame, 0, y, text=_("Use proxy server of {0}").format(hostProxy))
            useOsProxyCb.grid(columnspan=5)
            useOsProxyCb.valueVar.set(useOsProxy)
            ToolTip(useOsProxyCb, text=_("Check to use {0} \n"
                                         "Uncheck to specify: \n"
                                         "   No proxy if URL address is left blank, \n"
                                         "   Proxy via URL address if it is not blank, \n"
                                         "       with user and password (if provided)"
                                         ).format(hostProxy), wraplength=360)
            self.useOsProxyCb = useOsProxyCb
            useOsProxyCb.valueVar.trace("w", self.setEnabledState)

            y += 1
        if showUrl:
            urlAddrLabel = Label(frame, text=_("Address:"), underline=0)
            urlAddrEntry = Entry(frame, textvariable=self.urlAddrVar, width=16)
            urlPortLabel = Label(frame, text=_("Port:"), underline=0)
            urlPortEntry = Entry(frame, textvariable=self.urlPortVar, width=5)
            urlAddrEntry.focus_set()
            urlAddrLabel.grid(row=y, column=0, sticky=W, pady=3, padx=3)
            urlAddrEntry.grid(row=y, column=1, columnspan=2, sticky=EW, pady=3, padx=3)
            urlPortLabel.grid(row=y, column=3, sticky=W, pady=3, padx=3)
            urlPortEntry.grid(row=y, column=4, sticky=EW, pady=3, padx=3)
            ToolTip(urlAddrEntry, text=_("Enter URL address and port number \n"
                                         "  e.g., address: 168.1.2.3 port: 8080 \n"
                                         "  or address: proxy.myCompany.com port: 8080 \n"
                                         "  or leave blank to specify no proxy server"), wraplength=360)
            self.enabledWidgets.append(urlAddrEntry)
            self.enabledWidgets.append(urlPortEntry)
            y += 1
        userLabel = Label(frame, text=_("User:"******"Password:"******"*")
        passwordLabel.grid(row=y, column=0, sticky=W, pady=3, padx=3)
        passwordEntry.grid(row=y, column=1, columnspan=4, sticky=EW, pady=3, padx=3)
        self.enabledWidgets.append(passwordEntry)
        y += 1
        if showDatabase:
            urlDatabaseLabel = Label(frame, text=_("Database:"), underline=0)
            urlDatabaseEntry = Entry(frame, textvariable=self.databaseVar, width=25)
            urlDatabaseLabel.grid(row=y, column=0, sticky=W, pady=3, padx=3)
            urlDatabaseEntry.grid(row=y, column=1, columnspan=4, sticky=EW, pady=3, padx=3)
            ToolTip(urlAddrEntry, text=_("Enter database name (optional) or leave blank"), wraplength=360)
            self.enabledWidgets.append(urlDatabaseEntry)
            y += 1
            urlTimeoutLabel = Label(frame, text=_("Timeout:"), underline=0)
            urlTimeoutEntry = Entry(frame, textvariable=self.timeoutVar, width=25)
            urlTimeoutLabel.grid(row=y, column=0, sticky=W, pady=3, padx=3)
            urlTimeoutEntry.grid(row=y, column=1, columnspan=4, sticky=EW, pady=3, padx=3)
            ToolTip(urlAddrEntry, text=_("Enter timeout seconds (optional) or leave blank for default (60 secs.)"), wraplength=360)
            self.enabledWidgets.append(urlTimeoutEntry)
            y += 1
            dbTypeLabel = Label(frame, text=_("DB type:"), underline=0)
            dbTypeLabel.grid(row=y, column=0, sticky=W, pady=3, padx=3)
            self.cbDbType = gridCombobox(frame, 1, y, values=DBDescriptions, 
                                         selectindex=DBTypes.index(dbType) if dbType in DBTypes else None)
            self.cbDbType.grid(columnspan=4, pady=3, padx=3)
            y += 1
        okButton = Button(frame, text=_("OK"), command=self.ok)
        cancelButton = Button(frame, text=_("Cancel"), command=self.close)
        okButton.grid(row=y, column=2, sticky=E, pady=3)
        cancelButton.grid(row=y, column=3, columnspan=2, sticky=EW, pady=3, padx=3)
        y += 1
                
        if useOsProxy is not None:
            self.setEnabledState()

        frame.grid(row=0, column=0, sticky=(N,S,E,W))
        frame.columnconfigure(1, weight=1)
        window = self.winfo_toplevel()
        window.columnconfigure(0, weight=1)
        self.geometry("+{0}+{1}".format(dialogX+50,dialogY+100))
        
        self.bind("<Return>", self.ok)
        self.bind("<Escape>", self.close)
        
        self.protocol("WM_DELETE_WINDOW", self.close)
        self.grab_set()
        self.wait_window(self)
Пример #35
0
class MyGUI:
    def __init__(self, master, title=None, args=None):

        self.master = master
        self.args = args
        self.name = title
        master.title("Startup interface for %s" % title)
        self.arguments = dict()

        style = Style()
        style.configure(".", background="lightgrey")

        labelStyle = Style()
        labelStyle.configure("TLabel", background="lightgrey")
        buttonStyle = Style()
        buttonStyle.configure("TButton", background="lightgrey")
        chkbuttonStyle = Style()
        chkbuttonStyle.configure("TCheckbutton", background="lightgrey")
        rbuttonStyle = Style()
        rbuttonStyle.configure("TRadiobutton", background="lightgrey")

        row = 0
        column = 0

        # Input edge file
        self.inEdgeLabel = Label(master, text="Input edge file")
        self.inEdgeLabel.grid(row=row, column=column, sticky=W, padx=3)
        self.inEdgeFile = StringVar()
        if self.args.i:
            self.inEdgeFile.set(self.args.i)
        self.inEdgeEntry = Entry(master,
                                 width=WIDTH,
                                 textvariable=self.inEdgeFile)
        column += 1
        self.inEdgeEntry.grid(row=row, column=column, padx=3)
        self.inEdgeSelect = Button(master, text = "Select",\
                                   command = lambda: self.setOutputFiles2(IN=self.inEdgeFile,OUT=[(self.configFile,"config"),(self.outFile,"desc"),(self.outFile2,"xml_desc")]))
        column += 1
        self.inEdgeSelect.grid(row=row, column=column, sticky=W, padx=3)
        self.optionLabel2 = Label(master, text="required")
        column += 1
        self.optionLabel2.grid(row=row, column=column, sticky=W, padx=3)
        # tip
        helpText1 = "Edge file for input graph (two columns, tab-delimited)."
        self.inEdgeTip = CreateToolTip(self.inEdgeEntry, helpText1)
        ##
        row += 1
        column = 0

        self.annotLabel = Label(master, text="Annotation file")
        self.annotLabel.grid(row=row, column=column, sticky=W, padx=3)
        self.a = StringVar()
        if self.args.a:
            self.a.set(os.path.abspath(os.path.normpath(self.args.a)))
        self.annotEntry = Entry(master, width=WIDTH, textvariable=self.a)
        column += 1
        self.annotEntry.grid(row=row, column=column, padx=3)
        self.annotSelect = Button(
            master,
            text="Select",
            command=lambda: self.openAnnotFile(var=self.a))
        column += 1
        self.annotSelect.grid(row=row, column=column, sticky=W, padx=3)
        self.optionLabel2 = Label(master, text="required")
        column += 1
        self.optionLabel2.grid(row=row, column=column, sticky=W, padx=3)
        CreateToolTip(
            self.annotEntry,
            "Common annotation file for genomes and genes.\nTab-delimited, compulsory header with attribute names.\nSpecify empty annotations with '-'."
        )
        row += 1
        column = 0

        self.k = StringVar()
        if self.a.get():
            with open(self.a.get(), 'r') as ANNOT:
                keyList = ANNOT.readline().strip().split("\t")[1:]
                #print(keyList)
                keyList.sort()
                keyString = ",".join(keyList)
            self.optionLabel = Label(master, text="Annotation keys")
            self.optionLabel.grid(row=row, column=0, sticky=W, padx=3)
            self.k = StringVar()
            self.k.set(keyString)
            self.optionEntry = Entry(master, width=WIDTH, textvariable=self.k)
            self.optionEntry.grid(row=row, column=1, padx=3)
            self.optionLabel2 = Label(master, text="comma-separated")
            self.optionLabel2.grid(row=row, column=3, sticky=W, padx=3)
            CreateToolTip(
                self.optionEntry,
                "List of available attributes in file %s.\nIf you wish to remove some, click on line and edit."
                % self.args.a)
        row += 1

        self.configLabel = Label(master, text="Configuration file")
        self.configLabel.grid(row=row, column=column, sticky=W, padx=3)
        self.configFile = StringVar()
        self.generateConfig = BooleanVar()
        self.generateConfig.set(bool(self.args.X))
        self.useConfig = BooleanVar()
        self.useConfig.set(bool(self.args.x))
        if self.args.x or self.args.X:
            if self.args.x and self.args.X:
                if self.args.x == self.args.X:
                    cFile = self.args.x
                    self.configFile.set(cFile)
                else:
                    sys.exit(
                        "Conflicting fields -x and -X. Check and run again.")
            elif self.args.x:
                cFile = self.args.x
            else:
                cFile = self.args.X
            self.configFile.set(cFile)
        else:
            self.configFile.set('')
        self.configEntry = Entry(master,
                                 width=WIDTH,
                                 textvariable=self.configFile)
        column += 1
        self.configEntry.grid(row=row, column=column, padx=3)
        self.configSelect = Button(
            master,
            text="Select",
            command=lambda: self.setFile(var1=self.configFile,
                                         var2=self.outTrailFile))
        column += 1
        self.configSelect.grid(row=row, column=column, sticky=W, padx=3)
        """self.optionLabel2 = Label(master, text = "optional")
                column += 1
                self.optionLabel2.grid(row=row,column=column,sticky=W, padx=3)
                """
        # tip
        helpText3 = "XML file specifying component, trails and annotations for all node types."
        self.configTip = CreateToolTip(self.configEntry, helpText3)
        #
        column += 1
        #row += 1
        #column = 0

        cbFrame = Frame(master)
        chk1 = Checkbutton(cbFrame, text="Generate", var=self.generateConfig)
        chk1.pack(side="left", fill=None, expand=False, padx=3)
        CreateToolTip(chk1,
                      "Generate configuration file %s" % self.configFile.get())
        chk2 = Checkbutton(cbFrame, text="Use", var=self.useConfig)
        chk2.pack(side="left", fill=None, expand=False, padx=3)
        CreateToolTip(chk2,
                      "Use configuration file %s" % self.configFile.get())
        cbFrame.grid(row=row, column=column, sticky=W)
        row += 1
        column = 0

        self.TrailLabel = Label(master, text="Use trail file")
        self.TrailLabel.grid(row=row, column=column, sticky=W, padx=3)
        self.inTrailFile = StringVar()
        self.T = StringVar()
        if self.args.t:
            self.T.set("1")
            self.inTrailFile.set(self.args.t)
        elif self.args.H:
            self.T.set("2")
            self.inTrailFile.set(self.args.H)
        else:
            self.T.set("0")
        MODES = [
            ("No", "0"),
            ("Unique level", "1"),
            ("Follow history", "2"),
        ]
        trailVal = {
            "0": "Toto",
            "1": self.inTrailFile.get(),
            "2": self.inTrailFile.get()
        }
        helpVal = {
            "0":
            "Do not use trail file.\nCheck that annotations refer to IDs of current graph.",
            "1": "Use only level described by trail file.",
            "2": "Use all levels found in the trail history."
        }
        rbFrame = Frame(master)  # create subframe for radiobuttons
        i = 0
        MODE = MODES[0]
        b = Radiobutton(rbFrame,
                        text=MODE[0],
                        variable=self.T,
                        value=MODE[1],
                        command=lambda: self.inTrailFile.set(''))
        # tip
        CreateToolTip(b, helpVal[str(i)])
        ##
        b.pack(side="left", fill=None, expand=False, padx=3)
        for text, mode in MODES[1:]:
            b = Radiobutton(
                rbFrame,
                text=text,
                variable=self.T,
                value=mode,
                command=lambda: self.openFileCheck(var=self.inTrailFile))
            # tip
            CreateToolTip(b, helpVal[mode])
            ##
            b.pack(side="left", fill=None, expand=False, padx=3)
        rbFrame.grid(row=row, column=1)
        row += 1
        column = 0

        self.inTrailLabel = Label(master, text="Trail file")
        self.inTrailLabel.grid(row=row, column=column, sticky=W, padx=18)
        #self.inTrailEntry = Entry(master, width = WIDTH, textvariable = self.inTrailFile)

        self.inTrailEntry = Entry(master,
                                  width=WIDTH,
                                  textvariable=self.inTrailFile,
                                  validate='focusin',
                                  validatecommand=lambda: self.T.set("2"))
        CreateToolTip(
            self.inTrailEntry,
            """Select node type file for multipartite graphs.\nThis will reset the partiteness to "Multipartite"."""
        )

        column += 1
        self.inTrailEntry.grid(row=row, column=column, padx=3)
        self.inTrailSelect = Button(
            master,
            text="Select",
            command=lambda: self.openFile2(
                var=self.inTrailFile, var2=self.T, value="2"))
        column += 1
        self.inTrailSelect.grid(row=row, column=column, sticky=W, padx=3)
        self.optionLabel2 = Label(master, text="if option set")
        column += 1
        self.optionLabel2.grid(row=row, column=column, sticky=W, padx=3)
        # tip
        helpText3 = "Links IDs of current graph to IDs of ROOT graph (two columns, tab-delimited).\nIf skipped, current graph is considered ROOT."
        self.inTrailTip = CreateToolTip(self.inTrailEntry, helpText3)
        #
        """
                cbFrame = Frame(master)
                self.uniqueTrail = BooleanVar()
                chk1 = Checkbutton(cbFrame, text="Unique trail file", var = self.uniqueTrail)
                chk1.pack(side="left", fill=None, expand=False, padx=3) 
                CreateToolTip(chk1, "Consider only level given by %s" % self.inTrailFile.get())
                self.history = BooleanVar()
                chk2 = Checkbutton(cbFrame, text="Use trail history", var = self.history)
                chk2.pack(side="left", fill=None, expand=False, padx=3) 
                CreateToolTip(chk2, "Follow trail history of trail file %s" % self.inTrailFile.get())
                cbFrame.grid(row=row,column=1)
                """
        row += 1
        column = 0

        # Component file
        self.CompLabel = Label(master, text="Component file ")
        self.CompLabel.grid(row=row, column=column, sticky=W, padx=3)
        self.CompFile = StringVar()
        if self.args.c:
            self.CompFile.set(self.args.c)
        self.CompEntry = Entry(master, width=WIDTH, textvariable=self.CompFile)
        column += 1
        self.CompEntry.grid(row=row, column=column, padx=3)
        self.CompSelect = Button(
            master,
            text="Select",
            command=lambda: self.openFile(var=self.CompFile))
        column += 1
        self.CompSelect.grid(row=row, column=column, sticky=W, padx=3)
        self.optionLabel2 = Label(master, text="optional")
        column += 1
        self.optionLabel2.grid(row=row, column=column, sticky=W, padx=3)
        # tip
        helpText3 = "Links a nodeID and its neighbours to the twin class ID.\nThis is usually an overlapping clustering.\nIf left empty, consider nodes of current graph as components."
        self.CompTip = CreateToolTip(self.CompEntry, helpText3)
        ##
        row += 1
        column = 0

        # Partiteness options
        self.inNodeLabel = Label(master, text="Partiteness")
        self.inNodeLabel.grid(row=row, column=column, sticky=W, padx=3)
        column += 1
        MODES = [
            ("Unipartite", "1"),
            ("Bipartite", "2"),
        ]
        self.inNodeType = StringVar()
        self.v = StringVar()
        if str(self.args.N) == '1' or str(self.args.N) == '2':
            self.v.set(self.args.N)  # initialize at value
        elif self.args.N:
            self.v.set("m")
            self.inNodeType.set(self.args.N)
        else:
            self.v.set("2")
        rbFrame = Frame(master)  # create subframe for radiobuttons
        for text, mode in MODES:
            b = Radiobutton(rbFrame,
                            text=text,
                            variable=self.v,
                            value=mode,
                            command=lambda: self.inNodeType.set(''))
            # tip
            CreateToolTip(b, "Select if graph is %s" % text.lower())
            ##
            b.pack(side="left", fill=None, expand=False, padx=3)
        b = Radiobutton(rbFrame,
                        text="Multipartite",
                        variable=self.v,
                        value="m",
                        command=lambda: self.openFile(var=self.inNodeType))
        CreateToolTip(
            b,
            "Select if graph is multipartite.\nThis will open a select box for the node type file."
        )
        b.pack(side="left", fill=None, expand=False, padx=3)
        rbFrame.grid(row=row, column=column, padx=3)
        row += 1
        column = 0
        self.Label = Label(master, text="Node type file")
        self.Label.grid(row=row, column=column, sticky=W, padx=18)
        self.inNodeEntry = Entry(master,
                                 width=WIDTH,
                                 textvariable=self.inNodeType,
                                 validate='focusin',
                                 validatecommand=lambda: self.v.set("m"))
        CreateToolTip(
            self.inNodeEntry,
            """Select node type file for multipartite graphs.\nThis will reset the partiteness to "Multipartite"."""
        )
        column += 1
        self.inNodeEntry.grid(row=row, column=column, padx=3)
        self.inNodeSelect = Button(
            master,
            text="Select",
            command=lambda: self.openFile2(
                var=self.inNodeType, var2=self.v, value="m")
        )  # reset value to "multipartite" when type file is chosen.
        column += 1
        self.inNodeSelect.grid(row=row, column=column, sticky=W, padx=3)
        self.optionLabel2 = Label(master, text="for multipartite only")
        column += 1
        self.optionLabel2.grid(row=row, column=column, sticky=W, padx=3)
        CreateToolTip(
            self.inNodeSelect,
            """Select node type file for multipartite graphs.\nThis will reset the partiteness to "Multipartite"."""
        )
        row += 1
        column = 0

        # Output file
        self.outLabel = Label(master, text="Output plain file")
        self.outLabel.grid(row=row, column=column, sticky=W, padx=3)
        self.outFile = StringVar()
        if self.args.o:
            self.outFile.set(self.args.o)
        self.outEntry = Entry(master, width=WIDTH, textvariable=self.outFile)
        column += 1
        self.outEntry.grid(row=row, column=column, padx=3)
        self.outSelect = Button(
            master,
            text="Select",
            command=lambda: self.openFile(var=self.outFile))
        column += 1
        self.outSelect.grid(row=row, column=column, sticky=W, padx=3)
        self.optionLabel2 = Label(master, text="required")
        column += 1
        self.optionLabel2.grid(row=row, column=column, sticky=W, padx=3)
        # tip
        helpText2 = "Set name of the plain text description file"
        self.outTip = CreateToolTip(self.outEntry, helpText2)
        ##
        row += 1
        column = 0

        # Output file
        self.outLabel2 = Label(master, text="Output XML file")
        self.outLabel2.grid(row=row, column=column, sticky=W, padx=3)
        self.outFile2 = StringVar()
        if self.args.O:
            self.outFile.set(self.args.O)
        self.outEntry2 = Entry(master, width=WIDTH, textvariable=self.outFile2)
        column += 1
        self.outEntry2.grid(row=row, column=column, padx=3)
        self.outSelect2 = Button(
            master,
            text="Select",
            command=lambda: self.openFile(var=self.outFile2))
        column += 1
        self.outSelect2.grid(row=row, column=column, sticky=W, padx=3)
        self.optionLabel2 = Label(master, text="optional")
        column += 1
        self.optionLabel2.grid(row=row, column=column, sticky=W, padx=3)
        # tip
        helpText2 = "Set name of the XML description file"
        self.outTip = CreateToolTip(self.outEntry2, helpText2)
        ##
        row += 1
        column = 0

        self.optionLabel = Label(master, text="Unique node identifier")
        self.optionLabel.grid(row=row, column=0, sticky=W, padx=3)
        self.I = StringVar()
        if self.args.I:
            self.I.set(self.args.I)
        self.optionEntry = Entry(master, width=WIDTH, textvariable=self.I)
        self.optionEntry.grid(row=row, column=1, padx=3)
        CreateToolTip(
            self.optionEntry,
            """Name of first column in annotation %s file.\nCheck that the items in this column match the node IDs in the ROOT graph."""
            % os.path.basename(self.a.get()))
        row += 1
        column = 0

        self.trackLabel = Label(master, text="Missing annotation label")
        self.trackLabel.grid(row=row, column=column, sticky=W, padx=3)
        self.trackName = StringVar()
        if self.args.T:
            self.trackName.set(self.args.T)
        self.trackEntry = Entry(master,
                                width=WIDTH,
                                textvariable=self.trackName)
        column += 1
        self.trackEntry.grid(row=row, column=column, padx=3)
        # tip
        helpText3 = "Name replacing missing annotations"
        self.trackTip = CreateToolTip(self.trackEntry, helpText3)
        #
        column += 2

        self.Track = BooleanVar()
        chk1 = Checkbutton(master, text="Skip", var=self.Track)
        CreateToolTip(chk1, "Skip missing annotations")
        chk1.grid(row=row, column=column, sticky=W, padx=9)
        row += 1
        column = 0

        self.optionLabel = Label(master,
                                 text="Graphic interface for %s" %
                                 self.configFile.get())
        self.optionLabel.grid(row=row, column=0, sticky=W, padx=3)
        self.K = BooleanVar()
        self.K.set(self.args.K)
        self.chk = Checkbutton(master, text="Display?", var=self.K)
        self.chk.grid(row=row, column=1, padx=3, sticky=W)
        CreateToolTip(
            self.chk,
            "Displays graphic customization interface for the last description.py step.\nIf not selected, displays all attributes for all key types and all trail levels."
        )
        row += 1
        column = 0
        # Log
        self.optionLabel = Label(master, text="Log file")
        self.optionLabel.grid(row=row, column=0, sticky=W, padx=3)
        self.l = StringVar()
        try:
            log = self.args.l.name.strip("(<,>")
        except:
            log = log
        self.l.set(log)
        self.optionEntry = Entry(master, width=WIDTH, textvariable=self.l)
        self.optionEntry.grid(row=row, column=1, padx=3)
        row += 2

        # Populate outFiles if edge file given
        if self.args.i:
            self.setOutputFiles2(IN=self.inEdgeFile,
                                 OUT=[(self.configFile, "config"),
                                      (self.outFile, "desc"),
                                      (self.outFile2, "xml_desc")],
                                 OPEN=False)

        cbFrame = Frame(master)  # create subframe for command buttons

        self.run_button = Button(cbFrame, text="Run", command=self.run)
        self.run_button.grid(row=row, column=0, padx=12)

        self.close_button = Button(cbFrame, text="Close", command=self.Quit)
        self.close_button.grid(row=row, column=1, padx=12)

        cbFrame.grid(row=row, column=1, columnspan=2, sticky=E + W)

        helpText = description.processArgs().format_help()
        self.helpbutton = Button(
            master,
            text="Help",
            command=lambda: HelpWindow(text=helpText, name=self.name))
        self.helpbutton.grid(row=row, column=2, sticky=W, padx=3)

    def func(self, value):
        print("Set %s " % value)

    def setFile(self, var1=None, var2=None):
        self.openFile(var=var1)
        modfile = os.path.split(var1.get())[1]
        var2.set(modfile)
        self.master.update_idletasks()

    def setOutputFiles(self, IN=None, TWIN=None, TWINCOMP=None):
        self.openFile(var=IN)
        inFile = os.path.split(IN.get())[1]
        inRad = inFile.split(".")[0]
        twin = inRad + ".twins"
        twinComp = inRad + ".twin_comp"
        TWIN.set(twin)
        TWINCOMP.set(twinComp)
        self.master.update_idletasks()

    def setOutputFiles2(self, IN=None, OUT=None, OPEN=True):
        if OPEN:
            self.openFile(var=IN)
        inFile = os.path.split(IN.get())[1]
        inRad = inFile.split(".")[0]
        for items in OUT:
            FILE, EXT = items
            FILE.set(inRad + "." + EXT)
        self.master.update_idletasks()

    def openFile(self, var=None):
        var.set(askopenfilename())

    def openFileCheck(self, var=None):
        if not var.get():
            var.set(askopenfilename())

    def openFile2(self, var=None, var2=None, value=None):
        var.set(askopenfilename())
        var2.set(value)
        self.master.update_idletasks()

    def openAnnotFile(self, var=None):
        var.set(askopenfilename())
        row = 2
        master = self.master
        try:
            with open(var.get(), 'r') as ANNOT:
                keyList = ANNOT.readline().strip().split("\t")[1:]
                #print(keyList)
                keyList.sort()
                keyString = ",".join(keyList)
        except FileNotFoundError:
            return
        self.optionLabel = Label(master, text="Annotation keys")
        self.optionLabel.grid(row=row, column=0, sticky=W, padx=3)
        self.k = StringVar()
        self.k.set(keyString)
        self.optionEntry = Entry(master, width=WIDTH, textvariable=self.k)
        self.optionEntry.grid(row=row, column=1, padx=3)
        self.optionLabel2 = Label(master, text="comma-separated")
        self.optionLabel2.grid(row=row, column=3, sticky=W, padx=3)
        ann = os.path.basename(self.a.get())
        CreateToolTip(
            self.optionEntry,
            """List of available attributes in file %s.\nIf you wish to remove some, click on line and edit."""
            % ann)
        self.master.update_idletasks()
        RHeight = self.master.winfo_reqheight()
        RWidth = self.master.winfo_reqwidth()
        self.master.geometry(("%dx%d+300+300") % (RWidth, RHeight))
        center(self.master)

    def Quit(self, event=None):
        self.master.destroy()

    def run(self, event=None):
        self.arguments['edgeFile'] = self.inEdgeFile.get()
        self.arguments['annotFile'] = self.a.get()
        if self.k.get():
            #print("KeyList defined: %s" % self.k.get())
            self.arguments['keyList'] = self.k.get()
        if self.useConfig.get():
            self.arguments['x'] = self.configFile.get()
        if self.generateConfig.get():
            self.arguments['X'] = self.configFile.get()
        if self.T.get() == '1':
            self.arguments['trail'] = self.inTrailFile.get()
        elif self.T.get() == '2':
            self.arguments['hist'] = self.inTrailFile.get()
        self.arguments['comp'] = self.CompFile.get()
        if self.v.get() == '1' or self.v.get() == '2':
            self.arguments['NodeType'] = self.v.get()
        else:
            self.arguments['NodeType'] = self.inNodeType.get()
        self.arguments['outFile'] = self.outFile.get()
        self.arguments['Xout'] = self.outFile2.get()
        self.arguments['log'] = self.l.get()
        if self.arguments['log'] == 'stderr':
            self.arguments['log'] = sys.stderr
        self.arguments['sep'] = self.args.s
        self.arguments['track'] = self.trackName.get()
        self.arguments['empty'] = self.Track.get()
        if self.K.get():
            self.arguments['K'] = self.K
        else:
            self.arguments['display'] = True
        if self.k.get():
            self.arguments['keyList'] = self.k.get()
        if self.I.get():
            self.arguments['nodeID'] = self.I.get()
        self.arguments = renorm(self.arguments)
        self.master.destroy()
Пример #36
0
class ManagerWindow:
    """
    主管理界面入口类,直接无参数创建对象即可。
    """

    # 窗口宽高
    WIN_WIDTH = 800
    WIN_HEIGHT = 600

    def __init__(self):
        # 界面根节点
        self.root = Tk()

        # 主窗口标题
        self.root.title(MANAGER_TITLE)

        # 读取config
        self.config_dict = ConfigOperation.get_dir_from_file()

        # 主窗口分辨率
        self.root.geometry("%sx%s+%s+%s" % (
            self.WIN_WIDTH,
            self.WIN_HEIGHT,
            int((self.root.winfo_screenwidth() - self.WIN_WIDTH) / 2),
            int((self.root.winfo_screenheight() - self.WIN_HEIGHT) / 2)
        ))
        self.root.minsize(self.WIN_WIDTH, self.WIN_HEIGHT)

        # 选项卡
        self.tab_main = Notebook(self.root)
        self.tab_main.pack(expand=True, fill=BOTH)

        # 登录选项卡
        self.frame_login = Frame(self.tab_main, bg=BG_COLOR)
        self.frame_login.pack(side=TOP)
        self.tab_main.add(self.frame_login, text=TAB_NAME_LIST["login"]["text"])

        # 管理选项卡
        self.frame_manage = Frame(self.tab_main, bg=BG_COLOR)
        self.tab_main.add(self.frame_manage, text=TAB_NAME_LIST["manage"]["text"])

        # 好友选项卡
        self.frame_friend = Frame(self.tab_main, bg=BG_COLOR)
        self.frame_friend.pack(side=TOP)
        self.tab_main.add(self.frame_friend, text=TAB_NAME_LIST["friends"]["text"])

        # 群选项卡
        self.frame_group = Frame(self.tab_main, bg=BG_COLOR)
        self.frame_group.pack(side=TOP)
        self.tab_main.add(self.frame_group, text=TAB_NAME_LIST["groups"]["text"])

        # 插件选项卡
        self.frame_plugin = Frame(self.tab_main, bg=BG_COLOR)
        self.frame_plugin.pack(side=TOP)
        self.tab_main.add(self.frame_plugin, text=TAB_NAME_LIST["plugins"]["text"])

        # 初始化登录选项卡
        self.__init_login_tab()

        # 初始化好友选项卡
        self.__init_friend_tab()

        # 初始化群选项卡
        self.__init_group_tab()

        # 初始化管理选项卡
        self.__init_manage_tab()

        # 初始化插件选项卡
        self.__init_plugin_tab()

        # 关闭窗口自动释放Session
        self.root.protocol("WM_DELETE_WINDOW", lambda: self.__on_close_root())

        # 刷新显示
        self.__refresh()

        # 运行相关线程
        fetch_message_thread = FetchMessageThread()
        fetch_message_thread.daemon = True
        fetch_message_thread.start()

        # 运行插件初始化方法
        PluginHandler.call_init()

        # 执行自动连接一次
        self.__auto_connect()

        # 显示
        self.root.mainloop()

    def __init_login_tab(self):
        """
        初始化登录选项卡界面

        :return: 无
        """
        # 左边列表的frame
        frame_login_list = Frame(self.frame_login, bg=BG_COLOR)
        frame_login_list.pack(
            side=LEFT,
            expand=True,
            fill=BOTH,
            padx=5,
            pady=5
        )

        # 列表,用于保存连接记录
        self.treeview_login_list = Treeview(
            frame_login_list,
            columns=[
                LOGIN_GUIDE["host"],
                LOGIN_GUIDE["port"],
                LOGIN_GUIDE["authkey"],
                LOGIN_GUIDE["qq"]
            ],
            show="headings",
            selectmode=BROWSE
        )
        self.treeview_login_list.pack(
            expand=True,
            fill=BOTH,
            side=LEFT
        )
        self.treeview_login_list.column(
            LOGIN_GUIDE["host"],
            width=0
        )
        self.treeview_login_list.heading(
            LOGIN_GUIDE["host"],
            text=LOGIN_GUIDE["host"]
        )
        self.treeview_login_list.column(
            LOGIN_GUIDE["port"],
            width=0
        )
        self.treeview_login_list.heading(
            LOGIN_GUIDE["port"],
            text=LOGIN_GUIDE["port"]
        )
        self.treeview_login_list.column(
            LOGIN_GUIDE["authkey"],
            width=40
        )
        self.treeview_login_list.heading(
            LOGIN_GUIDE["authkey"],
            text=LOGIN_GUIDE["authkey"]
        )
        self.treeview_login_list.column(
            LOGIN_GUIDE["qq"],
            width=0
        )
        self.treeview_login_list.heading(
            LOGIN_GUIDE["qq"],
            text=LOGIN_GUIDE["qq"]
        )

        # 设定双击事件
        self.treeview_login_list.bind(
            "<Double-Button-1>",
            lambda event: self.__on_double_click_login_list_content()
        )

        # 设定登录列表的滚动条
        scrollbar_login_list = Scrollbar(frame_login_list)
        scrollbar_login_list.pack(fill="y", expand=True)
        self.treeview_login_list.config(yscrollcommand=scrollbar_login_list.set)
        scrollbar_login_list.config(command=self.treeview_login_list.yview)

        # 设置列表右键菜单
        self.treeview_login_list.bind("<Button-3>", self.__show_login_list_pop_up_menu)

        # 登录界面显示的那一坨
        frame_login_menu = Frame(self.frame_login, bg=BG_COLOR)
        frame_login_menu.pack(side=LEFT, padx=5, pady=5)

        # mirai端地址
        Label(frame_login_menu, text=LOGIN_GUIDE["host"], bg=BG_COLOR).grid(row=0, sticky=E, padx=5, pady=5)
        self.entry_host = Entry(frame_login_menu)
        self.entry_host.grid(row=0, column=1, sticky=W, padx=5, pady=5)

        # mirai端端口号
        Label(frame_login_menu, text=LOGIN_GUIDE["port"], bg=BG_COLOR).grid(row=1, sticky=E, padx=5, pady=5)
        self.entry_port = Entry(frame_login_menu)
        self.entry_port.grid(row=1, column=1, sticky=W, padx=5, pady=5)

        # mirai端http授权码
        Label(frame_login_menu, text=LOGIN_GUIDE["authkey"], bg=BG_COLOR).grid(
            row=2,
            sticky=E,
            padx=5,
            pady=5
        )
        self.entry_authkey = Entry(frame_login_menu, show=PWD_CHAR_CIRCLE)
        self.entry_authkey.grid(row=2, column=1, sticky=W, padx=5, pady=5)

        # 用于激活sessioKey的qq号码
        Label(frame_login_menu, text=LOGIN_GUIDE["qq"], bg=BG_COLOR).grid(
            row=3,
            sticky=E,
            padx=5,
            pady=5
        )
        self.entry_qq = Entry(frame_login_menu)
        self.entry_qq.grid(row=3, column=1, sticky=W, padx=5, pady=5)

        # 自动连接复选框
        self.auto_connect_var = BooleanVar()
        self.checkbutton_auto_connect = Checkbutton(
            frame_login_menu,
            text=AUTO_CONNECT_GUIDE,
            onvalue=True,
            offvalue=False,
            variable=self.auto_connect_var,
            bg=BG_COLOR
        )
        self.checkbutton_auto_connect.grid(row=4, column=0, padx=5, pady=5, columnspan=2)

        # 连接按钮
        self.btn_connect = Button(
            frame_login_menu,
            text=BTN_TEXT_CONN["connect"],
            width=15,
            command=lambda: self.__on_click_connect_event(),
        )
        self.btn_connect.grid(row=5, columnspan=2, padx=5, pady=5)

        # 添加到登录列表按钮
        self.btn_save_login = Button(
            frame_login_menu,
            width=15,
            text=BTN_TEXT_ADD_LOGIN,
            command=lambda: self.__on_click_add_to_login_list()
        )
        self.btn_save_login.grid(row=6, columnspan=2, padx=5, pady=5)

        # 状态栏
        self.label_login_status_bar = Label(
            self.root,
            text=LOGIN_STATUS_BAR_TEXT["notConnect"],
            fg=STATUS_BAR_COLOR["normal"]
        )
        self.label_login_status_bar.pack(side=LEFT)

        # 下面开始从config中将内容填充进文本框中
        self.entry_host.delete(0, END)
        self.entry_host.insert(END, self.config_dict["lastConnection"]["host"])
        self.entry_port.delete(0, END)
        self.entry_port.insert(END, self.config_dict["lastConnection"]["port"])
        self.entry_authkey.delete(0, END)
        self.entry_authkey.insert(END, self.config_dict["lastConnection"]["authkey"])
        self.entry_qq.delete(0, END)
        self.entry_qq.insert(END, self.config_dict["lastConnection"]["qq"])

        # 自动连接复选框内容
        self.auto_connect_var.set(self.config_dict["autoConnect"])

    def __init_friend_tab(self):
        """
        初始化好友选项卡内容

        :return: 无
        """

        # 创建好友列表框架
        frame_friend_list = Frame(self.frame_friend, bg=BG_COLOR)
        frame_friend_list.pack(
            side=LEFT,
            expand=True,
            fill=BOTH,
            padx=5,
            pady=5
        )

        # 创建消息测试发送框架
        frame_friend_send = Frame(self.frame_friend, bg=BG_COLOR)
        frame_friend_send.pack(
            side=LEFT,
            padx=5,
            pady=5
        )

        # 设置列表
        self.treeview_friend_list = Treeview(
            frame_friend_list,
            columns=[
                FRIEND_GUIDE["qq"],
                FRIEND_GUIDE["nickname"],
                FRIEND_GUIDE["remark"]
            ],
            show="headings",
            selectmode=BROWSE
        )
        self.treeview_friend_list.pack(
            expand=True,
            fill=BOTH,
            side=LEFT
        )
        self.treeview_friend_list.column(
            FRIEND_GUIDE["qq"],
            width=0
        )
        self.treeview_friend_list.heading(
            FRIEND_GUIDE["qq"],
            text=FRIEND_GUIDE["qq"]
        )
        self.treeview_friend_list.column(
            FRIEND_GUIDE["nickname"],
            width=0
        )
        self.treeview_friend_list.heading(
            FRIEND_GUIDE["nickname"],
            text=FRIEND_GUIDE["nickname"]
        )
        self.treeview_friend_list.column(
            FRIEND_GUIDE["remark"],
            width=0
        )
        self.treeview_friend_list.heading(
            FRIEND_GUIDE["remark"],
            text=FRIEND_GUIDE["remark"]
        )

        # 设定好友列表的滚动条
        scrollbar_friend_list = Scrollbar(frame_friend_list)
        scrollbar_friend_list.pack(fill="y", expand=True)
        self.treeview_friend_list.config(yscrollcommand=scrollbar_friend_list.set)
        scrollbar_friend_list.config(command=self.treeview_friend_list.yview)

        # 刷新列表按钮
        Button(
            frame_friend_send,
            text=BTN_FRIEND_REFRESH,
            command=lambda: self.__on_click_refresh_friend_list_event()
        ).grid(row=0, padx=5, pady=5)

        # 发送纯文本窗口标题
        Label(frame_friend_send, text=SEND_TITLE, bg=BG_COLOR).grid(row=1, padx=5, pady=5)

        # 发送纯文本窗口
        self.text_friend_send = Text(frame_friend_send, width=30, height=5)
        self.text_friend_send.grid(row=2, padx=5, pady=5)

        # 发送按钮
        Button(
            frame_friend_send,
            text=BTN_SEND,
            command=lambda: self.__on_click_send_friend_message()
        ).grid(row=3, padx=5, pady=5)

    def __init_group_tab(self):
        """
        初始化群选项卡内容

        :return: 无
        """

        # 创建好友列表框架
        frame_group_list = Frame(self.frame_group, bg=BG_COLOR)
        frame_group_list.pack(
            side=LEFT,
            expand=True,
            fill=BOTH,
            padx=5,
            pady=5
        )

        # 创建消息测试发送框架
        frame_group_send = Frame(self.frame_group, bg=BG_COLOR)
        frame_group_send.pack(
            side=LEFT,
            padx=5,
            pady=5
        )

        # 设置列表
        self.treeview_group_list = Treeview(
            frame_group_list,
            columns=[
                GROUP_GUIDE["group"],
                GROUP_GUIDE["name"],
                GROUP_GUIDE["permission"]
            ],
            show="headings",
            selectmode=BROWSE
        )
        self.treeview_group_list.pack(
            expand=True,
            fill=BOTH,
            side=LEFT
        )
        self.treeview_group_list.column(
            GROUP_GUIDE["group"],
            width=0
        )
        self.treeview_group_list.heading(
            GROUP_GUIDE["group"],
            text=GROUP_GUIDE["group"]
        )
        self.treeview_group_list.column(
            GROUP_GUIDE["name"],
            width=0
        )
        self.treeview_group_list.heading(
            GROUP_GUIDE["name"],
            text=GROUP_GUIDE["name"]
        )
        self.treeview_group_list.column(
            GROUP_GUIDE["permission"],
            width=0
        )
        self.treeview_group_list.heading(
            GROUP_GUIDE["permission"],
            text=GROUP_GUIDE["permission"]
        )

        # 设定群列表的滚动条
        scrollbar_group_list = Scrollbar(frame_group_list)
        scrollbar_group_list.pack(fill="y", expand=True)
        self.treeview_group_list.config(yscrollcommand=scrollbar_group_list.set)
        scrollbar_group_list.config(command=self.treeview_group_list.yview)

        # 刷新列表按钮
        Button(
            frame_group_send,
            text=BTN_GROUP_REFRESH,
            command=lambda: self.__on_click_refresh_group_list_event()
        ).grid(row=0, padx=5, pady=5)

        # 发送纯文本窗口标题
        Label(frame_group_send, text=SEND_TITLE, bg=BG_COLOR).grid(row=1, padx=5, pady=5)

        # 发送纯文本窗口
        self.text_group_send = Text(frame_group_send, width=30, height=5)
        self.text_group_send.grid(row=2, padx=5, pady=5)

        # 发送按钮
        Button(
            frame_group_send,
            text=BTN_SEND,
            command=lambda: self.__on_click_send_group_message()
        ).grid(row=3, padx=5, pady=5)

    def __init_manage_tab(self):
        """
        初始化管理选项卡

        :return: 无
        """

        f_manage = Frame(self.frame_manage, bg=BG_COLOR)
        f_manage.pack(padx=5, pady=5, expand=True)

        # 指定头指示
        Label(f_manage, text=MANAGE_GUIDE["commandHead"], bg=BG_COLOR).grid(
            row=0,
            column=0,
            padx=5,
            pady=5,
            sticky=E
        )

        # 指令头文本框
        self.entry_command_head = Entry(f_manage)
        self.entry_command_head.grid(row=0, column=1, padx=5, pady=5, sticky=EW)

        # 调试复选框
        self.debug_var = BooleanVar()
        checkbutton_debug = Checkbutton(
            f_manage,
            text=MANAGE_GUIDE["debug"],
            onvalue=True,
            offvalue=False,
            variable=self.debug_var,
            bg=BG_COLOR
        )
        checkbutton_debug.grid(row=1, column=0, columnspan=3, padx=5, pady=5)

        # 启用机器人
        self.enable_var = BooleanVar()
        checkbutton_enable = Checkbutton(
            f_manage,
            text=MANAGE_GUIDE["enable"],
            onvalue=True,
            offvalue=False,
            variable=self.enable_var,
            bg=BG_COLOR
        )
        checkbutton_enable.grid(row=2, column=0, columnspan=3, padx=5, pady=5)

        # 配置保存
        Button(
            f_manage,
            text=MANAGE_GUIDE["saveConfig"],
            command=self.__on_click_save_config
        ).grid(
            row=3,
            column=1,
            padx=5,
            pady=5,
            sticky=EW
        )

        # bot管理qq列表
        self.treeview_op_list = Treeview(
            f_manage,
            columns=[
                MANAGE_GUIDE["botOpQQ"]
            ],
            show="headings",
            selectmode=BROWSE
        )
        self.treeview_op_list.column(MANAGE_GUIDE["botOpQQ"], width=200)
        self.treeview_op_list.heading(MANAGE_GUIDE["botOpQQ"], text=MANAGE_GUIDE["botOpQQ"])
        self.treeview_op_list.grid(
            row=4,
            column=0,
            columnspan=3,
            rowspan=10,
            sticky=EW
        )

        # 列表右键
        self.treeview_op_list.bind("<Button-3>", self.__show_op_list_pop_up_menu)

        # 添加管理标签
        Label(f_manage, text=MANAGE_GUIDE["addOpQQ"], bg=BG_COLOR).grid(row=14, column=0, padx=5, pady=5)

        # 添加管理文本框
        self.entry_add_op = Entry(f_manage)
        self.entry_add_op.grid(row=14, column=1, padx=5, pady=5)

        # 添加添加按钮
        Button(
            f_manage,
            text=MANAGE_GUIDE["btnAddOpQQ"],
            command=lambda: self.__on_click_add_op()
        ).grid(row=14, column=2, padx=5, pady=5, sticky=EW)

    def __init_plugin_tab(self):
        """
        初始化插件选项卡

        :return: 无
        """

        # 指示标签
        Label(self.frame_plugin, text=PLUGIN_LABEL_TEXT, bg=BG_COLOR).pack(side=TOP)

        # 插件列表frame
        frame_plugin_list = Frame(self.frame_plugin, bg=BG_COLOR)
        frame_plugin_list.pack(
            side=TOP,
            expand=True,
            fill=BOTH,
            padx=5,
            pady=5
        )

        # 插件列表
        self.treeview_plugin_list = Treeview(
            frame_plugin_list,
            columns=[
                PLUGIN_GUIDE["pluginName"]
            ],
            show="headings",
            selectmode=BROWSE
        )
        self.treeview_plugin_list.pack(fill=BOTH, expand=True, side=LEFT)
        self.treeview_plugin_list.column(PLUGIN_GUIDE["pluginName"])
        self.treeview_plugin_list.heading(PLUGIN_GUIDE["pluginName"], text=PLUGIN_GUIDE["pluginName"])

        # 设定插件列表滚动条
        scrollbar_plugin_list = Scrollbar(frame_plugin_list)
        scrollbar_plugin_list.pack(fill="y", expand=True)
        self.treeview_plugin_list.config(yscrollcommand=scrollbar_plugin_list.set)
        scrollbar_plugin_list.config(command=self.treeview_plugin_list.yview)

    def __on_click_connect_event(self):
        """
        点击连接按钮事件

        :return: 无
        """

        if not GlobalValues.is_connected:
            # 如果是要连接

            # 存到全局使用变量
            GlobalValues.conn_host = self.entry_host.get()
            GlobalValues.conn_port = self.entry_port.get()
            GlobalValues.conn_authkey = self.entry_authkey.get()
            try:
                # 转换为整型后保存
                GlobalValues.conn_qq = int(self.entry_qq.get())
            except ValueError:
                self.label_login_status_bar.config(text=LOGIN_STATUS_BAR_TEXT["wrongQQ"], fg=STATUS_BAR_COLOR["failed"])
                return

            # 修改界面上的一些内容为不可修改
            self.__set_login_tools_active(False)

            # 修改按钮内容
            self.btn_connect.config(text=BTN_TEXT_CONN["disconnect"])

            # 修改状态栏内容
            self.label_login_status_bar.config(text=LOGIN_STATUS_BAR_TEXT["connecting"], fg=STATUS_BAR_COLOR["normal"])

            # 调用连接
            try:
                Conn.new_session_key()
            except (
                requests.exceptions.InvalidURL,
                requests.exceptions.ConnectionError,
            ):
                # 连接错误

                # 错误信息显示到状态栏
                self.label_login_status_bar.config(
                    text=LOGIN_STATUS_BAR_TEXT["connectFailed"],
                    fg=STATUS_BAR_COLOR["failed"]
                )

                # 修改文本框为可修改
                self.__set_login_tools_active(True)
                self.btn_connect.config(text=BTN_TEXT_CONN["connect"])
                return
            except WrongAuthkeyException:
                # 授权码错误

                # 显示到状态栏
                self.label_login_status_bar.config(
                    text=LOGIN_STATUS_BAR_TEXT["wrongAuthkey"],
                    fg=STATUS_BAR_COLOR["failed"]
                )

                # 修改文本框为可修改
                self.__set_login_tools_active(True)
                self.btn_connect.config(text=BTN_TEXT_CONN["connect"])
                return

            except BotNotExistException:
                # bot不存在错误
                self.label_login_status_bar.config(
                    text=LOGIN_STATUS_BAR_TEXT["qqNotExist"],
                    fg=STATUS_BAR_COLOR["failed"]
                )

                # 修改文本框为可修改
                self.__set_login_tools_active(True)
                self.btn_connect.config(text=BTN_TEXT_CONN["connect"])
                return

            self.label_login_status_bar.config(
                text=LOGIN_STATUS_BAR_TEXT["connected"],
                fg=STATUS_BAR_COLOR["passed"]
            )

            # 修改连接状态值
            GlobalValues.is_connected = True

            # 修改上次连接键值对
            ConfigOperation.modify_dict("lastConnection", {
                "host": GlobalValues.conn_host,
                "port": GlobalValues.conn_port,
                "authkey": GlobalValues.conn_authkey,
                "qq": GlobalValues.conn_qq
            })

            # 修改文件中自动连接开关
            ConfigOperation.modify_dict("autoConnect", self.auto_connect_var.get())

        else:
            # 如果要断开连接

            # 修改文本框为可修改
            self.__set_login_tools_active(True)

            # 修改按钮名称
            self.btn_connect.config(text=BTN_TEXT_CONN["connect"])

            # 修改属性值
            self.label_login_status_bar.config(
                text=LOGIN_STATUS_BAR_TEXT["disconnectSuccess"],
                fg=STATUS_BAR_COLOR["normal"]
            )

            # 释放session
            Conn.release_session_key()

            # 修改连接状态值
            GlobalValues.is_connected = False

    def __set_login_tools_active(self, active: bool):
        """
        修改界面上的一些内容为不可修改

        :param active: bool,如果为False则禁用掉文本框,否则启用
        :return: 无
        """
        if active:
            self.entry_host.config(state=ACTIVE)
            self.entry_port.config(state=ACTIVE)
            self.entry_authkey.config(state=ACTIVE)
            self.entry_qq.config(state=ACTIVE)
            self.checkbutton_auto_connect.config(state=ACTIVE)
        else:
            self.entry_host.config(state=DISABLED)
            self.entry_port.config(state=DISABLED)
            self.entry_authkey.config(state=DISABLED)
            self.entry_qq.config(state=DISABLED)
            self.checkbutton_auto_connect.config(state=DISABLED)

    def __on_close_root(self):
        """
        关闭窗口的事件
        :return: 无
        """

        # 如果正在连接则释放连接
        if GlobalValues.is_connected:
            Conn.release_session_key()

        # 杀掉root
        self.root.destroy()

    def __refresh(self):
        """
        用于刷新界面,在必要时调用

        :return: 无
        """

        def refresh_login_list():
            """
            刷新登录列表

            :return: 无
            """

            # 删除目前表中的所有内容
            self.treeview_login_list.delete(*self.treeview_login_list.get_children())

            # 把登录列表内容添加到显示中
            for one_record in LoginListOperation.get_list_from_file():
                self.treeview_login_list.insert("", index=END, values=(
                    one_record["host"],
                    one_record["port"],
                    one_record["authkey"],
                    one_record["qq"]
                ))

        def refresh_op_list():
            """
            刷新bot管理员qq列表

            :return: 无
            """

            # 删除目前表中的所有内容
            self.treeview_op_list.delete(*self.treeview_op_list.get_children())

            # 把内容添加到显示中
            for one_record in OpListOperation.get_list():
                self.treeview_op_list.insert("", index=END, values=(
                    one_record
                ))

        def refresh_config():
            """
            刷新配置

            :return: 无
            """
            # 重新获取config
            self.config_dict = ConfigOperation.get_dir_from_file()

            # 将文件中的内容显示到界面中
            self.entry_command_head.delete(0, END)
            self.entry_command_head.insert(END, self.config_dict["commandHead"])

            # 设置复选框默认勾选
            self.debug_var.set(self.config_dict["debug"])
            self.enable_var.set(self.config_dict["enable"])

            # 将内容设置到全局变量
            GlobalValues.command_head = self.config_dict["commandHead"]
            GlobalValues.debug_var = self.debug_var
            GlobalValues.enable_var = self.enable_var

        def refresh_plugin_list():
            # 获取插件名称
            plugin_names = PluginHandler.get_plugin_name_list()

            # 显示
            self.treeview_plugin_list.delete(*self.treeview_plugin_list.get_children())
            for name in plugin_names:
                self.treeview_plugin_list.insert("", index=END, values=(
                    name
                ))

        # 调用刷新登录列表
        refresh_login_list()

        # 调用刷新op列表
        refresh_op_list()

        # 刷新config显示
        refresh_config()

        # 刷新插件列表显示
        refresh_plugin_list()

    def __on_click_add_to_login_list(self):
        """
        将填写内容添加到列表中
        :return: 无
        """

        # 非空检测
        if [
            self.entry_host.get(),
            self.entry_port.get(),
            self.entry_authkey.get(),
            self.entry_qq.get()
        ] == [""] * 4:
            return

        # 调用添加登录项方法
        LoginListOperation.add_to_list(
            self.entry_host.get(),
            self.entry_port.get(),
            self.entry_authkey.get(),
            self.entry_qq.get()
        )

        # 刷新显示
        self.__refresh()

    def __on_double_click_login_list_content(self):
        """
        双击登录列表项目时,自动填充到右侧

        :return: 无
        """

        # 获取item的值
        item_list = self.treeview_login_list.item(self.treeview_login_list.focus(), "values")

        # 获取需要的项目并设置
        self.entry_host.delete(0, END)
        self.entry_host.insert(END, item_list[0])
        self.entry_port.delete(0, END)
        self.entry_port.insert(END, item_list[1])
        self.entry_authkey.delete(0, END)
        self.entry_authkey.insert(END, item_list[2])
        self.entry_qq.delete(0, END)
        self.entry_qq.insert(END, item_list[3])

    def __show_login_list_pop_up_menu(self, event):
        """
        显示右键菜单

        :param event: 事件
        :return: 无
        """
        def on_delete_event(item_id):
            """
            删除选项的事件

            :return: 无
            """

            # 删除该项
            LoginListOperation.remove_from_list(*self.treeview_login_list.item(item_id, "values"))
            self.treeview_login_list.delete(item_id)
            self.__refresh()

        # 获取选择对象
        iid = self.treeview_login_list.identify_row(event.y)

        # 如果有选择,则弹出右键菜单
        if iid:
            self.treeview_login_list.selection_set(iid)
            menu_pop_up = Menu(self.treeview_login_list, tearoff=False)
            menu_pop_up.add_command(
                label=POP_UP_MENU_DELETE_STR,
                command=lambda: on_delete_event(iid)
            )
            menu_pop_up.post(event.x_root, event.y_root)

    def __on_click_refresh_friend_list_event(self):
        """
        点击刷新好友列表事件

        :return: 无
        """
        try:
            # 如果未连接,则可能会抛出异常,此处直接弹出错误消息框
            friend_list = Conn.get_friend_list()
        except:
            messagebox.showerror(message=REFRESH_ERROR_MSG)
            return

        # 删除列表内容
        self.treeview_friend_list.delete(*self.treeview_friend_list.get_children())

        # 解析friend_list
        for friend_block in friend_list:
            self.treeview_friend_list.insert("", index=END, values=(
                friend_block["id"],
                friend_block["nickname"],
                friend_block["remark"]
            ))

    def __on_click_refresh_group_list_event(self):
        """
        点击刷新群列表事件

        :return: 无
        """
        try:
            # 如果未连接,则可能会抛出异常,此处直接弹出错误消息框
            group_list = Conn.get_group_list()
        except:
            messagebox.showerror(message=REFRESH_ERROR_MSG)
            return

        # 删除列表内容
        self.treeview_group_list.delete(*self.treeview_group_list.get_children())

        # 解析group_list
        for group_block in group_list:
            self.treeview_group_list.insert("", index=END, values=(
                group_block["id"],
                group_block["name"],
                group_block["permission"]
            ))

    def __on_click_send_friend_message(self):
        """
        点击发送消息给好友按钮

        :return: 无
        """

        # 获取到选中好友的值列表
        value_list = self.treeview_friend_list.item(self.treeview_friend_list.focus(), "values")

        try:
            # 获取qq并发送消息
            qq = value_list[0]
            message_chain = MessageChain()
            text = self.text_friend_send.get(1.0, END)
            if text == "\n":
                return
            message_chain.add_plain_text(text)
            Conn.send_friend_message(qq, message_chain)
            self.text_friend_send.delete(1.0, END)
        except:
            messagebox.showerror(message=SEND_ERROR_MSG)
            return

    def __on_click_send_group_message(self):
        """
        点击发送消息给群按钮

        :return: 无
        """

        # 获取到选中群的值列表
        value_list = self.treeview_group_list.item(self.treeview_group_list.focus(), "values")

        try:
            # 获取qq并发送消息
            qq = value_list[0]
            message_chain = MessageChain()
            text = self.text_group_send.get(1.0, END)
            if text == "\n":
                return
            message_chain.add_plain_text(text)
            Conn.send_group_message(qq, message_chain)
            self.text_group_send.delete(1.0, END)
        except:
            messagebox.showerror(message=SEND_ERROR_MSG)
            return



    def __on_click_add_op(self):
        """
        点击添加op按钮事件

        :return: 无
        """

        content = self.entry_add_op.get()

        # 如果添加op的文本框中没有东西,则不添加
        if content == "":
            return

        # 如果转换数字出错则不添加
        try:
            op_qq = int(content)
        except ValueError:
            return

        # 添加到op列表中
        OpListOperation.add_to_list(op_qq)

        # 刷新显示
        self.__refresh()

    def __show_op_list_pop_up_menu(self, event):
        """
        op列表右键菜单

        :return: 无
        """

        def on_delete_event():
            """
            删除选项的事件

            :return: 无
            """

            # 删除该项
            # 注意此处的强转,由于能够保证显示出来的内容一定只含有数字,故可以直接转换
            OpListOperation.remove_from_list(int(self.treeview_op_list.item(op_qq, "values")[0]))
            self.treeview_op_list.delete(op_qq)
            self.__refresh()

        # 获取选择对象
        op_qq = self.treeview_op_list.identify_row(event.y)

        # 如果有选择,则弹出右键菜单
        if op_qq:
            menu_pop_up = Menu(self.treeview_op_list, tearoff=False)
            self.treeview_op_list.selection_set(op_qq)
            menu_pop_up.add_command(
                label=POP_UP_MENU_DELETE_STR,
                command=lambda: on_delete_event()
            )
            menu_pop_up.post(event.x_root, event.y_root)

    def __on_click_save_config(self):
        """
        点击保存配置事件

        :return: 无
        """

        content = self.entry_command_head.get()

        # 如果为空,则不存入,但是刷新
        # 这样是为了保证点击后会显示原来的设置
        if content == "":
            self.__refresh()
            return

        ConfigOperation.modify_dict("commandHead", content)
        ConfigOperation.modify_dict("debug", self.debug_var.get())
        ConfigOperation.modify_dict("enable", self.enable_var.get())

        # 刷新
        self.__refresh()

        # 弹出对话框
        messagebox.showinfo(message=MANAGE_GUIDE["successSaveCommandHeadMsg"])

    def __auto_connect(self):
        if self.config_dict["autoConnect"]:
            self.__on_click_connect_event()
Пример #37
0
    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.player = StringVar()
        self.character = StringVar()
        self.dm = StringVar()
        self.str = StringVar()
        self.int = StringVar()
        self.wis = StringVar()
        self.dex = StringVar()
        self.con = StringVar()
        self.cha = StringVar()
        self.JPpoison = StringVar()
        self.JPwands = StringVar()
        self.JPparalysis = StringVar()
        self.JPbreath = StringVar()
        self.JPspell = StringVar()
        self.class_ = StringVar()
        self.race = StringVar()
        self.align = StringVar()
        self.AC = StringVar()
        self.HP = StringVar()
        self.maxHP = StringVar()
        self.XP_to_add = StringVar()
        self.XPbonus = StringVar()
        self.XPtotal = IntVar()
        self.level = StringVar()

        self.init_once()

        (
            self.baseXP,
            self.mainCarRace,
            self.mainCarClass) = self.classDifferenciation()
        self.remainingXP = StringVar()
        self.remainingXP.set(self.getRemainingXP())
        self.bonusXP = StringVar()
        self.bonusXP.set(self.getBonusXP())

        self.freeze = IntVar()
        self.freeze.set(1)

        Label(self, text="Player Name:").grid(row=0, column=0, columnspan=2)
        Label(self, text="Character Name :").grid(
            row=0, column=4, columnspan=2)
        Label(self, text="DM Name:").grid(row=0, column=8, columnspan=2)
        Label(self, text="STR:").grid(row=1, column=0)
        Label(self, text="INT:").grid(row=2, column=0)
        Label(self, text="WIS:").grid(row=3, column=0)
        Label(self, text="DEX:").grid(row=4, column=0)
        Label(self, text="CON:").grid(row=5, column=0)
        Label(self, text="CHA:").grid(row=6, column=0)
        Label(self, text="Poison/Deathray:").grid(row=1, column=2)
        Label(self, text="Wands:").grid(row=2, column=2)
        Label(self, text="Paralysis:").grid(row=3, column=2)
        Label(self, text="Dragon Breath:").grid(row=4, column=2)
        Label(self, text="Spells:").grid(row=5, column=2)
        Label(self, text="Armor Class").grid(row=1, column=4, columnspan=1)
        Label(self, text="Health Points").grid(row=1, column=5, columnspan=3)
        Label(self, text="  /  ").grid(row=2, column=6)
        Label(self, text="Class :").grid(row=3, column=4)
        Label(self, text="Race :").grid(row=4, column=4)
        Label(self, text="XP to add :").grid(row=7, column=0)
        Label(self, text="Remaining :").grid(row=8, column=0)
        Label(self, text="Bonus :").grid(row=7, column=2)
        Label(self, text="Alignment :").grid(row=3, column=6)
        Label(self, text="Level :").grid(row=9, column=0, columnspan=2)
        self.remainingLabel = Label(
            self,
            textvariable=self.remainingXP,
            relief=SUNKEN,
            width=5)
        self.remainingLabel.grid(row=8, column=1)
        self.bonusLabel = Label(
            self,
            textvariable=self.bonusXP,
            relief=SUNKEN,
            width=5)
        self.bonusLabel.grid(row=7, column=3)
        self.levelLabel = Label(
            self,
            textvariable=self.level,
            relief=SUNKEN,
            width=5)
        self.levelLabel.grid(row=9, column=2, columnspan=2)

        Eplayer = Entry(self, textvariable=self.player)
        Eplayer.grid(row=0, column=2, columnspan=2)
        Eplayer.bind(sequence='<KeyRelease>', func=self.refresh)

        Echaracter = Entry(self, textvariable=self.character)
        Echaracter.grid(row=0, column=6, columnspan=2)
        Echaracter.bind(sequence='<KeyRelease>', func=self.refresh)

        EDM = Entry(self, textvariable=self.dm)
        EDM.grid(row=0, column=10, columnspan=2)
        EDM.bind(sequence='<KeyRelease>', func=self.refresh)

        Estr = Entry(self, textvariable=self.str)
        Estr.grid(row=1, column=1)
        Estr.bind(sequence='<KeyRelease>', func=self.refresh)

        Eint = Entry(self, textvariable=self.int)
        Eint.grid(row=2, column=1)
        Eint.bind(sequence='<KeyRelease>', func=self.refresh)

        Ewis = Entry(self, textvariable=self.wis)
        Ewis.grid(row=3, column=1)
        Ewis.bind(sequence='<KeyRelease>', func=self.refresh)

        Edex = Entry(self, textvariable=self.dex)
        Edex.grid(row=4, column=1)
        Edex.bind(sequence='<KeyRelease>', func=self.refresh)

        Econ = Entry(self, textvariable=self.con)
        Econ.grid(row=5, column=1)
        Econ.bind(sequence='<KeyRelease>', func=self.refresh)

        Echa = Entry(self, textvariable=self.cha)
        Echa.grid(row=6, column=1)
        Echa.bind(sequence='<KeyRelease>', func=self.refresh)

        Entry(self, textvariable=self.JPpoison).grid(row=1, column=3)
        Entry(self, textvariable=self.JPwands).grid(row=2, column=3)
        Entry(self, textvariable=self.JPparalysis).grid(row=3, column=3)
        Entry(self, textvariable=self.JPbreath).grid(row=4, column=3)
        Entry(self, textvariable=self.JPspell).grid(row=5, column=3)
        Entry(self, textvariable=self.AC).grid(row=2, column=4)
        Entry(self, textvariable=self.HP).grid(row=2, column=5)
        Entry(self, textvariable=self.maxHP).grid(row=2, column=7)

        EXP = Entry(self, textvariable=self.XP_to_add)
        EXP.grid(row=7, column=1)
        EXP.bind(sequence='<KeyPress-Return>', func=self.addXP)

        OptionMenu(
            self, self.class_,
            "Class",
            "Warrior",
            "Wizard",
            "Thief",
            "Cleric").grid(row=3, column=5)
        OptionMenu(
            self, self.align,
            "Alignment",
            "Lawful Good",
            "Lawful Neutral",
            "Lawful Evil",
            "Neutral Good",
            "Neutral Neutral",
            "Neutral Evil",
            "Chaotic Good",
            "Chaotic Neutral",
            "Chaotic Evil").grid(row=3, column=7)
        OptionMenu(
            self, self.race,
            "Race",
            "Human",
            "Elf",
            "Dwarf",
            "Halfelin").grid(row=4, column=5)

        Button(
            self,
            text="Add XP",
            command=self.refresh,
            width=6).grid(row=10, column=3)
Пример #38
0
    def __init__(self, parent, url=None, buttonSEC=False, buttonRSS=False):
        super(DialogURL, self).__init__(parent)
        self.parent = parent
        parentGeometry = re.match("(\d+)x(\d+)[+]?([-]?\d+)[+]?([-]?\d+)",
                                  parent.geometry())
        dialogX = int(parentGeometry.group(3))
        dialogY = int(parentGeometry.group(4))
        self.accepted = False
        self.url = None
        self.transient(self.parent)
        self.title("Enter URL")
        self.urlVar = StringVar()
        self.urlVar.set(url if url is not None else "http://")

        frame = Frame(self)
        urlLabel = Label(frame, text=_("URL:"), underline=0)
        urlEntry = Entry(frame, textvariable=self.urlVar, width=60)
        urlEntry.focus_set()
        okButton = Button(frame, text=_("OK"), command=self.ok)
        cancelButton = Button(frame, text=_("Cancel"), command=self.close)
        if buttonSEC:
            usSecButton = Button(frame,
                                 text=_("SEC search"),
                                 command=self.usSec)
            usSecButton.grid(row=1, column=1, sticky=W, pady=3)
            ToolTip(
                usSecButton,
                text=
                _("Opens US SEC Edgar Company Search (in web browser)\n\n"
                  "(1) Find the company in web browser,\n"
                  "(2) Click 'documents' button for desired filing,\n"
                  "(3) Find 'data files' panel, instance document row, 'document' column,\n"
                  "(4) On instance document file name, right-click browser menu: 'copy shortcut',\n"
                  "(5) Come back to this dialog window,\n"
                  "(6) Ctrl-v (paste) shortcut into above URL text box,\n"
                  "(7) Click ok button to load instance document"),
                wraplength=480)
        if buttonRSS:
            rssButton = Button(frame, text=_("SEC RSS"), command=self.rssFeed)
            rssButton.grid(row=1, column=1, pady=3)
            ToolTip(rssButton,
                    text=_("Opens current US SEC Edgar RSS feed"),
                    wraplength=480)
        urlLabel.grid(row=0, column=0, sticky=W, pady=3, padx=3)
        urlEntry.grid(row=0, column=1, columnspan=3, sticky=EW, pady=3, padx=3)
        okButton.grid(row=1, column=2, sticky=E, pady=3)
        ToolTip(
            okButton,
            text=
            _("Opens above URL from web cache, downloading to cache if necessary"
              ),
            wraplength=240)
        cancelButton.grid(row=1, column=3, sticky=EW, pady=3, padx=3)
        ToolTip(cancelButton, text=_("Cancel operation"))

        frame.grid(row=0, column=0, sticky=(N, S, E, W))
        frame.columnconfigure(1, weight=1)
        window = self.winfo_toplevel()
        window.columnconfigure(0, weight=1)
        self.geometry("+{0}+{1}".format(dialogX + 50, dialogY + 100))

        self.bind("<Alt-u>", lambda *ignore: urlEntry.focus_set())
        self.bind("<Return>", self.ok)
        self.bind("<Escape>", self.close)

        self.protocol("WM_DELETE_WINDOW", self.close)
        self.grab_set()
        self.wait_window(self)
Пример #39
0
class PlotDialog:
    """ Display plot dialog for plotting multiple plot """
    def __init__(self,
                 parent,
                 plot1,
                 plot2,
                 marker=".",
                 linestyle="solid",
                 linewidth=1.5):
        """ PlotDialog constructor """
        self.__plots = [plot1, plot2]
        self.__marker = marker
        self.__linestyle = linestyle
        self.__linewidth = linewidth

        top = self.top = tkinter.Toplevel(parent)
        logger.log(
            logging.INFO, "[PlotDialog] Comparing two plots " + str(plot1) +
            " " + str(plot2))

        top_frame = tkinter.Frame(top, borderwidth=2, relief=tkinter.GROOVE)
        top_frame.pack(side=tkinter.TOP, fill=tkinter.X, padx=10, pady=10)

        self.__chkbx_g = tkinter.IntVar()
        self.__chkbx_g.set(1)
        self.__check_graph = Checkbutton(top_frame,
                                         text="Display graphs to compare",
                                         variable=self.__chkbx_g)
        self.__check_graph.grid(row=1, column=1, rowspan=1, padx=5, pady=5)
        self.__chkbx_d = tkinter.IntVar()
        self.__check_graph_diff = Checkbutton(top_frame,
                                              text="Display diff as graph",
                                              variable=self.__chkbx_d)
        self.__check_graph_diff.grid(row=1,
                                     column=2,
                                     rowspan=1,
                                     padx=5,
                                     pady=5)
        self.__chkbx_v = tkinter.IntVar()
        self.__check_graph_values = Checkbutton(top_frame,
                                                text="Display diff as values",
                                                variable=self.__chkbx_v)
        self.__check_graph_values.grid(row=2,
                                       column=2,
                                       rowspan=1,
                                       padx=5,
                                       pady=5)

        label_threshold = Label(top_frame, text="Diff threshold:", anchor="w")
        label_threshold.grid(row=1, column=3, padx=5, pady=5)
        self.__entry_threshold = Entry(top_frame, width=15)
        self.__entry_threshold.insert(tkinter.END, '0.1')
        self.__entry_threshold.grid(row=1,
                                    column=4,
                                    columnspan=1,
                                    rowspan=1,
                                    padx=5,
                                    pady=5)

        label_round = Label(top_frame, text="Diff round:", anchor="w")
        label_round.grid(row=2, column=3, padx=5, pady=5)
        self.__entry_round = Entry(top_frame, width=15)
        self.__entry_round.insert(tkinter.END, '2')
        self.__entry_round.grid(row=2,
                                column=4,
                                columnspan=1,
                                rowspan=1,
                                padx=5,
                                pady=5)

        display_button = Button(top_frame,
                                text="Display",
                                command=self.display,
                                width=15)
        display_button.grid(row=1, column=5, rowspan=1, padx=5, pady=5)

        clear_button = Button(top_frame,
                              text="Clear",
                              command=self.clear,
                              width=15)
        clear_button.grid(row=2, column=5, rowspan=1, padx=5, pady=5)

        title_button = Button(top_frame,
                              text="Add title",
                              command=self.add_title,
                              width=20)
        title_button.grid(row=1,
                          column=6,
                          columnspan=1,
                          rowspan=1,
                          padx=5,
                          pady=5)

        graph_frame = tkinter.Frame(top, borderwidth=2, relief=tkinter.GROOVE)
        graph_frame.pack(side=tkinter.BOTTOM,
                         padx=10,
                         pady=10,
                         fill=tkinter.BOTH,
                         expand=True)
        figure = Figure(figsize=(8, 4))
        figure.subplots_adjust(left=0.08, right=0.845, bottom=0.14)
        self.__graph = figure.add_subplot(111)

        self.__canvas = FigureCanvasTkAgg(figure, master=graph_frame)
        self.__canvas.draw()
        self.__canvas.get_tk_widget().pack(side=tkinter.TOP,
                                           fill=tkinter.BOTH,
                                           expand=1)

        toolbar = NavigationToolbar2Tk(self.__canvas, graph_frame)
        toolbar.update()
        self.__canvas.get_tk_widget().pack(side=tkinter.TOP,
                                           fill=tkinter.BOTH,
                                           expand=1)

        graph_compare_plot(self.__graph, plot1, plot2, self.__marker,
                           self.__linestyle, self.__linewidth)
        self.__canvas.draw()

    def display(self):
        """ Display in the graph frame """
        graph_clear(self.__graph)

        if self.__chkbx_g.get():
            graph_compare_plot(self.__graph, self.__plots[0], self.__plots[1],
                               self.__marker, self.__linestyle,
                               self.__linewidth)

        if self.__chkbx_d.get():
            graph_compare_plot_diff(self.__graph, self.__plots[0],
                                    self.__plots[1], self.__marker,
                                    self.__linestyle, self.__linewidth)

        if self.__chkbx_v.get():
            graph_compare_plot_values(self.__graph, self.__plots[0],
                                      self.__plots[1],
                                      float(self.__entry_threshold.get()),
                                      bool(self.__chkbx_d.get()),
                                      int(self.__entry_round.get()))
        self.__canvas.draw()

    def add_title(self):
        """ Add title to the graph"""
        title = simpledialog.askstring("Graph Title",
                                       "What is the title of the Graph?",
                                       parent=self.top)
        if title is not None and title != "":
            graph_add_title(self.__graph, title)
            self.__canvas.draw()

    def clear(self):
        """ Clear the graph frame """
        graph_clear(self.__graph)
        self.__canvas.draw()
Пример #40
0
class Query(Toplevel):
    """Base class for getting verified answer from a user.

    For this base class, accept any non-blank string.
    """
    def __init__(self,
                 parent,
                 title,
                 message,
                 *,
                 text0='',
                 used_names={},
                 _htest=False,
                 _utest=False):
        """Create popup, do not return until tk widget destroyed.

        Additional subclass init must be done before calling this
        unless  _utest=True is passed to suppress wait_window().

        title - string, title of popup dialog
        message - string, informational message to display
        text0 - initial value for entry
        used_names - names already in use
        _htest - bool, change box location when running htest
        _utest - bool, leave window hidden and not modal
        """
        Toplevel.__init__(self, parent)
        self.withdraw()  # Hide while configuring, especially geometry.
        self.parent = parent
        self.title(title)
        self.message = message
        self.text0 = text0
        self.used_names = used_names
        self.transient(parent)
        self.grab_set()
        windowingsystem = self.tk.call('tk', 'windowingsystem')
        if windowingsystem == 'aqua':
            try:
                self.tk.call('::tk::unsupported::MacWindowStyle', 'style',
                             self._w, 'moveableModal', '')
            except:
                pass
            self.bind("<Command-.>", self.cancel)
        self.bind('<Key-Escape>', self.cancel)
        self.protocol("WM_DELETE_WINDOW", self.cancel)
        self.bind('<Key-Return>', self.ok)
        self.bind("<KP_Enter>", self.ok)
        self.resizable(height=False, width=False)
        self.create_widgets()
        self.update_idletasks()  # Needed here for winfo_reqwidth below.
        self.geometry(  # Center dialog over parent (or below htest box).
            "+%d+%d" % (parent.winfo_rootx() +
                        (parent.winfo_width() / 2 - self.winfo_reqwidth() / 2),
                        parent.winfo_rooty() +
                        ((parent.winfo_height() / 2 -
                          self.winfo_reqheight() / 2) if not _htest else 150)))
        if not _utest:
            self.deiconify()  # Unhide now that geometry set.
            self.wait_window()

    def create_widgets(self):  # Call from override, if any.
        # Bind to self widgets needed for entry_ok or unittest.
        self.frame = frame = Frame(self, padding=10)
        frame.grid(column=0, row=0, sticky='news')
        frame.grid_columnconfigure(0, weight=1)

        entrylabel = Label(frame,
                           anchor='w',
                           justify='left',
                           text=self.message)
        self.entryvar = StringVar(self, self.text0)
        self.entry = Entry(frame, width=30, textvariable=self.entryvar)
        self.entry.focus_set()
        self.error_font = Font(name='TkCaptionFont',
                               exists=True,
                               root=self.parent)
        self.entry_error = Label(frame,
                                 text=' ',
                                 foreground='red',
                                 font=self.error_font)
        self.button_ok = Button(frame,
                                text='OK',
                                default='active',
                                command=self.ok)
        self.button_cancel = Button(frame, text='Cancel', command=self.cancel)

        entrylabel.grid(column=0, row=0, columnspan=3, padx=5, sticky=W)
        self.entry.grid(column=0,
                        row=1,
                        columnspan=3,
                        padx=5,
                        sticky=W + E,
                        pady=[10, 0])
        self.entry_error.grid(column=0,
                              row=2,
                              columnspan=3,
                              padx=5,
                              sticky=W + E)
        self.button_ok.grid(column=1, row=99, padx=5)
        self.button_cancel.grid(column=2, row=99, padx=5)

    def showerror(self, message, widget=None):
        #self.bell(displayof=self)
        (widget or self.entry_error)['text'] = 'ERROR: ' + message

    def entry_ok(self):  # Example: usually replace.
        "Return non-blank entry or None."
        self.entry_error['text'] = ''
        entry = self.entry.get().strip()
        if not entry:
            self.showerror('blank line.')
            return None
        return entry

    def ok(self, event=None):  # Do not replace.
        '''If entry is valid, bind it to 'result' and destroy tk widget.

        Otherwise leave dialog open for user to correct entry or cancel.
        '''
        entry = self.entry_ok()
        if entry is not None:
            self.result = entry
            self.destroy()
        else:
            # [Ok] moves focus.  (<Return> does not.)  Move it back.
            self.entry.focus_set()

    def cancel(self, event=None):  # Do not replace.
        "Set dialog result to None and destroy tk widget."
        self.result = None
        self.destroy()
Пример #41
0
class VadTest(Frame):
    """ A demo class that provides simple GUI for testing voice activity detection on microphone or wav file input. """
    def __init__(self, featurizer_path, input_device, wav_file, sample_rate,
                 auto_scale):
        """ Initialize the VadTest object:
        featurizer_path - path to the ELL featurizer to use
        input_device - id of the microphone to use
        wav_file - optional wav_file to use when you click play
        sample_rate - the sample rate to resample the incoming audio
        auto_scale - auto scale audio input to the range [-1, 1]
        """
        super().__init__()

        self.FEATURIZER_PATH_KEY = "featurizer_path"
        self.WAV_FILE_KEY = "wav_file"
        self.main_thread = get_ident()
        self.output_clear_time = 5000
        self.channels = 1
        self.init_ui()
        self.auto_scale = auto_scale

        self.get_settings_file_name()
        self.load_settings()

        self.max_spectrogram_width = 120
        self.spectrogram_image = None
        self.spectrogram_image_data = None
        self.show_spectrogram = True
        self.colormap_name = "inferno"
        self.min_value = 0.0
        self.max_value = 1.0
        self.update_minmax = True

        self.levels = []
        self.signals = []
        self.featurizer_path = None
        self.featurizer = None
        self.reading_input = False

        # Threads
        self.read_input_thread = None
        self.lock = Lock()
        self.main_thread = get_ident()
        self.message_queue = []
        self.animation = None

        # featurizer
        if featurizer_path:
            self.featurizer_path = featurizer_path
            self.settings[self.FEATURIZER_PATH_KEY] = featurizer_path
        elif self.FEATURIZER_PATH_KEY in self.settings:
            self.featurizer_path = self.settings[self.FEATURIZER_PATH_KEY]
        self.sample_rate = sample_rate

        self.input_device = input_device
        self.wav_filename = None
        self.wav_file = None
        if wav_file:
            self.wav_filename = wav_file
            self.settings[self.WAV_FILE_KEY] = wav_file
        if self.wav_filename is None and self.WAV_FILE_KEY in self.settings:
            self.wav_filename = self.settings[self.WAV_FILE_KEY]

        self.wav_file_list = None
        self.speaker = None
        self.microphone = None
        self.save_settings()  # in case we just changed it.

        if self.featurizer_path:
            self.load_featurizer_model(os.path.abspath(self.featurizer_path))
        else:
            self.show_output("Please specify and load a feature model")

        self.update_ui()

    def init_ui(self):
        self.master.title("VAD Test")
        self.pack(side="top", fill=BOTH, expand=True)

        # VAD Controls section for controlling these VAD settings:
        controls_frame = LabelFrame(self, text="Controls", height=30)
        Label(controls_frame, text="tau_up:").grid(row=0, column=0)
        self.tau_up = Entry(controls_frame, width=15)
        self.tau_up.grid(row=1, column=0)

        Label(controls_frame, text="tau_down:").grid(row=0, column=1)
        self.tau_down = Entry(controls_frame, width=15)
        self.tau_down.grid(row=1, column=1)

        Label(controls_frame, text="threshold_up:").grid(row=0, column=2)
        self.threshold_up = Entry(controls_frame, width=15)
        self.threshold_up.grid(row=1, column=2)

        Label(controls_frame, text="threshold_down:").grid(row=0, column=3)
        self.threshold_down = Entry(controls_frame, width=15)
        self.threshold_down.grid(row=1, column=3)

        Label(controls_frame, text="large_input:").grid(row=0, column=4)
        self.large_input = Entry(controls_frame, width=15)
        self.large_input.grid(row=1, column=4)

        Label(controls_frame, text="gain_att:").grid(row=0, column=5)
        self.gain_att = Entry(controls_frame, width=15)
        self.gain_att.grid(row=1, column=5)

        Label(controls_frame, text="level_threshold:").grid(row=0, column=6)
        self.level_threshold = Entry(controls_frame, width=15)
        self.level_threshold.grid(row=1, column=6)
        controls_frame.pack(side=TOP)

        # Input section
        input_frame = LabelFrame(self, text="Input")
        input_frame.bind("-", self.on_minus_key)
        input_frame.bind("+", self.on_plus_key)
        input_frame.pack(fill=X)
        self.play_button = Button(input_frame,
                                  text="Play",
                                  command=self.on_play_button_click)
        self.play_button.pack(side=RIGHT, padx=4)
        self.rec_button = Button(input_frame,
                                 text="Rec",
                                 command=self.on_rec_button_click)
        self.rec_button.pack(side=RIGHT, padx=4)
        self.wav_filename_entry = Entry(input_frame, width=24)
        self.wav_filename_entry.pack(fill=X)
        self.wav_filename_entry.delete(0, END)

        # Feature section
        features_frame = LabelFrame(self, text="Features")
        features_frame.pack(fill=X)

        features_control_frame = Frame(features_frame)
        features_control_frame.pack(fill=X)
        load_features_button = Button(features_control_frame,
                                      text="Load",
                                      command=self.on_load_featurizer_model)
        load_features_button.pack(side=RIGHT)
        self.features_entry = Entry(features_control_frame, width=8)
        self.features_entry.pack(fill=X)
        self.features_entry.delete(0, END)

        viz_frame = Frame(features_frame)
        viz_frame.bind("%w", self.on_resized)
        viz_frame.pack(fill=X)
        self.features_figure = Figure(figsize=(5, 4), dpi=96)
        self.subplot = self.features_figure.add_subplot(211)

        self.subplot2 = self.features_figure.add_subplot(212)

        self.canvas = FigureCanvasTkAgg(self.features_figure, master=viz_frame)
        self.canvas.draw()
        self.canvas.show()
        self.canvas.get_tk_widget().pack(side=TOP, fill=BOTH, expand=True)

        # Output section
        output_frame = LabelFrame(self, text="Output")
        output_frame.pack(fill=BOTH, expand=True)
        self.bind("<Configure>", self.on_resized)

        self.output_text = Text(output_frame)
        self.output_text.pack(fill=BOTH, padx=4, expand=True)

    def on_resized(self, event):
        window_size = event.width
        box = self.spectrogram_image.get_window_extent()
        scale = (box.x1 - box.x0) / self.max_spectrogram_width
        self.max_spectrogram_width = int((window_size * 0.8) / scale)
        self.setup_spectrogram_image()

    def load_featurizer_model(self, featurizer_path):
        """ load the given compiled ELL featurizer for use in processing subsequent audio input """
        if featurizer_path:
            self.featurizer = featurizer.AudioTransform(featurizer_path, 40)
            self.setup_spectrogram_image()

            self.vad = vad.VoiceActivityDetector(self.sample_rate,
                                                 self.featurizer.output_size)

            self.show_output("Feature input size: {}, output size: {}".format(
                self.featurizer.input_size, self.featurizer.output_size))

        self.init_data()

    def setup_spectrogram_image(self):
        """ this need to be called if you load a new feature model, because the featurizer output size might have
        changed. """
        if self.featurizer:
            dim = (self.featurizer.output_size, self.max_spectrogram_width)
            self.spectrogram_image_data = np.zeros(dim, dtype=float)
            self.subplot.clear()
            self.spectrogram_image = self.subplot.imshow(
                self.spectrogram_image_data,
                vmin=self.min_value,
                vmax=self.max_value,
                origin="lower",
                animated=True,
                cmap=pyplot.get_cmap(self.colormap_name))

    def accumulate_spectrogram_image(self, feature_data):
        """ accumulate the feature data into the spectrogram image """
        image_data = self.spectrogram_image_data
        feature_data = np.reshape(feature_data, [-1, 1])
        new_image = np.hstack(
            (image_data, feature_data))[:, -image_data.shape[1]:]
        image_data[:, :] = new_image

    def set_spectrogram_image(self):
        """ update the spectrogram image and the min/max values """
        self.lock.acquire()  # protect access to the shared state
        if self.update_minmax and self.show_spectrogram:
            min_value = np.min(self.spectrogram_image_data)
            max_value = np.max(self.spectrogram_image_data)
            if np.isfinite(min_value) and np.isfinite(max_value):
                self.min_value = min_value
                self.max_value = max_value
                eps = 0.1
                if self.max_value - self.min_value < eps:
                    self.max_value = self.min_value + eps

            self.spectrogram_image.set_clim(self.min_value, self.max_value)
        self.spectrogram_image.set_data(self.spectrogram_image_data)
        self.lock.release()

    def on_load_featurizer_model(self):
        """ called when user clicks the Load button for the feature model """
        filename = self.features_entry.get()
        filename = filename.strip('"')
        self.featurizer_path = filename
        self.get_sample_rate()
        self.settings[self.FEATURIZER_PATH_KEY] = filename
        self.save_settings()
        self.stop()
        self.load_featurizer_model(filename)

    def set_entry(self, e, value):
        s = str(value)
        if e.get() != s:
            e.delete(0, END)
            e.insert(0, s)

    def get_entry(self, e):
        v = e.get()
        return float(v)

    def update_ui(self):
        self.set_entry(self.wav_filename_entry, self.wav_filename)
        self.set_entry(self.features_entry, self.featurizer_path)
        self.set_entry(self.tau_up, vad.DEFAULT_TAU_UP)
        self.set_entry(self.tau_down, vad.DEFAULT_TAU_DOWN)
        self.set_entry(self.threshold_up, vad.DEFAULT_THRESHOLD_UP)
        self.set_entry(self.threshold_down, vad.DEFAULT_THRESHOLD_DOWN)
        self.set_entry(self.large_input, vad.DEFAULT_LARGE_INPUT)
        self.set_entry(self.gain_att, vad.DEFAULT_GAIN_ATT)
        self.set_entry(self.level_threshold, vad.DEFAULT_LEVEL_THRESHOLD)

    def read_ui_settings(self):
        self.vad.configure(self.get_entry(self.tau_up),
                           self.get_entry(self.tau_down),
                           self.get_entry(self.threshold_up),
                           self.get_entry(self.threshold_down),
                           self.get_entry(self.large_input),
                           self.get_entry(self.gain_att),
                           self.get_entry(self.level_threshold))

    def init_data(self):
        """ initialize the spectrogram_image_data based on the newly loaded model info """
        if self.featurizer:
            dim = (self.featurizer.output_size, self.max_spectrogram_width)
            self.spectrogram_image_data = np.zeros(dim, dtype=float)
            if self.spectrogram_image is not None:
                self.spectrogram_image.set_data(self.spectrogram_image_data)

    def get_settings_file_name(self):
        """ this app stores the various UI field values in a settings file in your temp folder
        so you don't always have to specify the full command line options """
        import tempfile
        temp = tempfile.gettempdir()
        self.settings_file_name = os.path.join(temp, "ELL", "Audio",
                                               "vad_test.json")

    def load_settings(self):
        """ load the previously saved settings from disk, if any """
        self.settings = {}
        try:
            if os.path.isfile(self.settings_file_name):
                with open(self.settings_file_name, "r") as f:
                    self.settings = json.load(f)
        except:
            self.show_output("error loading settings: {}".format(
                self.settings_file_name))
            self.settings = {}

    def save_settings(self):
        """ save the current settings to disk """
        settings_dir = os.path.dirname(self.settings_file_name)
        if not os.path.isdir(settings_dir):
            os.makedirs(settings_dir)
        with open(self.settings_file_name, "w") as f:
            json.dump(self.settings, f, indent=2)

    def on_rec_button_click(self):
        """ called when user clicks the record button, same button is used to "stop" recording. """
        if self.rec_button["text"] == "Rec":
            self.rec_button["text"] = "Stop"
            self.play_button["text"] = "Play"
            self.start_recording()
        else:
            self.rec_button["text"] = "Rec"
            self.on_stopped()

    def on_play_button_click(self):
        """ called when user clicks the record button, same button is used to "stop" playback """
        if self.play_button["text"] == "Play":
            self.play_button["text"] = "Stop"
            self.rec_button["text"] = "Rec"
            self.on_play()
        else:
            self.play_button["text"] = "Play"
            self.on_stopped()

    def on_play(self):
        """ called when user clicks the Play button """
        filename = self.wav_filename_entry.get()
        filename = filename.strip('"')
        self.wav_filename = filename
        self.settings[self.WAV_FILE_KEY] = filename
        self.save_settings()
        self.start_playing(filename)

    def on_stop(self):
        """ called when user clicks the Stop button """
        self.reading_input = False
        if self.wav_file:
            self.wav_file.close()
            self.wav_file = None
        if self.read_input_thread:
            self.read_input_thread.join()
            self.read_input_thread = None
        self.stop()

    def on_stopped(self):
        """ called when we reach the end of the wav file playback """
        self.play_button["text"] = "Play"
        self.on_stop()
        self.subplot2.clear()
        if (len(self.levels) > 0):
            levels = np.array(self.levels)
            levels /= np.max(levels)
            signals = np.array(self.signals)
            self.subplot2.plot(levels)
            self.subplot2.plot(signals)
            self.vad.reset()
        self.canvas.draw()
        self.canvas.show()
        self.levels = []
        self.signals = []

    def stop(self):
        """ called when user clicks the stop button, or we reach the end of a wav file input """
        # close streams
        if self.animation:
            self.animation.event_source.stop()
            self.animation = None
        if self.microphone:
            self.microphone.close()
        if self.speaker:
            self.speaker.close()
        if self.wav_file:
            self.wav_file.close()
            self.wav_file = None
        self.reading_input = False

    def get_wav_list(self):
        if self.wav_filename and os.path.isfile(self.wav_filename):
            full_path = os.path.abspath(self.wav_filename)
            dir_name = os.path.dirname(full_path)
            if not self.wav_file_list:
                print("wav file name: {}".format(full_path))
                print("looking for wav files in: {}".format(dir_name))
                self.wav_file_list = [
                    x for x in os.listdir(dir_name)
                    if os.path.splitext(x)[1] == ".wav"
                ]
                self.wav_file_list.sort()
        return self.wav_file_list

    def select_wav_file(self, filename):
        self.wav_filename = filename
        # show the file in the UI
        self.wav_filename_entry.delete(0, END)
        if self.wav_filename:
            self.wav_filename_entry.insert(0, self.wav_filename)
        # and automatically play the file.
        self.on_play()

    def on_minus_key(self, event):
        """ When user presses the plus button we reverse to the previous wav file in the current folder.
        This way you can easily step through all the training wav files """
        if self.get_wav_list():
            i = self.wav_file_list.index(os.path.basename(self.wav_filename))
            if i - 1 >= 0:
                next_wav_file = self.wav_file_list[i - 1]
                dir_name = os.path.dirname(self.wav_filename)
                self.select_wav_file(os.path.join(dir_name, next_wav_file))

    def on_plus_key(self, event):
        """ When user presses the plus button we advance to the next wav file in the current folder.
        This way you can easily step through all the training wav files """
        if self.get_wav_list():
            i = self.wav_file_list.index(os.path.basename(self.wav_filename))
            if i + 1 < len(self.wav_file_list):
                next_wav_file = self.wav_file_list[i + 1]
                dir_name = os.path.dirname(self.wav_filename)
                self.select_wav_file(os.path.join(dir_name, next_wav_file))

    def clear_output(self):
        """ remove some of the Output based a the timeout callback  """
        self.output_text.delete(1.0, 2.0)

    def process_output(self):
        """ show output that was queued by background thread """
        self.lock.acquire()
        messages = self.message_queue
        self.message_queue = []
        self.lock.release()
        for msg in messages:
            self.show_output(msg)

    def show_output(self, message):
        """ show output message, or queue it if we are on a background thread """
        if self.main_thread != get_ident():
            self.message_queue += [message]
            return

        for line in str(message).split('\n'):
            self.output_text.insert(END, "{}\n".format(line))

        self.output_text.see("end")  # scroll to end
        self.after(self.output_clear_time, self.clear_output)

    def start_playing(self, filename):
        """
        Play a wav file, and classify the audio. Note we use a background thread to read the
        wav file and we setup a UI animation function to draw the sliding spectrogram image, this way
        the UI update doesn't interfere with the smoothness of the audio playback
        """

        self.stop()

        self.read_ui_settings()
        self.reading_input = False
        self.wav_file = wav_reader.WavReader(self.sample_rate,
                                             self.channels,
                                             auto_scale=self.auto_scale)
        self.wav_file.open(filename, self.featurizer.input_size, self.speaker)
        self.setup_spectrogram_image()

        def update_func(frame_index):
            self.process_output()
            if not self.reading_input:
                self.after(1, self.on_stopped)
            self.set_spectrogram_image()
            return (self.spectrogram_image, )

        if self.animation:
            self.animation.event_source.stop()
        self.reading_input = True

        # Start animation timer for updating the UI (e.g. spectrogram image) (30 fps is usually fine)
        self.animation = animation.FuncAnimation(self.features_figure,
                                                 update_func,
                                                 interval=33,
                                                 blit=True)

        # start background thread to read and classify the audio.
        self.featurizer.open(self.wav_file)
        self.read_input_thread = Thread(target=self.on_read_features, args=())
        self.read_input_thread.daemon = True
        self.read_input_thread.start()

    def start_recording(self):
        """ Start recording audio from the microphone nd classify the audio. Note we use a background thread to
        process the audio and we setup a UI animation function to draw the sliding spectrogram image, this way
        the UI update doesn't interfere with the smoothness of the microphone readings """
        if self.microphone is None:
            self.microphone = microphone.Microphone(True, False)

        self.stop()
        self.read_ui_settings()
        num_channels = 1
        self.microphone.open(self.featurizer.input_size, self.sample_rate,
                             num_channels, self.input_device)

        def update_func(frame_index):
            # this is an animation callback to update the UI every 33 milliseconds.
            self.process_output()
            self.set_spectrogram_image()
            if not self.reading_input:
                self.after(1, self.on_stopped)
            return (self.spectrogram_image, )

        if self.animation:
            self.animation.event_source.stop()

        self.reading_input = True
        # Start animation timer for updating the UI (e.g. spectrogram image) (30 fps is usually fine)
        self.animation = animation.FuncAnimation(self.features_figure,
                                                 update_func,
                                                 interval=33,
                                                 blit=True)

        # start background thread to read and classify the recorded audio.
        self.featurizer.open(self.microphone)
        self.read_input_thread = Thread(target=self.on_read_features, args=())
        self.read_input_thread.daemon = True
        self.read_input_thread.start()

    def on_read_features(self):
        """ this is the background thread entry point.  So we read the feature data in a loop """
        try:

            while self.reading_input and self.featurizer:
                feature_data = self.featurizer.read()
                if feature_data is None:
                    break  # eof
                else:
                    signal = self.vad.process(feature_data)
                    self.levels += [self.vad.level]
                    self.signals += [signal]
                    self.lock.acquire()
                    if self.show_spectrogram:
                        self.accumulate_spectrogram_image(feature_data)
                    self.lock.release()
        except:
            errorType, value, traceback = sys.exc_info()
            print("### Exception reading input: " + str(errorType) + ": " +
                  str(value) + " " + str(traceback))
            while traceback:
                print(traceback.tb_frame.f_code)
                traceback = traceback.tb_next

        self.reading_input = False
Пример #42
0
class MainWindow(object):
    """Handles all the configuration and starts flashing window

    Args:
        master: Tkinter root window

    """

    def __init__(self, master: Tk):
        self.master = master
        master.title('P300 speller configuration')

        self.p300_window = None

        # Variables
        self.usable_images = []
        self.image_labels = []
        self.flash_sequence = []
        self.flash_image = None
        self.sequence_number = 0
        self.lsl_output = None

        self.config = ConfigParams()

        # Widget definition
        self.changeable_widgets = []

        self.config_file_label = Label(self.master, text='Config File:')
        self.config_file_label.grid(row=0, column=0)

        self.config_file_entry = Entry(self.master, textvariable=self.config.config_file_path)
        self.config_file_entry.grid(row=0, column=1, sticky=EW)
        self.changeable_widgets.append(self.config_file_entry)

        self.open_conf_btn = Button(self.master, text='Open config file',
                                    command=lambda: self.open_file_update_entry(self.config.config_file_path))
        self.open_conf_btn.grid(row=0, column=2, sticky=EW)
        self.changeable_widgets.append(self.open_conf_btn)

        self.use_conf_btn = Button(self.master, text='Apply', command=self.config.read_from_file)
        self.use_conf_btn.grid(row=0, column=3)
        self.changeable_widgets.append(self.use_conf_btn)

        self.save_settings_btn = Button(self.master, text='Save', command=self.config.save_to_file)
        self.save_settings_btn.grid(row=0, column=4)
        self.changeable_widgets.append(self.save_settings_btn)

        self.images_folder_label = Label(self.master, text='Images folder:')
        self.images_folder_label.grid(row=1, column=0)

        self.images_folder_entry = Entry(self.master, textvariable=self.config.images_folder_path)
        self.images_folder_entry.grid(row=1, column=1, sticky=EW)
        self.changeable_widgets.append(self.images_folder_entry)

        self.open_images_dir_btn = Button(self.master, text='Open image folder',
                                          command=lambda: self.open_folder_update_entry(
                                              self.config.images_folder_path))
        self.open_images_dir_btn.grid(row=1, column=2, sticky=EW)
        self.changeable_widgets.append(self.open_images_dir_btn)

        self.flash_image_label = Label(self.master, text='Flash image:')
        self.flash_image_label.grid(row=2, column=0)

        self.flash_image_file_entry = Entry(self.master, textvariable=self.config.flash_image_path)
        self.flash_image_file_entry.grid(row=2, column=1, sticky=EW)
        self.changeable_widgets.append(self.flash_image_file_entry)

        self.open_flash_dir_btn = Button(self.master, text='Open image',
                                         command=lambda: self.open_file_update_entry(
                                             self.config.flash_image_path))
        self.open_flash_dir_btn.grid(row=2, column=2, sticky=EW)
        self.changeable_widgets.append(self.open_flash_dir_btn)

        self.imagesize_label = Label(self.master, text='Imagesize (px):')
        self.imagesize_label.grid(row=3, column=0)

        self.imagesize_entry = Entry(self.master, textvariable=self.config.imagesize)
        self.imagesize_entry.grid(row=3, column=1, sticky=W)
        self.changeable_widgets.append(self.imagesize_entry)

        self.number_of_rows_label = Label(self.master, text='Number of rows:')
        self.number_of_rows_label.grid(row=4, column=0)

        self.number_of_rows_entry = Entry(self.master, textvariable=self.config.number_of_rows)
        self.number_of_rows_entry.grid(row=4, column=1, sticky=W)
        self.changeable_widgets.append(self.number_of_rows_entry)

        self.number_of_columns_label = Label(self.master, text='Number of columns:')
        self.number_of_columns_label.grid(row=5, column=0)

        self.number_of_columns_entry = Entry(self.master, textvariable=self.config.number_of_columns)
        self.number_of_columns_entry.grid(row=5, column=1, sticky=W)
        self.changeable_widgets.append(self.number_of_columns_entry)

        self.lsl_streamname_label = Label(self.master, text='LSL Streamname:')
        self.lsl_streamname_label.grid(row=6, column=0)

        self.lsl_streamname_entry = Entry(self.master, textvariable=self.config.lsl_streamname)
        self.lsl_streamname_entry.grid(row=6, column=1, sticky=W)
        self.changeable_widgets.append(self.lsl_streamname_entry)

        self.flash_duration_label = Label(self.master, text='Flash duration (ms):')
        self.flash_duration_label.grid(row=7, column=0)

        self.flash_duration_entry = Entry(self.master, textvariable=self.config.flash_duration)
        self.flash_duration_entry.grid(row=7, column=1, sticky=W)
        self.changeable_widgets.append(self.flash_duration_entry)

        self.break_duration_label = Label(self.master, text='Break duration (ms):')
        self.break_duration_label.grid(row=8, column=0)

        self.break_duration_entry = Entry(self.master, textvariable=self.config.break_duration)
        self.break_duration_entry.grid(row=8, column=1, sticky=W)
        self.changeable_widgets.append(self.break_duration_entry)

        self.flash_mode_label = Label(self.master, text='Flashmode:')
        self.flash_mode_label.grid(row=9, column=0)

        self.flash_mode_1_rb = Radiobutton(self.master,
                                           text='Rows and Columns (Sequence not pseudorandom yet!)',
                                           variable=self.config.flash_mode, value=1)
        self.flash_mode_1_rb.grid(row=9, column=1, sticky=W)
        self.changeable_widgets.append(self.flash_mode_1_rb)

        self.flash_mode_2_rb = Radiobutton(self.master, text='Single images', variable=self.config.flash_mode,
                                           value=2)
        self.flash_mode_2_rb.grid(row=10, column=1, sticky=W)
        self.changeable_widgets.append(self.flash_mode_2_rb)
        self.set_flash_mode_rbs()

        self.text_console = Text(self.master)
        self.text_console.grid(row=11, column=0, rowspan=4, columnspan=5)
        self.text_console.configure(state='disabled')

        self.close_button = Button(self.master, text='Close', command=master.quit)
        self.close_button.grid(row=15, column=0)

        self.open_button = Button(self.master, text='Open', command=self.open_p300_window)
        self.open_button.grid(row=15, column=3)
        self.changeable_widgets.append(self.open_button)

    def set_flash_mode_rbs(self):
        if self.config.flash_mode.get() is 1:
            self.flash_mode_1_rb.select()
        else:
            self.flash_mode_2_rb.select()

    def open_folder_update_entry(self, entry_var):
        new_path = filedialog.askdirectory()
        if new_path is not '':
            entry_var.set(new_path)

    def open_file_update_entry(self, entry_var):
        new_path = filedialog.askopenfilename()
        if new_path is not '':
            entry_var.set(new_path)

    def print_to_console(self, text_to_print):
        if not isinstance(text_to_print, str):
            text_to_print = str(text_to_print)

        self.text_console.configure(state='normal')
        self.text_console.insert('end', text_to_print + '\n')
        self.text_console.configure(state='disabled')

    def disable_all_widgets(self):
        for widget in self.changeable_widgets:
            widget.configure(state='disabled')
        self.master.iconify()

    def enable_all_widgets(self):
        for widget in self.changeable_widgets:
            widget.configure(state='normal')
        self.master.deiconify()

    def open_p300_window(self):
        p300_window_master = Toplevel(self.master)
        self.p300_window = P300Window(p300_window_master, self, self.config)
        self.disable_all_widgets()
Пример #43
0
class MarkovDemo(Frame):

    "MarkovDemo(master=None, **kw) -> MarkovDemo instance"

    TEXT = dict(height=2, width=46, wrap=WORD)  # Text Options
    GRID = dict(padx=5, pady=5)                 # Grid Options

    # Initialize a MarkovDemo instance with a GUI for interaction.

    def __init__(self, master=None, **kw):
        "Initialize the MarkovDemo instance's widgets and settings."
        super().__init__(master, **kw)
        self.build_widgets()
        self.place_widgets()
        self.setup_widgets()
        self.grid_rowconfigure(2, weight=1)
        self.grid_rowconfigure(3, weight=1)
        self.grid_columnconfigure(0, weight=1)
        self.key = self.primer = None

    def build_widgets(self):
        "Build the various widgets that will be used in the program."
        # Create processing frame widgets.
        self.processing_frame = LabelFrame(self, text='Processing Mode:')
        self.mode_var = StringVar(self, 'encode')
        self.decode_button = Radiobutton(self.processing_frame,
                                         text='Decode Cipher-Text',
                                         command=self.handle_radiobuttons,
                                         value='decode',
                                         variable=self.mode_var)
        self.encode_button = Radiobutton(self.processing_frame,
                                         text='Encode Plain-Text',
                                         command=self.handle_radiobuttons,
                                         value='encode',
                                         variable=self.mode_var)
        self.freeze_var = BooleanVar(self, False)
        self.freeze_button = Checkbutton(self.processing_frame,
                                         text='Freeze Key & Primer',
                                         command=self.handle_checkbutton,
                                         offvalue=False,
                                         onvalue=True,
                                         variable=self.freeze_var)
        # Create encoding frame widgets.
        self.encoding_frame = LabelFrame(self, text='Encoding Options:')
        self.chain_size_label = Label(self.encoding_frame, text='Chain Size:')
        self.chain_size_entry = Entry(self.encoding_frame)
        self.plain_text_label = Label(self.encoding_frame, text='Plain-Text:')
        self.plain_text_entry = Entry(self.encoding_frame)
        # Create input frame widgets.
        self.input_frame = LabelFrame(self, text='Input Area:')
        self.input_text = ScrolledText(self.input_frame, **self.TEXT)
        # Create output frame widgets.
        self.output_frame = LabelFrame(self, text='Output Area:')
        self.output_text = ScrolledText(self.output_frame, **self.TEXT)

    def place_widgets(self):
        "Place the widgets where they belong in the MarkovDemo frame."
        # Locate processing frame widgets.
        self.processing_frame.grid(sticky=EW, **self.GRID)
        self.decode_button.grid(row=0, column=0, **self.GRID)
        self.encode_button.grid(row=0, column=1, **self.GRID)
        self.freeze_button.grid(row=0, column=2, **self.GRID)
        # Locate encoding frame widgets.
        self.encoding_frame.grid(sticky=EW, **self.GRID)
        self.chain_size_label.grid(row=0, column=0, sticky=W, **self.GRID)
        self.chain_size_entry.grid(row=0, column=1, sticky=EW, **self.GRID)
        self.plain_text_label.grid(row=1, column=0, sticky=W, **self.GRID)
        self.plain_text_entry.grid(row=1, column=1, sticky=EW, **self.GRID)
        self.encoding_frame.grid_columnconfigure(1, weight=1)
        # Locate input frame widgets.
        self.input_frame.grid(sticky=NSEW, **self.GRID)
        self.input_text.grid(sticky=NSEW, **self.GRID)
        self.input_frame.grid_rowconfigure(0, weight=1)
        self.input_frame.grid_columnconfigure(0, weight=1)
        # Locate output frame widgets.
        self.output_frame.grid(sticky=NSEW, **self.GRID)
        self.output_text.grid(sticky=NSEW, **self.GRID)
        self.output_frame.grid_rowconfigure(0, weight=1)
        self.output_frame.grid_columnconfigure(0, weight=1)

    def setup_widgets(self):
        "Setup each widget's configuration for the events they handle."
        self.input_text.bind('<Key>', self.handle_key_events)
        self.input_text.bind('<Control-Key-a>', self.handle_control_a)
        self.input_text.bind('<Control-Key-/>', lambda event: 'break')
        self.output_text['state'] = DISABLED
        self.output_text.bind('<Control-Key-a>', self.handle_control_a)
        self.output_text.bind('<Control-Key-/>', lambda event: 'break')

    ########################################################################

    # Take care of any special event needing dedicated processing.

    def handle_radiobuttons(self):
        "Change the interface based on the encoding / decoding setting."
        if self.encrypting:
            self.freeze_button.grid()
            if not self.freeze_var.get():
                self.encoding_frame.grid()
        else:
            self.freeze_button.grid_remove()
            if not self.freeze_var.get():
                self.encoding_frame.grid_remove()
        self.handle_key_events(None)

    def handle_checkbutton(self):
        "Change the interface based on the key / primer freeze setting."
        if self.freeze_var.get():
            self.encoding_frame.grid_remove()
        else:
            self.encoding_frame.grid()

    def handle_key_events(self, event):
        "Schedule refreshing the output area after an input area event."
        if event is None or event.char and event.state | 0o11 == 0o11:
            self.after_idle(self.refresh)

    @staticmethod
    def handle_control_a(event):
        "Select all text in the widget associated with the given event."
        event.widget.tag_add(SEL, 1.0, END + '-1c')
        return 'break'

    ########################################################################

    # Handle interface's updates when either encoding or decoding.

    def refresh(self):
        "Refresh the output based on the value of the input."
        text = self.input_text.get(1.0, END + '-1c')
        if not text:
            self.output = text
        elif self.encrypting:
            self.encode(text)
        else:
            self.decode(text)

    def output(self, value):
        "Set the text in the output area to the string value."
        self.output_text['state'] = NORMAL
        self.output_text.delete(1.0, END)
        self.output_text.insert(END, value)
        if self.encrypting and self.freeze_var.get():
            self.output_text.see(END)
        self.output_text['state'] = DISABLED

    output = property(fset=output, doc='Output area property.')

    @property
    def chain_size(self):
        "Chain size for the Markov chains used when encrypting."
        try:
            value = ast.literal_eval(self.chain_size_entry.get())
            assert isinstance(value, int) and 2 <= value <= 256
            return value
        except:
            self.chain_size_entry.delete(0, END)
            self.chain_size_entry.insert(0, '2')
            return 2

    @property
    def plain_text(self):
        "Plain text or ignored characters in encryption process."
        try:
            value = self.repr_to_obj(self.plain_text_entry.get(), '')
            assert isinstance(value, str)
            return value
        except:
            self.plain_text_entry.delete(0, END)
            return ''

    ########################################################################

    # Encrypt a string for display in the interface's output area.

    def encode(self, string):
        "Encode the string and show the cipher-text in the output."
        try:
            cipher = self.build_cipher(string)
        except ValueError:
            self.output = ''
        except:
            self.output = traceback.format_exc()
        else:
            self.output = self.build_header() + '\n\n' + cipher

    def build_cipher(self, string):
        "Build cipher-text based on plain-text and return answer."
        if self.key and self.freeze_var.get():
            cipher, primer = me.encrypt_str(string, self.key, self.primer)
        else:
            args = string, self.chain_size, self.plain_text
            cipher, self.key, self.primer = me.auto_encrypt_str(*args)
        return cipher

    def build_header(self):
        "Build header from key and primer values in current use."
        header = '\n'.join(map(self.bytes_to_repr, self.key.data))
        header += '\n' + self.bytes_to_repr(self.primer.data)
        return header

    ########################################################################

    # Decrypt a string for display in the interface's output area.

    def decode(self, string):
        "Decode encrypted message and display plain-text in output."
        try:
            cipher = self.extract_keys(string)
            text = self.extract_text(cipher)
        except ValueError:
            self.output = ''
        except:
            self.output = traceback.format_exc()
        else:
            self.output = text

    def extract_keys(self, string):
        "Extract keys to decryption and return the cipher-text area."
        header, cipher = string.split('\n\n', 1)
        *key, primer = map(self.repr_to_obj, header.split('\n'))
        self.key, self.primer = me.Key(tuple(key)), me.Primer(primer)
        return cipher

    def extract_text(self, string):
        "Extract text message from string using built key and primer."
        text, primer = me.decrypt_str(string, self.key, self.primer)
        return text

    ########################################################################

    # Provide some special methods to simplify the program's code.

    @property
    def encrypting(self):
        "Encrypting boolean stating current operations mode."
        return {'encode': True, 'decode': False}[self.mode_var.get()]

    @staticmethod
    def bytes_to_repr(obj):
        "Convert bytes object into suitable representation."
        if not isinstance(obj, bytes):
            raise TypeError('Object must be a bytes instance!')
        return repr(obj)[2:-1]

    @staticmethod
    def repr_to_obj(string, prefix='b'):
        "Convert representation into an equivalent object."
        for template in '{}"{}"', "{}'{}'":
            try:
                return ast.literal_eval(template.format(prefix, string))
            except:
                pass
        raise ValueError('Cannot convert {!r} to object!'.format(string))

    @classmethod
    def main(cls):
        "Create context for demo and run a test instance."
        NoDefaultRoot()
        root = Tk()
        root.minsize(420, 330)
        root.title('Markov Demo 2')
        test = cls(root)
        test.grid(sticky=NSEW)
        root.grid_rowconfigure(0, weight=1)
        root.grid_columnconfigure(0, weight=1)
        root.mainloop()
Пример #44
0
    def __init__(self, master):
        # create dictionary of possible messages to deliver to user
        self.messages = {}
        self.messages['instructions'] = 'Type up to three input variables in the boxes below and click compute. ' \
                                        'Enter all variables in units based on meters, seconds, and degrees.'

        # create frame within main window to hold widgets
        mainframe = Frame(master)
        mainframe.grid()

        # create template of necessary variables for auto-generation
        dict_list = ['v', 'angle', 'vx', 'viy', 'vfy', 't', 'deltax', 'deltay']

        # create label to hold instructions and other messages
        self.current_message = StringVar()
        self.current_message.set(self.messages['instructions'])
        Label(mainframe, textvariable=self.current_message).grid(row=0,
                                                                 columnspan=3,
                                                                 sticky='we')

        # create descriptive text labels (can't auto-generate from template)
        Label(mainframe, text='Launch Speed:', justify=RIGHT).grid(column=0,
                                                                   row=1,
                                                                   sticky='e')
        Label(mainframe, text='Launch Angle:').grid(column=0,
                                                    row=2,
                                                    sticky='e')
        Label(mainframe, text='Horizontal Velocity:').grid(column=0,
                                                           row=3,
                                                           sticky='e')
        Label(mainframe, text='Initial Vertical Velocity:').grid(column=0,
                                                                 row=4,
                                                                 sticky='e')
        Label(mainframe, text='Final Vertical Velocity:').grid(column=0,
                                                               row=5,
                                                               sticky='e')
        Label(mainframe, text='Time:').grid(column=0, row=6, sticky='e')
        Label(mainframe, text='Range').grid(column=0, row=7, sticky='e')
        Label(mainframe, text='Vertical Displacement:').grid(column=0,
                                                             row=8,
                                                             sticky='e')

        # create compute button
        Button(mainframe, text="Solve",
               command=self.compute).grid(row=9, columnspan=3, sticky='ew')

        # create dictionaries to store tk DoubleVars
        # user_entries stores information typed by the user
        # display_entries stores information returned from solve method
        self.user_entries = {}
        self.display_entries = {}

        # auto-generate necessary DoubleVars and necessary widgets in rows 1-8
        for key in dict_list:
            self.user_entries[key] = DoubleVar(value='')
            self.display_entries[key] = StringVar(value='Not Calculated')
            temp = Entry(mainframe,
                         textvariable=self.user_entries[key],
                         width=10)
            temp.grid(column=1, row=dict_list.index(key) + 1)
            temp = Label(mainframe, textvariable=self.display_entries[key])
            temp.grid(column=2, row=dict_list.index(key) + 1, sticky='e')
Пример #45
0
    def initUI(self):
        self.parent.title("Calculator")

        Style().configure("TButton", padding=(0, 5, 0, 5),
            font='serif 14')
        # set up internal padding of cells, left,top,right, bottom.  From label
        # to edge of cell box

        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)
        # padding on each side of row.

        entry = Entry(self)
        entry.grid(row=0, columnspan=4, sticky=W+E)
        # unclear meaning.  The colspan says the entry
        # field spans at least four columns, but the stick seems to
        # to do nothing.  It is supposed to make it fill the grid space.

        cls = Button(self, text="Cls")
        cls.grid(row=1, column=0)
        bck = Button(self, text="Back")
        bck.grid(row=1, column=1)
        lbl = Button(self)
        lbl.grid(row=1, column=2)
        clo = Button(self, text="Close")
        clo.grid(row=1, column=3)
        sev = Button(self, text="7")
        sev.grid(row=2, column=0)
        eig = Button(self, text="8")
        eig.grid(row=2, column=1)
        nin = Button(self, text="9")
        nin.grid(row=2, column=2)
        div = Button(self, text="/")
        div.grid(row=2, column=3)

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

        one = Button(self, text="1")
        one.grid(row=4, column=0)
        two = Button(self, text="2")
        two.grid(row=4, column=1)
        thr = Button(self, text="3")
        thr.grid(row=4, column=2)
        mns = Button(self, text="-")
        mns.grid(row=4, column=3)

        zer = Button(self, text="0")
        zer.grid(row=5, column=0)
        dot = Button(self, text=".")
        dot.grid(row=5, column=1)
        equ = Button(self, text="=")
        equ.grid(row=5, column=2)
        pls = Button(self, text="+")
        pls.grid(row=5, column=3)

        self.pack()
Пример #46
0
class ModelFrame(LabelFrame):
	
	topPadding = 12

	def __init__(self,parent):        
		LabelFrame.__init__(self,parent,text="Model",borderwidth=5)
		
		self.selection = tkinter.IntVar()
		
		self.exponential = Radiobutton(self,text="Exponential model",variable=self.selection,value=Model.EXP.value,command=self.changeSelection)
		self.powerlaw = Radiobutton(self,text="Power law model",variable=self.selection,value=Model.POW.value,command=self.changeSelection)
		self.weibull = Radiobutton(self,text="Weibull model",variable=self.selection,value=Model.WEI.value,command=self.changeSelection)

		self.exponential.grid(row=0,column=0,sticky="W",padx=10,pady=(self.topPadding,5))
		self.powerlaw.grid(row=1,column=0,sticky="W",padx=10,pady=5)
		self.weibull.grid(row=2,column=0,sticky="W",padx=10,pady=(5,0))
		
		seperator = Separator(self, orient=tkinter.VERTICAL)
		seperator.grid(row=0, column=1, rowspan=3, sticky="NS", padx=(20,10), pady=(self.topPadding,0))
		
		## Exponential setup

		self.expNumberOfSegments_L = Label(self,text="Number of segments: ")
		self.expNumberOfSegments_E = Entry(self,width=5, justify="right")

		self.expNumberOfSegments_E.insert(0, settings.EXP_DEFAULT_NUMBER_OF_SEGMENTS)

		self.expWidgets = [self.expNumberOfSegments_L,self.expNumberOfSegments_E]
		
		## Power law setup

		self.powProximalLimit_L = Label(self,text="Proximal limit of integration: ")
		self.powProximalLimit_E = Entry(self,width=5, justify="right")
		self.powDistalLimit_L = Label(self,text="Distal limit of integration: ")
		self.powDistalLimit_E = Entry(self,width=5, justify="right")

		self.powProximalLimit_E.insert(0, settings.POW_DEFAULT_PROXIMAL_LIMIT)
		self.powDistalLimit_E.insert(0, settings.POW_DEFAULT_DISTAL_LIMIT)

		self.powWidgets = [self.powProximalLimit_L,self.powProximalLimit_E,
						   self.powDistalLimit_L,self.powDistalLimit_E]
		
		## Weibull setup

		self.weiNumberOfRuns_L = Label(self,text="Number of runs: ")
		self.weiNumberOfRuns_E = Entry(self,width=5, justify="right")
		self.weiIterationsPerRun_L = Label(self,text="Iterations per run: ")
		self.weiIterationsPerRun_E = Entry(self,width=5, justify="right")

		self.weiEstimatedTime_L = Label(self,text="Estimated time (s): ")
		self.weiEstimatedTime_E = CustomEntry(self,width=5, justify="right")
		self.weiEstimatedTime_E.setUserEditable(False)

		self.weiLambdaLowerBoundL = Label(self,text="\u03BB lower bound:")
		self.weiLambdaUpperBoundL = Label(self,text="\u03BB upper bound:")
		self.weiLambdaLowerBoundE = Entry(self,width=5, justify="right")
		self.weiLambdaUpperBoundE = Entry(self,width=5, justify="right")

		self.weiKLowerBoundL = Label(self,text="k lower bound:")
		self.weiKUpperBoundL = Label(self,text="k upper bound:")
		self.weiKLowerBoundE = Entry(self,width=5, justify="right")
		self.weiKUpperBoundE = Entry(self,width=5, justify="right")

		self.weiNumberOfRuns_E.insert(0, settings.WEI_DEFAULT_NUMBER_OF_RUNS)
		self.weiIterationsPerRun_E.insert(0, settings.WEI_DEFAULT_ITERATIONS_PER_RUN)
		self.weiLambdaLowerBoundE.insert(0, settings.WEI_DEFAULT_LAMBDA_LOWER_BOUND)
		self.weiLambdaUpperBoundE.insert(0, settings.WEI_DEFAULT_LAMBDA_UPPER_BOUND)
		self.weiKLowerBoundE.insert(0, settings.WEI_DEFAULT_K_LOWER_BOUND)
		self.weiKUpperBoundE.insert(0, settings.WEI_DEFAULT_K_UPPER_BOUND)

		
		self.weiWidgets = [self.weiNumberOfRuns_L,self.weiNumberOfRuns_E,
						   self.weiIterationsPerRun_L,self.weiIterationsPerRun_E,
						   self.weiEstimatedTime_L,self.weiEstimatedTime_E,
						   self.weiLambdaLowerBoundL,self.weiLambdaUpperBoundL,self.weiLambdaLowerBoundE,self.weiLambdaUpperBoundE,
						   self.weiKLowerBoundL,self.weiKUpperBoundL,self.weiKLowerBoundE,self.weiKUpperBoundE]
		
		## General

		self.currentWidgets = []
		self.selection.set(Model.EXP.value)
		self.changeSelection()
		
	def changeSelection(self):
		
		for widget in self.currentWidgets:
			widget.grid_remove()

		modelType = Model(self.selection.get())
		
		sX = 10
		bX = 20
		
		if modelType == Model.EXP:
			self.expNumberOfSegments_L.grid(row=0,column=2,padx=(bX,sX),pady=(self.topPadding,5),sticky="W")
			self.expNumberOfSegments_E.grid(row=0,column=3,padx=(sX,bX),pady=(self.topPadding,5),sticky="W")
			self.currentWidgets = self.expWidgets
		elif modelType == Model.POW:
			self.powProximalLimit_L.grid(row=0,column=2,padx=(bX,sX),pady=(self.topPadding,5),sticky="W")
			self.powProximalLimit_E.grid(row=0,column=3,padx=(sX,bX),pady=(self.topPadding,5),sticky="W")
			self.powDistalLimit_L.grid(row=1,column=2,padx=(bX,sX),pady=5,sticky="W")
			self.powDistalLimit_E.grid(row=1,column=3,padx=(sX,bX),pady=5,sticky="W")
			self.currentWidgets = self.powWidgets
		elif modelType == Model.WEI:
			self.weiNumberOfRuns_L.grid(row=0,column=2,padx=(bX,sX),pady=(self.topPadding,5),sticky="W")
			self.weiNumberOfRuns_E.grid(row=0,column=3,padx=(sX,bX),pady=(self.topPadding,5),sticky="W")
			self.weiIterationsPerRun_L.grid(row=1,column=2,padx=(bX,sX),pady=5,sticky="W")
			self.weiIterationsPerRun_E.grid(row=1,column=3,padx=(sX,bX),pady=5,sticky="W")
			self.weiEstimatedTime_L.grid(row=2,column=2,padx=(bX,sX),pady=5,sticky="W")
			self.weiEstimatedTime_E.grid(row=2,column=3,padx=(sX,bX),pady=5,sticky="W")
			
			self.weiLambdaLowerBoundL.grid(row=0,column=4,padx=(bX,sX),pady=(self.topPadding,5),sticky="W")
			self.weiLambdaLowerBoundE.grid(row=0,column=5,padx=(sX,bX),pady=(self.topPadding,5))
			self.weiLambdaUpperBoundL.grid(row=1,column=4,padx=(bX,sX),pady=5,sticky="W")
			self.weiLambdaUpperBoundE.grid(row=1,column=5,padx=(sX,bX),pady=5)
			
			self.weiKLowerBoundL.grid(row=0,column=6,padx=(bX,sX),pady=(self.topPadding,5),sticky="W")
			self.weiKLowerBoundE.grid(row=0,column=7,padx=(sX,sX),pady=(self.topPadding,5))
			self.weiKUpperBoundL.grid(row=1,column=6,padx=(bX,sX),pady=5,sticky="W")
			self.weiKUpperBoundE.grid(row=1,column=7,padx=(sX,sX),pady=5)
			
			self.currentWidgets = self.weiWidgets
	
	def getModelDetails(self):
		modelType = Model(self.selection.get())
		values = [modelType]

		if modelType == Model.EXP:
			numberOfSegments = helper_functions.validateValue(
									self.expNumberOfSegments_E.get(),
									"The number of exponential segments must be 1 \u2264 n \u2264 " + str(settings.EXP_MAX_NUMBER_OF_SEGMENTS),
									"int",
									lowerBound=1,
									upperBound=settings.EXP_MAX_NUMBER_OF_SEGMENTS)
			values.append(numberOfSegments)
			
		elif modelType == Model.POW:
			proximalLimitKM = helper_functions.validateValue(
									self.powProximalLimit_E.get(),
									"The proximal limit of integration must be 0 \u2264 x \u2264 \u221E",
									"float",
									strictLowerBound=0,
									strictUpperBound=float('inf'))
			proximalLimitKM /= SQRT_PI
			
			distalLimitKM = helper_functions.validateValue(
									self.powDistalLimit_E.get(),
									"The distal limit of integration must be prox \u2264 x \u2264 \u221E",
									"float",
									strictLowerBound=proximalLimitKM,
									strictUpperBound=float('inf'))
			distalLimitKM /= SQRT_PI
			
			values.extend([proximalLimitKM,distalLimitKM])
			
		elif modelType == Model.WEI:
			numberOfRuns = helper_functions.validateValue(
									self.weiNumberOfRuns_E.get(),
									"The number of runs must be greater than 0",
									"int",
									strictLowerBound=0)
			
			iterationsPerRun = helper_functions.validateValue(
									self.weiIterationsPerRun_E.get(),
									"The number of iterations must be greater than 0",
									"int",
									strictLowerBound=0)
			
			lambdaLowerBound = helper_functions.validateValue(
									self.weiLambdaLowerBoundE.get(),
									"The lower bound for \u03BB must be a decimal",
									"float")
			  
			lambdaUpperBound = helper_functions.validateValue(
									self.weiLambdaUpperBoundE.get(),
									"The upper bound for \u03BB must be greater than the lower bound",
									"float",
									strictLowerBound=lambdaLowerBound)
			
			kLowerBound = helper_functions.validateValue(
									self.weiKLowerBoundE.get(),
									"The lower bound for k must be numeric and less than 2",
									"float",
									strictUpperBound=2)
												
			kUpperBound = helper_functions.validateValue(
									self.weiKUpperBoundE.get(),
									"The upper bound for k must be greater than the lower bound and less than or equal to 2",
									"float",
									strictLowerBound=kLowerBound,
									upperBound=2)
			
			values.extend([numberOfRuns,iterationsPerRun,[[lambdaLowerBound,lambdaUpperBound],[kLowerBound,kUpperBound]]])
		
		return values
Пример #47
0
    def build(self):
        """widget construction

        Parameters
        ----------
        None

        Results
        -------
        None
        """

        fr1 = LabelFrame(self.fr0, text='rgb')
        fr1.grid(column=0, row=0, sticky='news')

        rl0 = Label(fr1, text='red  ')
        rl0.grid(column=0, row=0, sticky='s')

        self.rcan = Canvas(fr1, width=self.canvas_w, height=self.canvas_h, bd=0,
                           highlightthickness=0)
        self.rcan.grid(column=1, row=0, sticky='s')

        rsc = TtkScale(fr1, from_=0, to=255, variable=self.rvar, orient='horizontal',
                       length=self.scale_l, command=self.rhandle, tickinterval=20)
        rsc.grid(column=1, row=1, sticky='news')

        rsb = Spinbox(fr1, from_=0, to=255, textvariable=self.rvar,
                      command=self.rhandle, width=5)
        rsb.grid(column=2, row=1, sticky='nw')

        rel = Label(fr1, height=1)
        rel.grid(column=2, row=2)

        gl0 = Label(fr1, text='green')
        gl0.grid(column=0, row=3)

        self.gcan = Canvas(fr1, width=self.canvas_w, height=self.canvas_h, bd=0,
                           highlightthickness=0)
        self.gcan.grid(column=1, row=3, sticky='s')

        gsc = TtkScale(fr1, from_=0, to=255, variable=self.gvar, orient='horizontal',
                       length=self.scale_l, command=self.ghandle, tickinterval=20)
        gsc.grid(column=1, row=4, sticky='news')

        gsb = Spinbox(fr1, from_=0, to=255, textvariable=self.gvar,
                      command=self.ghandle, width=5)
        gsb.grid(column=2, row=4, sticky='nw')

        gel = Label(fr1, height=1)
        gel.grid(column=2, row=5)

        bl0 = Label(fr1, text='blue ')
        bl0.grid(column=0, row=6, sticky='s')

        self.bcan = Canvas(fr1, width=self.canvas_w, height=self.canvas_h, bd=0,
                           highlightthickness=0)
        self.bcan.grid(column=1, row=6, sticky='n')

        bsc = TtkScale(fr1, from_=0, to=255, variable=self.bvar, orient='horizontal',
                       length=self.scale_l, command=self.bhandle, tickinterval=20)
        bsc.grid(column=1, row=7, sticky='news')

        bsb = Spinbox(fr1, from_=0, to=255, textvariable=self.bvar,
                      command=self.bhandle, width=5)
        bsb.grid(column=2, row=7, sticky='nw')

        bel = Label(fr1, height=1)
        bel.grid(column=2, row=8)

        fr3 = LabelFrame(self.fr0, text='colour mix')
        fr3.grid(column=1, row=0, sticky='nw')

        self.cmcan = cmcan = Canvas(fr3, width=30, height=30, bd=0,
                                    highlightthickness=0)
        cmcan.grid(column=0, row=0, sticky='n', columnspan=2)
        cmcan.grid_propagate(0)
        vdraw_gradient(self.cmcan, (255, 0, 0), alpha=255)

        cml = Label(fr3, text='hash\nvalue')
        cml.grid(column=0, row=1)

        ent0 = Entry(fr3, width=8, textvariable=self.evar)
        ent0.grid(column=1, row=1)

        fr2 = LabelFrame(self.fr0, text='opacity')
        fr2.grid(column=0, row=1, sticky='news')

        al0 = Label(fr2, text='alpha')
        al0.grid(column=0, row=0, sticky='s')

        self.acan = Canvas(fr2, width=self.canvas_w, height=self.canvas_h, bd=0,
                           highlightthickness=0)
        self.acan.grid(column=1, row=0, sticky='n')

        asc = TtkScale(fr2, from_=0, to=255, variable=self.avar, orient='horizontal',
                       length=self.scale_l, command=self.ahandle, tickinterval=20)
        asc.grid(column=1, row=1, sticky='news')

        asb = Spinbox(fr2, from_=0, to=255, textvariable=self.avar,
                      command=self.ahandle, width=5)
        asb.grid(column=2, row=1, sticky='nw')

        ael = Label(fr2, text=' ', height=1)
        ael.grid(column=2, row=2, sticky='s')

        draw_gradient(self.rcan, (0, 0, 0), (255, 0, 0), width=self.canvas_w)
        draw_gradient(self.gcan, (255, 0, 0),
                      (255, 255, 0), width=self.canvas_w)
        draw_gradient(self.bcan, (255, 0, 0),
                      (255, 0, 255), width=self.canvas_w)
        draw_agradient(self.acan, (127, 127, 127),
                       (255, 0, 0), width=self.canvas_w)
Пример #48
0
class HelpSource(Query):
    "Get menu name and help source for Help menu."
    # Used in ConfigDialog.HelpListItemAdd/Edit, (941/9)

    def __init__(self, parent, title, *, menuitem='', filepath='',
                 used_names={}, _htest=False, _utest=False):
        """Get menu entry and url/local file for Additional Help.

        User enters a name for the Help resource and a web url or file
        name. The user can browse for the file.
        """
        self.filepath = filepath
        message = 'Name for item on Help menu:'
        super().__init__(
                parent, title, message, text0=menuitem,
                used_names=used_names, _htest=_htest, _utest=_utest)

    def create_widgets(self):
        super().create_widgets()
        frame = self.frame
        pathlabel = Label(frame, anchor='w', justify='left',
                          text='Help File Path: Enter URL or browse for file')
        self.pathvar = StringVar(self, self.filepath)
        self.path = Entry(frame, textvariable=self.pathvar, width=40)
        browse = Button(frame, text='Browse', width=8,
                        command=self.browse_file)
        self.path_error = Label(frame, text=' ', foreground='red',
                                font=self.error_font)

        pathlabel.grid(column=0, row=10, columnspan=3, padx=5, pady=[10,0],
                       sticky=W)
        self.path.grid(column=0, row=11, columnspan=2, padx=5, sticky=W+E,
                       pady=[10,0])
        browse.grid(column=2, row=11, padx=5, sticky=W+S)
        self.path_error.grid(column=0, row=12, columnspan=3, padx=5,
                             sticky=W+E)

    def askfilename(self, filetypes, initdir, initfile):  # htest #
        # Extracted from browse_file so can mock for unittests.
        # Cannot unittest as cannot simulate button clicks.
        # Test by running htest, such as by running this file.
        return filedialog.Open(parent=self, filetypes=filetypes)\
               .show(initialdir=initdir, initialfile=initfile)

    def browse_file(self):
        filetypes = [
            ("HTML Files", "*.htm *.html", "TEXT"),
            ("PDF Files", "*.pdf", "TEXT"),
            ("Windows Help Files", "*.chm"),
            ("Text Files", "*.txt", "TEXT"),
            ("All Files", "*")]
        path = self.pathvar.get()
        if path:
            dir, base = os.path.split(path)
        else:
            base = None
            if platform[:3] == 'win':
                dir = os.path.join(os.path.dirname(executable), 'Doc')
                if not os.path.isdir(dir):
                    dir = os.getcwd()
            else:
                dir = os.getcwd()
        file = self.askfilename(filetypes, dir, base)
        if file:
            self.pathvar.set(file)

    item_ok = SectionName.entry_ok  # localize for test override

    def path_ok(self):
        "Simple validity check for menu file path"
        path = self.path.get().strip()
        if not path: #no path specified
            self.showerror('no help file path specified.', self.path_error)
            return None
        elif not path.startswith(('www.', 'http')):
            if path[:5] == 'file:':
                path = path[5:]
            if not os.path.exists(path):
                self.showerror('help file path does not exist.',
                               self.path_error)
                return None
            if platform == 'darwin':  # for Mac Safari
                path =  "file://" + path
        return path

    def entry_ok(self):
        "Return apparently valid (name, path) or None"
        self.entry_error['text'] = ''
        self.path_error['text'] = ''
        name = self.item_ok()
        path = self.path_ok()
        return None if name is None or path is None else (name, path)
Пример #49
0
    """
    print(text)
    index = int(index)
    if text.isupper() and index == 0:
        return True
    if input in (",", ".", "'", " ") and index > 0:
        return True
    if inp.isalnum() and index > 0:
        return True
    if text == "":
        return True
    else:
        return False


vcmd = root.register(is_okay)

entsv = StringVar()
ent0 = Entry(lf0,
             validate='key',
             validatecommand=(vcmd, '%P', '%S', '%i'),
             textvariable=entsv)
ent0.bind("<Return>", end_input)
ent0.grid(row=1, column=0, padx=10)
ent0.focus()

mess_lbl = Label(lf0, text='Start with capital letter, <Return> to confirm')
mess_lbl.grid(row=2, column=0, pady=10, padx=10)

root.mainloop()
Пример #50
0
class FunctionDialog:
    """ Display function dialog for creating plot from math functions """
    def __init__(self,
                 parent,
                 function="x*x",
                 xmin=1.0,
                 xmax=10.0,
                 discr=100,
                 xlabel="x",
                 ylabel="x*x"):
        """ FunctionDialog constructor """
        top = self.top = tkinter.Toplevel(parent)
        self.__entry_function_label = Label(top,
                                            text='Enter the function:',
                                            width=25)
        self.__entry_function_label.grid(row=2,
                                         column=1,
                                         columnspan=2,
                                         rowspan=1,
                                         padx=5,
                                         pady=5)
        self.__entry_function = Entry(top, width=50)
        self.__entry_function.insert(tkinter.END, function)
        self.__entry_function.grid(row=2,
                                   column=3,
                                   columnspan=4,
                                   rowspan=1,
                                   padx=5,
                                   pady=5)

        self.__entry_xmin_label = Label(top, text='X min:', width=10)
        self.__entry_xmin_label.grid(row=3,
                                     column=1,
                                     columnspan=1,
                                     rowspan=1,
                                     padx=5,
                                     pady=5)
        self.__entry_xmin = Entry(top, width=10)
        self.__entry_xmin.insert(tkinter.END, xmin)
        self.__entry_xmin.grid(row=3,
                               column=2,
                               columnspan=1,
                               rowspan=1,
                               padx=5,
                               pady=5)

        self.__entry_xmax_label = Label(top, text='X max:', width=10)
        self.__entry_xmax_label.grid(row=4,
                                     column=1,
                                     columnspan=1,
                                     rowspan=1,
                                     padx=5,
                                     pady=5)
        self.__entry_xmax = Entry(top, width=10)
        self.__entry_xmax.insert(tkinter.END, xmax)
        self.__entry_xmax.grid(row=4,
                               column=2,
                               columnspan=1,
                               rowspan=1,
                               padx=5,
                               pady=5)

        self.__entry_discr_label = Label(top, text='Discr:', width=10)
        self.__entry_discr_label.grid(row=3,
                                      column=5,
                                      columnspan=1,
                                      rowspan=1,
                                      padx=5,
                                      pady=5)
        self.__entry_discr = Entry(top, width=10)
        self.__entry_discr.insert(tkinter.END, discr)
        self.__entry_discr.grid(row=3,
                                column=6,
                                columnspan=1,
                                rowspan=1,
                                padx=5,
                                pady=5)

        self.__entry_xlabel_label = Label(top, text='X label:', width=10)
        self.__entry_xlabel_label.grid(row=3,
                                       column=3,
                                       columnspan=1,
                                       rowspan=1,
                                       padx=5,
                                       pady=5)
        self.__entry_xlabel = Entry(top, width=10)
        self.__entry_xlabel.insert(tkinter.END, xlabel)
        self.__entry_xlabel.grid(row=3,
                                 column=4,
                                 columnspan=1,
                                 rowspan=1,
                                 padx=5,
                                 pady=5)

        self.__entry_ylabel_label = Label(top, text='Y label:', width=10)
        self.__entry_ylabel_label.grid(row=4,
                                       column=3,
                                       columnspan=1,
                                       rowspan=1,
                                       padx=5,
                                       pady=5)
        self.__entry_ylabel = Entry(top, width=10)
        self.__entry_ylabel.insert(tkinter.END, ylabel)
        self.__entry_ylabel.grid(row=4,
                                 column=4,
                                 columnspan=1,
                                 rowspan=1,
                                 padx=5,
                                 pady=5)

        self.__plot_button = Button(top,
                                    text='Plot',
                                    command=self.create_plot_from_function,
                                    width=35)
        self.__plot_button.grid(row=5,
                                column=1,
                                columnspan=3,
                                rowspan=1,
                                padx=5,
                                pady=5)

        self.__cancel_button = Button(top,
                                      text='Cancel',
                                      command=self.quit,
                                      width=35)
        self.__cancel_button.grid(row=5,
                                  column=4,
                                  columnspan=3,
                                  rowspan=1,
                                  padx=5,
                                  pady=5)

        self.__plot = None

    def create_plot_from_function(self):
        """ create plot from math functions """
        logger.log(
            logging.INFO,
            "[FunctionDialog] Creating plot from math function " +
            self.__entry_function.get())
        self.__plot = PlotCreator.get_instance().plot_from_function(
            self.__entry_function.get(), self.__entry_xmin.get(),
            self.__entry_xmax.get(), self.__entry_discr.get(),
            self.__entry_xlabel.get(), self.__entry_ylabel.get())

        self.__plot.set_function(str(self.__entry_function.get()))

        self.quit()

    def get_plot(self):
        """ Get the plot """
        return self.__plot

    def quit(self):
        """ Exit the dialog """
        self.top.destroy()
Пример #51
0
    def initUI(self):

        self.parent.title("Calculator")

        Style().configure("TButton", padding=(0, 5, 0, 5), font='serif 10')
        
        self.pack(fill=BOTH, expand=1)


        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)

        entry = Entry(self)
        entry.grid(row=0, columnspan=4, sticky=E + W + S + N)

        cls = Button(self, text="Cls")
        cls.grid(row=1, column=0, sticky=E + W + S + N)
        bck = Button(self, text="Back")
        bck.grid(row=1, column=1, sticky=E + W + S + N)
        lbl = Button(self)
        lbl.grid(row=1, column=2, sticky=E + W + S + N)    
        clo = Button(self, text="Close")
        clo.grid(row=1, column=3, sticky=E + W + S + N)        
        sev = Button(self, text="7")
        sev.grid(row=2, column=0, sticky=E + W + S + N)        
        eig = Button(self, text="8")
        eig.grid(row=2, column=1, sticky=E + W + S + N)         
        nin = Button(self, text="9")
        nin.grid(row=2, column=2, sticky=E + W + S + N) 
        div = Button(self, text="/")
        div.grid(row=2, column=3, sticky=E + W + S + N) 

        fou = Button(self, text="4")
        fou.grid(row=3, column=0, sticky=E + W + S + N)        
        fiv = Button(self, text="5")
        fiv.grid(row=3, column=1, sticky=E + W + S + N)         
        six = Button(self, text="6")
        six.grid(row=3, column=2, sticky=E + W + S + N) 
        mul = Button(self, text="*")
        mul.grid(row=3, column=3, sticky=E + W + S + N)    

        one = Button(self, text="1")
        one.grid(row=4, column=0, sticky=E + W + S + N)        
        two = Button(self, text="2")
        two.grid(row=4, column=1, sticky=E + W + S + N)         
        thr = Button(self, text="3")
        thr.grid(row=4, column=2, sticky=E + W + S + N) 
        mns = Button(self, text="-")
        mns.grid(row=4, column=3, sticky=E + W + S + N)         

        zer = Button(self, text="0")
        zer.grid(row=5, column=0, sticky=E + W + S + N)        
        dot = Button(self, text=".")
        dot.grid(row=5, column=1, sticky=E + W + S + N)         
        equ = Button(self, text="=")
        equ.grid(row=5, column=2, sticky=E + W + S + N) 
        pls = Button(self, text="+")
        pls.grid(row=5, column=3, sticky=E + W + S + N)
Пример #52
0
     def __init__(self, tester):
         self.tester = tester
         self.mainWin = tester.cntlr
 
         parent = self.mainWin.parent
         super(DialogTransformTester, self).__init__(parent)
         self.parent = parent
         parentGeometry = re.match("(\d+)x(\d+)[+]?([-]?\d+)[+]?([-]?\d+)", parent.geometry())
         dialogX = int(parentGeometry.group(3))
         dialogY = int(parentGeometry.group(4))
         self.selectedGroup = None
 
         self.transient(self.parent)
         self.title(_("Transformation Tester"))
         
         frame = Frame(self)
         
         # load grid
         trRegLabel = label(frame, 0, 0, _("Registry:"))
         trReg = self.tester.trRegs[-1] # default is latest
         self.trRegName = gridCombobox(frame, 1, 0, 
                                       value=trReg,
                                       values=self.tester.trRegs, 
                                       comboboxselected=self.dialogTrRegComboBoxSelected)
         trRegToolTipMessage = _("Select Transformation Registry")
         ToolTip(self.trRegName, text=trRegToolTipMessage, wraplength=360)
         ToolTip(trRegLabel, text=trRegToolTipMessage, wraplength=360)
         
         trNameLabel = label(frame, 0, 1, _("Transform:"))
         self.trNameName = gridCombobox(frame, 1, 1, 
                                       value="",
                                       values=self.tester.getTrNames(trReg), 
                                       comboboxselected=self.dialogTrNameComboBoxSelected)
         trRegToolTipMessage = _("Select or enter transform")
         ToolTip(self.trRegName, text=trRegToolTipMessage, wraplength=360)
         ToolTip(trRegLabel, text=trRegToolTipMessage, wraplength=360)
 
         sourceLabel = label(frame, 0, 2, _("Source text:"))
         ToolTip(sourceLabel, text=_("Enter the source text which is to be transformed. "), wraplength=240)
         self.sourceVar = StringVar()
         self.sourceVar.set("")
         sourceEntry = Entry(frame, textvariable=self.sourceVar, width=50)
         sourceLabel.grid(row=2, column=0, sticky=W)
         sourceEntry.grid(row=2, column=1, sticky=EW, pady=3, padx=3)
 
         resultLabel = label(frame, 1, 3, _("Result:"))
         ToolTip(sourceLabel, text=_("Transformation result. "), wraplength=240)
         self.resultVar = StringVar()
         self.resultVar.set("")
         resultEntry = Entry(frame, textvariable=self.resultVar, width=50)
         resultLabel.grid(row=3, column=0, sticky=W)
         resultEntry.grid(row=3, column=1, sticky=EW, pady=3, padx=3)
 
         
         self.mainWin.showStatus(None)
 
         btnPad = 2 if self.mainWin.isMSW else 0 # buttons too narrow on windows
         okButton = Button(frame, text=_("Transform"), width=8 + btnPad, command=self.dialogOk)
         cancelButton = Button(frame, text=_("Done"), width=4 + btnPad, command=self.dialogClose)
         cancelButton.grid(row=4, column=0, sticky=E, columnspan=2, pady=3, padx=3)
         okButton.grid(row=4, column=0, sticky=E, columnspan=2, pady=3, padx=64)
         ToolTip(okButton, text=_("Transform the source entered. "), wraplength=240)
         ToolTip(cancelButton, text=_("Close this dialog. "), wraplength=240)
         
         frame.grid(row=0, column=0, sticky=(N,S,E,W))
         frame.columnconfigure(1, weight=3)
         frame.columnconfigure(2, weight=1)
         window = self.winfo_toplevel()
         window.columnconfigure(0, weight=1)
         self.geometry("+{0}+{1}".format(dialogX+150,dialogY+100))
         
         #self.bind("<Return>", self.ok)
         #self.bind("<Escape>", self.close)
         
         self.protocol("WM_DELETE_WINDOW", self.dialogClose)
         self.grab_set()
         
         self.wait_window(self)
    def initUI(self):
        self.parent.title("Calculator")
        
        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.columnconfigure(4, pad=3)
        self.columnconfigure(5, pad=3)
        self.rowconfigure(0, pad=3)

        entry1 = Entry(self)
        #entry.grid(row=0, columnspan=4, sticky=W+E)
        entry1.insert(0, "0")

        entry2 = Entry(self)
        entry2.insert(0, "0")

        Team_1_Score = 0
        Team_2_Score = 0


        def Addition_1():
            nonlocal Team_1_Score
            Team_1_Score += 1
            entry1.delete(0, 3)
            entry1.insert(0, Team_1_Score)
            F = open("Team1.txt", "w")
            F.write(str(Team_1_Score))
            F.close()

        def Substraction_1():
            nonlocal Team_1_Score
            Team_1_Score -= 1
            entry1.delete(0, 3)
            entry1.insert(0, Team_1_Score)
            F = open("Team1.txt", "w")
            F.write(str(Team_1_Score))
            F.close()

        def Addition_2():
            nonlocal Team_2_Score
            Team_2_Score += 1
            entry2.delete(0, 3)
            entry2.insert(0, Team_2_Score)
            F = open("Team2.txt", "w")
            F.write(str(Team_2_Score))
            F.close()

        def Substraction_2():
            nonlocal Team_2_Score
            Team_2_Score -= 1
            entry2.delete(0, 3)
            entry2.insert(0, Team_2_Score)
            F = open("Team2.txt", "w")
            F.write(str(Team_2_Score))
            F.close()

        def display_1():
            return Team_1_Score
        def display_2():
            return Team_2_Score


        One_Pls = Button(self, text="+", command = Addition_1)
        One_Pls.grid(row=0, column=0) 
        One_Mns = Button(self, text="-", command = Substraction_1)
        One_Mns.grid(row=0, column=1) 
        #One_Display = Button(self, text="=", command = display_1)
        entry1.grid(row=0, column=2)
        Two_Pls = Button(self, text="+", command = Addition_2)
        Two_Pls.grid(row=0, column=3) 
        Two_Mns = Button(self, text="-", command = Substraction_2)
        Two_Mns.grid(row=0, column=4) 
        #Two_Display = Button(self, text="=", command = display_2)
        entry2.grid(row=0, column=5)

        self.pack()