示例#1
0
class GuiGenerateCount(Frame):
    def __init__(self, parent):
        Frame.__init__(self, parent)
        self.parent = parent
        self.pack()
        
        #step increment len
        self._stepLenFrm  = Frame(self); self._stepLenFrm.pack()
        self._stepLenLbl  = Label(self._stepLenFrm, text="Step Len: ");   self._stepLenLbl.pack(side=LEFT)
        self._stepLenSpin = Spinbox(self._stepLenFrm, from_=0, to=1000); self._stepLenSpin.pack(side=LEFT)
        
        #start value
        self._startFrm  = Frame(self); self._startFrm.pack()
        self._startLbl  = Label(self._startFrm, text="Start Value: ");   self._startLbl.pack(side=LEFT)
        self._startTxt  = Entry(self._startFrm);   self._startTxt.pack(side=LEFT)
        self._startTxt.insert(0, "0")
        
    def getSettings(self):
        return  {   "StepLen":      self._stepLenSpin.get(),
                    "StartValue":   self._startTxt.get()
                }
    
    def getName(self):
        return "Counter"
        
    def getGeneratorFunction(self):
        return generateCounter
示例#2
0
class RegisterPage(Frame):
    def __init__(self, master, blockchain=None, client=None):
        Frame.__init__(self, master)

        self.blockchain = blockchain
        self.client = client

        # user id
        id_frame = Frame(self)
        id_frame.pack()
        id_label = Label(id_frame, text='User ID')
        id_label.pack(side=LEFT)
        self.id_entry = Entry(id_frame, bd=5)
        self.id_entry.pack(side=LEFT)

        #first name
        fname_frame = Frame(self)
        fname_frame.pack()
        fname_label = Label(fname_frame, text='First Name')
        fname_label.pack(side=LEFT)
        self.fname_entry = Entry(fname_frame, bd=5)
        self.fname_entry.pack(side=LEFT)

        #last name
        lname_frame = Frame(self)
        lname_frame.pack()
        lname_label = Label(lname_frame, text='Last Name')
        lname_label.pack(side=LEFT)
        self.lname_entry = Entry(lname_frame, bd=5)
        self.lname_entry.pack(side=LEFT)

        # department
        departments = [(1, 'cse'), (2, 'arch')]
        department_frame = Frame(self)
        department_frame.pack()
        department_label = Label(department_frame, text='Department')
        department_label.pack(side=LEFT)
        self.department_list = Listbox(department_frame,
                                       selectmode=SINGLE,
                                       selectbackground='Blue',
                                       height=len(departments))

        for index, dep in departments:
            self.department_list.insert(index, dep)
        self.department_list.pack(side=LEFT)

        #section
        section_frame = Frame(self)
        section_frame.pack()
        section_label = Label(section_frame, text='section')
        section_label.pack(side=LEFT)
        self.section_spinbox = Spinbox(section_frame, from_=1, to=3)
        self.section_spinbox.pack(side=LEFT)

        # Year
        year_frame = Frame(self)
        year_frame.pack()
        year_label = Label(year_frame, text='Year')
        year_label.pack()
        self.year_var = IntVar()
        years = [('2007', 2007), ('2008', 2008), ('2009', 2009),
                 ('2010', 2010), ('2011', 2011)]
        for text, value in years:
            rb = Radiobutton(year_frame,
                             text=text,
                             variable=self.year_var,
                             value=value,
                             command=self.sel)
            rb.pack(anchor=W)

        self.label = Label(year_frame)
        self.label.pack()
        # password
        password_frame = Frame(self)
        password_frame.pack()
        password_label = Label(password_frame, text='Password')
        password_label.pack(side=LEFT)
        self.password_entry = Entry(password_frame, bd=5)
        self.password_entry.pack(side=LEFT)

        #Re-password
        repassword_frame = Frame(self)
        repassword_frame.pack()
        repassword_label = Label(repassword_frame, text='Re-password')
        repassword_label.pack(side=LEFT)
        self.repassword_entry = Entry(repassword_frame, bd=5)
        self.repassword_entry.pack(side=LEFT)

        #register button
        w = tkinter.Button(self,
                           bg='Green',
                           text='Register',
                           command=self.register)
        w.pack()

    def sel(self):
        selection = 'You selected the year ' + str(self.year_var.get())
        self.label.config(text=selection)

    def register(self):
        user = User()
        selected = self.department_list.curselection()
        if len(selected) < 1:
            tkinter.messagebox.showerror('Error',
                                         'Department not selected !!!')
        else:
            department = self.department_list.get(
                self.department_list.curselection())
            id_ = self.id_entry.get()
            fname = self.fname_entry.get()
            lname = self.lname_entry.get()

            print(str(department))
            section = int(self.section_spinbox.get())
            print(section)
            print(type(section))
            year = int(self.year_var.get())
            print(year)
            print(type(year))
            password = self.password_entry.get()
            repassword = self.repassword_entry.get()
            if password == repassword:
                student = Student(fname,
                                  lname,
                                  department,
                                  section,
                                  year,
                                  id_,
                                  password=password)
                if user.student_register(student):
                    tkinter.messagebox.showinfo('Register',
                                                'you are Registerd.')
                else:
                    tkinter.messagebox.showerror('Error',
                                                 'Registration failed.')
            else:
                tkinter.messagebox.showerror('Error', 'password is incorrect')
示例#3
0
class OOP():
    def __init__(self):
        # Create instance
        self.win = tk.Tk()

        # Add a title
        self.win.title("Python GUI")

        # Disable resizing the window
        self.win.resizable(0, 0)

        # Create a Queue
        self.guiQueue = Queue()

        self.createWidgets()

        # populate Tab 2 Entries
        self.defaultFileEntries()

        # create MySQL instance
        self.mySQL = MySQL()

    def defaultFileEntries(self):
        self.fileEntry.delete(0, tk.END)
        self.fileEntry.insert(0, 'Z:\\')  # bogus path
        self.fileEntry.config(state='readonly')

        self.netwEntry.delete(0, tk.END)
        self.netwEntry.insert(0, 'Z:\\Backup')  # bogus path

    # Combobox callback
    def _combo(self, val=0):
        value = self.combo.get()
        self.scr.insert(tk.INSERT, value + '\n')

    # Spinbox callback
    def _spin(self):
        value = self.spin.get()
        self.scr.insert(tk.INSERT, value + '\n')

    # Checkbox callback
    def checkCallback(self, *ignoredArgs):
        # only enable one checkbutton
        if self.chVarUn.get(): self.check3.configure(state='disabled')
        else: self.check3.configure(state='normal')
        if self.chVarEn.get(): self.check2.configure(state='disabled')
        else: self.check2.configure(state='normal')

    # Radiobutton callback function
    def radCall(self):
        radSel = self.radVar.get()
        if radSel == 0: self.mySQL2.configure(text=WIDGET_LABEL + 'in Blue')
        elif radSel == 1: self.mySQL2.configure(text=WIDGET_LABEL + 'in Gold')
        elif radSel == 2: self.mySQL2.configure(text=WIDGET_LABEL + 'in Red')

    # Exit GUI cleanly
    def _quit(self):
        self.win.quit()
        self.win.destroy()
        exit()

    def methodInAThread(self, numOfLoops=10):
        for idx in range(numOfLoops):
            sleep(1)
            self.scr.insert(tk.INSERT, str(idx) + '\n')
        sleep(1)
        print('methodInAThread():', self.runT.isAlive())

    # Running methods in Threads
    def createThread(self, num):
        self.runT = Thread(target=self.methodInAThread, args=[num])
        self.runT.setDaemon(True)
        self.runT.start()
        print(self.runT)
        print('createThread():', self.runT.isAlive())

        # textBoxes are the Consumers of Queue data
        writeT = Thread(target=self.useQueues, daemon=True)
        writeT.start()

    # Create Queue instance
    def useQueues(self):
        # Now using a class member Queue
        while True:
            qItem = self.guiQueue.get()
            print(qItem)
            self.scr.insert(tk.INSERT, qItem + '\n')

    # Button callback
    def insertQuote(self):
        title = self.bookTitle.get()
        page = self.pageNumber.get()
        quote = self.quote.get(1.0, tk.END)
        print(title)
        print(quote)
        self.mySQL.insertBooks(title, page, quote)

    # Button callback
    def getQuote(self):
        allBooks = self.mySQL.showBooks()
        print(allBooks)
        self.quote.insert(tk.INSERT, allBooks)

    # Button callback
    def modifyQuote(self):
        raise NotImplementedError(
            "This still needs to be implemented for the SQL command.")

    #####################################################################################
    def createWidgets(self):
        # Tab Control introduced here --------------------------------------
        tabControl = ttk.Notebook(self.win)  # Create Tab Control

        tab1 = ttk.Frame(tabControl)  # Create a tab
        tabControl.add(tab1, text='MySQL')  # Add the tab

        tab2 = ttk.Frame(tabControl)  # Add a second tab
        tabControl.add(tab2, text='Widgets')  # Make second tab visible

        tabControl.pack(expand=1, fill="both")  # Pack to make visible
        # ~ Tab Control introduced here -----------------------------------------

        # We are creating a container frame to hold all other widgets
        self.mySQL = ttk.LabelFrame(tab1, text=' Python Database ')
        self.mySQL.grid(column=0, row=0, padx=8, pady=4)

        # Creating a Label
        ttk.Label(self.mySQL, text="Book Title:").grid(column=0,
                                                       row=0,
                                                       sticky='W')

        # Adding a Textbox Entry widget
        book = tk.StringVar()
        self.bookTitle = ttk.Entry(self.mySQL, width=34, textvariable=book)
        self.bookTitle.grid(column=0, row=1, sticky='W')

        # Adding a Textbox Entry widget
        book1 = tk.StringVar()
        self.bookTitle1 = ttk.Entry(self.mySQL, width=34, textvariable=book1)
        self.bookTitle1.grid(column=0, row=2, sticky='W')

        # Adding a Textbox Entry widget
        book2 = tk.StringVar()
        self.bookTitle2 = ttk.Entry(self.mySQL, width=34, textvariable=book2)
        self.bookTitle2.grid(column=0, row=3, sticky='W')

        # Creating a Label
        ttk.Label(self.mySQL, text="Page:").grid(column=1, row=0, sticky='W')

        # Adding a Textbox Entry widget
        page = tk.StringVar()
        self.pageNumber = ttk.Entry(self.mySQL, width=6, textvariable=page)
        self.pageNumber.grid(column=1, row=1, sticky='W')

        # Adding a Textbox Entry widget
        page = tk.StringVar()
        self.pageNumber1 = ttk.Entry(self.mySQL, width=6, textvariable=page)
        self.pageNumber1.grid(column=1, row=2, sticky='W')

        # Adding a Textbox Entry widget
        page = tk.StringVar()
        self.pageNumber2 = ttk.Entry(self.mySQL, width=6, textvariable=page)
        self.pageNumber2.grid(column=1, row=3, sticky='W')

        # Adding a Button
        self.action = ttk.Button(self.mySQL,
                                 text="Insert Quote",
                                 command=self.insertQuote)
        self.action.grid(column=2, row=1)

        # Adding a Button
        self.action1 = ttk.Button(self.mySQL,
                                  text="Get Quotes",
                                  command=self.getQuote)
        self.action1.grid(column=2, row=2)

        # Adding a Button
        self.action2 = ttk.Button(self.mySQL,
                                  text="Mody Quote",
                                  command=self.modifyQuote)
        self.action2.grid(column=2, row=3)

        # Add some space around each widget
        for child in self.mySQL.winfo_children():
            child.grid_configure(padx=2, pady=4)

        quoteFrame = ttk.LabelFrame(tab1, text=' Book Quotation ')
        quoteFrame.grid(column=0, row=1, padx=8, pady=4)

        # Using a scrolled Text control
        quoteW = 40
        quoteH = 6
        self.quote = scrolledtext.ScrolledText(quoteFrame,
                                               width=quoteW,
                                               height=quoteH,
                                               wrap=tk.WORD)
        self.quote.grid(column=0, row=8, sticky='WE', columnspan=3)

        # Add some space around each widget
        for child in quoteFrame.winfo_children():
            child.grid_configure(padx=2, pady=4)

        #======================================================================================================
        # Tab Control 2
        #======================================================================================================
        # We are creating a container frame to hold all other widgets -- Tab2
        self.mySQL2 = ttk.LabelFrame(tab2, text=WIDGET_LABEL)
        self.mySQL2.grid(column=0, row=0, padx=8, pady=4)

        # Creating three checkbuttons
        self.chVarDis = tk.IntVar()
        self.check1 = tk.Checkbutton(self.mySQL2,
                                     text="Disabled",
                                     variable=self.chVarDis,
                                     state='disabled')
        self.check1.select()
        self.check1.grid(column=0, row=0, sticky=tk.W)

        self.chVarUn = tk.IntVar()
        self.check2 = tk.Checkbutton(self.mySQL2,
                                     text="UnChecked",
                                     variable=self.chVarUn)
        self.check2.deselect()
        self.check2.grid(column=1, row=0, sticky=tk.W)

        self.chVarEn = tk.IntVar()
        self.check3 = tk.Checkbutton(self.mySQL2,
                                     text="Toggle",
                                     variable=self.chVarEn)
        self.check3.deselect()
        self.check3.grid(column=2, row=0, sticky=tk.W)

        # trace the state of the two checkbuttons
        self.chVarUn.trace(
            'w', lambda unused0, unused1, unused2: self.checkCallback())
        self.chVarEn.trace(
            'w', lambda unused0, unused1, unused2: self.checkCallback())

        # Radiobutton list
        colors = ["Blue", "Gold", "Red"]

        self.radVar = tk.IntVar()

        # Selecting a non-existing index value for radVar
        self.radVar.set(99)

        # Creating all three Radiobutton widgets within one loop
        for col in range(3):
            curRad = 'rad' + str(col)
            curRad = tk.Radiobutton(self.mySQL2,
                                    text=colors[col],
                                    variable=self.radVar,
                                    value=col,
                                    command=self.radCall)
            curRad.grid(column=col, row=6, sticky=tk.W, columnspan=3)
            # And now adding tooltips
            ToolTip(curRad, 'This is a Radiobutton control.')

        # Create a container to hold labels
        labelsFrame = ttk.LabelFrame(self.mySQL2,
                                     text=' Labels within a Frame ')
        labelsFrame.grid(column=0, row=7, pady=6)

        # Place labels into the container element - vertically
        ttk.Label(labelsFrame, text="Choose a number:").grid(column=0, row=0)
        ttk.Label(labelsFrame, text="Label 2").grid(column=0, row=1)

        # Add some space around each label
        for child in labelsFrame.winfo_children():
            child.grid_configure(padx=6, pady=1)

        number = tk.StringVar()
        self.combo = ttk.Combobox(self.mySQL2, width=12, textvariable=number)
        self.combo['values'] = (1, 2, 4, 42, 100)
        self.combo.grid(column=1, row=7, sticky=tk.W)
        self.combo.current(0)
        self.combo.bind('<<ComboboxSelected>>', self._combo)

        # Adding a Spinbox widget using a set of values
        self.spin = Spinbox(self.mySQL2,
                            values=(1, 2, 4, 42, 100),
                            width=5,
                            bd=8,
                            command=self._spin)
        self.spin.grid(column=2, row=7, sticky='W,', padx=6, pady=1)

        # Using a scrolled Text control
        scrolW = 40
        scrolH = 1
        self.scr = scrolledtext.ScrolledText(self.mySQL2,
                                             width=scrolW,
                                             height=scrolH,
                                             wrap=tk.WORD)
        self.scr.grid(column=0, row=8, sticky='WE', columnspan=3)

        # Create Manage Files Frame ------------------------------------------------
        mngFilesFrame = ttk.LabelFrame(tab2, text=' Manage Files: ')
        mngFilesFrame.grid(column=0, row=1, sticky='WE', padx=10, pady=5)

        # Button Callback
        def getFileName():
            print('hello from getFileName')
            fDir = path.dirname(__file__)
            fName = fd.askopenfilename(parent=self.win, initialdir=fDir)
            print(fName)
            self.fileEntry.config(state='enabled')
            self.fileEntry.delete(0, tk.END)
            self.fileEntry.insert(0, fName)

            if len(fName) > self.entryLen:
                self.fileEntry.config(width=len(fName) + 3)

        # Add Widgets to Manage Files Frame
        lb = ttk.Button(mngFilesFrame,
                        text="Browse to File...",
                        command=getFileName)
        lb.grid(column=0, row=0, sticky=tk.W)

        #-----------------------------------------------------
        file = tk.StringVar()
        self.entryLen = scrolW - 4
        self.fileEntry = ttk.Entry(mngFilesFrame,
                                   width=self.entryLen,
                                   textvariable=file)
        self.fileEntry.grid(column=1, row=0, sticky=tk.W)

        #-----------------------------------------------------
        logDir = tk.StringVar()
        self.netwEntry = ttk.Entry(mngFilesFrame,
                                   width=self.entryLen,
                                   textvariable=logDir)
        self.netwEntry.grid(column=1, row=1, sticky=tk.W)

        def copyFile():
            import shutil
            src = self.fileEntry.get()
            file = src.split('/')[-1]
            dst = self.netwEntry.get() + '\\' + file
            try:
                shutil.copy(src, dst)
                mBox.showinfo('Copy File to Network', 'Succes: File copied.')
            except FileNotFoundError as err:
                mBox.showerror('Copy File to Network',
                               '*** Failed to copy file! ***\n\n' + str(err))
            except Exception as ex:
                mBox.showerror('Copy File to Network',
                               '*** Failed to copy file! ***\n\n' + str(ex))

        cb = ttk.Button(mngFilesFrame,
                        text="Copy File To :   ",
                        command=copyFile)
        cb.grid(column=0, row=1, sticky=tk.E)

        # Add some space around each label
        for child in mngFilesFrame.winfo_children():
            child.grid_configure(padx=6, pady=6)

        # Creating a Menu Bar ==========================================================
        menuBar = Menu(tab1)
        self.win.config(menu=menuBar)

        # Add menu items
        fileMenu = Menu(menuBar, tearoff=0)
        fileMenu.add_command(label="New")
        fileMenu.add_separator()
        fileMenu.add_command(label="Exit", command=self._quit)
        menuBar.add_cascade(label="File", menu=fileMenu)

        # Add another Menu to the Menu Bar and an item
        helpMenu = Menu(menuBar, tearoff=0)
        helpMenu.add_command(label="About")
        menuBar.add_cascade(label="Help", menu=helpMenu)

        # Change the main windows icon
        self.win.iconbitmap('pyc.ico')

        # Using tkinter Variable Classes
        strData = tk.StringVar()
        strData.set('Hello StringVar')

        # It is not necessary to create a tk.StringVar()
        strData = tk.StringVar()
        strData = self.spin.get()

        # Place cursor into name Entry
        self.bookTitle.focus()

        # Add a Tooltip to the Spinbox
        ToolTip(self.spin, 'This is a Spin control.')

        # Add Tooltips to more widgets
        ToolTip(self.bookTitle, 'This is an Entry control.')
        ToolTip(self.action, 'This is a Button control.')
        ToolTip(self.scr, 'This is a ScrolledText control.')
示例#4
0
class App:
    def __init__(self):

        self.window = tk.Tk()
        self.window.title("Cripto Escitala")
        self.window.geometry('430x410')
        self.window.config(bg="#FFFFFF")
        self.escitala = Escitala()

        frameHead = Frame(self.window)
        lbl_method = tk.Label(frameHead, text='Metodo')
        lbl_method.grid(column=0, row=0, sticky='W', padx=5)
        lbl_n_col = tk.Label(frameHead, text='Nro Columnas')
        lbl_n_col.grid(column=2, row=0, sticky='W', padx=10)
        lbl_ord_col = tk.Label(frameHead, text='Orden Col: ejm {1,3,2}')
        lbl_ord_col.grid(column=3, row=0, sticky='W', padx=5)
        frameHead.grid(column=0, row=0)

        self.frame = Frame(self.window)
        self.combo = Combobox(self.frame)
        self.combo['values'] = ("Encriptar", "Desencriptar")
        self.combo.grid(column=0, row=0, sticky='W', padx=10)

        self.spin = Spinbox(self.frame, from_=2, to=500, width=5)
        self.spin.grid(column=1, row=0, sticky='W', padx=10)

        self.input_ord_col = Entry(self.frame)
        self.input_ord_col.grid(column=2, row=0, sticky='W', padx=10)

        buton = tk.Button(self.frame, text='Start', command=self.clicked)
        buton.grid(column=3, row=0, sticky='W', padx=10)
        self.frame.grid(column=0, row=1)

        lbl_txt_init = tk.Label(self.window, text='Input')
        lbl_txt_init.grid(column=0, row=3, sticky='W', padx=10)

        self.scroll_txt_init = tk.scrolledtext.ScrolledText(self.window,
                                                            width=50,
                                                            height=10)
        self.scroll_txt_init.grid(column=0, row=4, sticky='W', padx=10)

        lbl_txt_end = tk.Label(self.window, text='Output')
        lbl_txt_end.grid(column=0, row=5, sticky='W', padx=10)

        self.scroll_txt_end = scrolledtext.ScrolledText(self.window,
                                                        width=50,
                                                        height=10)
        self.scroll_txt_end.grid(column=0, row=6, sticky='W', padx=10)

        self.window.mainloop()

    def clicked(self):
        # Clear buffer f
        self.scroll_txt_end.delete(0.0, tk.END)
        indices = self.convertir_indices(self.input_ord_col.get())
        n_col = int(self.spin.get())
        self.verificar_ind_col(indices, n_col)
        typeAction = self.combo.get()

        textInput = self.scroll_txt_init.get(
            "0.0", tk.END)[:-1]  # Eliminamos el ultimo caracter '\n'

        if textInput == "":
            messagebox.showerror(
                'Mensaje Error',
                'Input vacio, Ingrese el texto a encriptar/desencriptar')

        if typeAction == "":
            messagebox.showerror('Mensaje Error', 'Seleccione el metodo')

        elif typeAction == "Encriptar":
            textOutput = self.escitala.encriptar_con_orden(
                textInput, n_col, indices)
        else:
            textOutput = self.escitala.desencriptar_con_orden(
                textInput, n_col, indices)
        # Put new string into of stroll
        self.scroll_txt_end.insert(tk.INSERT, textOutput)

    def convertir_indices(self, text_indices):
        try:
            indices = text_indices[text_indices.index('{') +
                                   1:text_indices.index('}')]
            indices = [int(l) - 1 for l in indices.split(',')]
            return indices
        except:
            messagebox.showerror('Mensaje Error',
                                 'Error al ingresar el orden de las columnas')

    def verificar_ind_col(self, indices, n_col):
        if (n_col != len(indices)):
            messagebox.showerror(
                'Mensaje Error',
                'Error en la cantidad de los ordenes de las columnas')
        for i in range(n_col):
            if (not (i in indices)):
                messagebox.showerror(
                    'Mesaje Error',
                    f'Error, el orden {i+1} no se encuentra en los ordenes de las columnas'
                )
示例#5
0
class OOP():
    def __init__(self):  # Initializer method
        # Create instance
        self.win = tk.Tk()

        # Add a title
        self.win.title("Python GUI")

        # Create a Queue
        self.gui_queue = Queue()

        self.create_widgets()

        self.defaultFileEntries()

        # Start TCP/IP server in its own thread
        svr_thread = Thread(target=start_server, daemon=True)
        svr_thread.start()

    def defaultFileEntries(self):
        self.fileEntry.delete(0, tk.END)
        self.fileEntry.insert(0, fDir)
        if len(fDir) > self.entryLen:
            self.fileEntry.config(width=35)  # limit width to adjust GUI
            self.fileEntry.config(state='readonly')

        self.netwEntry.delete(0, tk.END)
        self.netwEntry.insert(0, netDir)
        if len(netDir) > self.entryLen:
            self.netwEntry.config(width=35)  # limit width to adjust GUI

    # Create Queue instance
    def use_queues(self, loops=5):
        # Now using a class member Queue
        while True:
            q_item = self.gui_queue.get()
            print(q_item)
            self.scrol.insert(tk.INSERT, q_item + '\n')

    def method_in_a_thread(self, num_of_loops=10):
        for idx in range(num_of_loops):
            sleep(1)
            self.scrol.insert(tk.INSERT, str(idx) + '\n')

    # Running methods in Threads
    def create_thread(self, num=1):
        self.run_thread = Thread(target=self.method_in_a_thread, args=[num])
        self.run_thread.setDaemon(True)
        self.run_thread.start()

        # start queue in its own thread
        write_thread = Thread(target=self.use_queues, args=[num], daemon=True)
        write_thread.start()

    # Button callback
    def click_me(self):
        self.action.configure(text='Hello ' + self.name.get())
        bq.write_to_scrol(self)
        sleep(2)
        html_data = url.get_html()
        print(html_data)
        try:
            self.scrol.insert(tk.INSERT, html_data)
        except Exception as ex:
            print(ex)

    # Spinbox callback
    def _spin(self):
        value = self.spin.get()
        self.scrol.insert(tk.INSERT, value + '\n')

    # GUI Callback
    def checkCallback(self, *ignored_args):
        # only enable one checkbutton
        if self.chVarUn.get(): self.check3.configure(state='disabled')
        else: self.check3.configure(state='normal')
        if self.chVarEn.get(): self.check2.configure(state='disabled')
        else: self.check2.configure(state='normal')

    # Radiobutton Callback
    def radCall(self):
        radSel = self.radVar.get()
        if radSel == 0: self.mighty2.configure(text='Blue')
        elif radSel == 1: self.mighty2.configure(text='Gold')
        elif radSel == 2: self.mighty2.configure(text='Red')

    # update progressbar in callback loop
    def run_progressbar(self):
        self.progress_bar["maximum"] = 100
        for i in range(101):
            sleep(0.05)
            self.progress_bar["value"] = i  # increment progressbar
            self.progress_bar.update()  # have to call update() in loop
        self.progress_bar["value"] = 0  # reset/clear progressbar

    def start_progressbar(self):
        self.progress_bar.start()

    def stop_progressbar(self):
        self.progress_bar.stop()

    def progressbar_stop_after(self, wait_ms=1000):
        self.win.after(wait_ms, self.progress_bar.stop)

    def usingGlobal(self):
        global GLOBAL_CONST
        GLOBAL_CONST = 777

    # Exit GUI cleanly
    def _quit(self):
        self.win.quit()
        self.win.destroy()
        exit()

    #####################################################################################
    def create_widgets(self):
        tabControl = ttk.Notebook(self.win)  # Create Tab Control

        tab1 = ttk.Frame(tabControl)  # Create a tab
        tabControl.add(tab1, text='Tab 1')  # Add the tab
        tab2 = ttk.Frame(tabControl)  # Add a second tab
        tabControl.add(tab2, text='Tab 2')  # Make second tab visible

        tabControl.pack(expand=1, fill="both")  # Pack to make visible

        # LabelFrame using tab1 as the parent
        mighty = ttk.LabelFrame(tab1, text=' Mighty Python ')
        mighty.grid(column=0, row=0, padx=8, pady=4)

        # Modify adding a Label using mighty as the parent instead of win
        a_label = ttk.Label(mighty, text="Enter a name:")
        a_label.grid(column=0, row=0, sticky='W')

        # Adding a Textbox Entry widget
        self.name = tk.StringVar()
        #         self.name_entered = ttk.Entry(mighty, width=24, textvariable=self.name)
        self.name_entered = ttk.Entry(mighty, width=16, textvariable=self.name)
        self.name_entered.grid(column=0, row=1, sticky='W')
        self.name_entered.delete(0, tk.END)
        self.name_entered.insert(0, '< default name >')

        # Adding a Button
        self.action = ttk.Button(mighty,
                                 text="Click Me!",
                                 command=self.click_me)
        self.action.grid(column=2, row=1)

        ttk.Label(mighty, text="Choose a number:").grid(column=1, row=0)
        number = tk.StringVar()
        self.number_chosen = ttk.Combobox(mighty,
                                          width=14,
                                          textvariable=number,
                                          state='readonly')
        self.number_chosen['values'] = (1, 2, 4, 42, 100)
        self.number_chosen.grid(column=1, row=1)
        self.number_chosen.current(0)

        # Adding a Spinbox widget
        self.spin = Spinbox(mighty,
                            values=(1, 2, 4, 42, 100),
                            width=5,
                            bd=9,
                            command=self._spin)  # using range
        self.spin.grid(column=0, row=2, sticky='W')  # align left

        # Using a scrolled Text control
        scrol_w = 38
        scrol_h = 10  # increase sizes
        self.scrol = scrolledtext.ScrolledText(mighty,
                                               width=scrol_w,
                                               height=scrol_h,
                                               wrap=tk.WORD)
        self.scrol.grid(column=0, row=3, sticky='WE', columnspan=3)

        for child in mighty.winfo_children(
        ):  # add spacing to align widgets within tabs
            child.grid_configure(padx=4, pady=2)

        #=====================================================================================
        # Tab Control 2 ----------------------------------------------------------------------
        self.mighty2 = ttk.LabelFrame(tab2, text=' The Snake ')
        self.mighty2.grid(column=0, row=0, padx=8, pady=4)

        # Creating three checkbuttons
        chVarDis = tk.IntVar()
        check1 = tk.Checkbutton(self.mighty2,
                                text="Disabled",
                                variable=chVarDis,
                                state='disabled')
        check1.select()
        check1.grid(column=0, row=0, sticky=tk.W)

        chVarUn = tk.IntVar()
        check2 = tk.Checkbutton(self.mighty2,
                                text="UnChecked",
                                variable=chVarUn)
        check2.deselect()
        check2.grid(column=1, row=0, sticky=tk.W)

        chVarEn = tk.IntVar()
        check3 = tk.Checkbutton(self.mighty2, text="Enabled", variable=chVarEn)
        check3.deselect()
        check3.grid(column=2, row=0, sticky=tk.W)

        # trace the state of the two checkbuttons
        chVarUn.trace('w',
                      lambda unused0, unused1, unused2: self.checkCallback())
        chVarEn.trace('w',
                      lambda unused0, unused1, unused2: self.checkCallback())

        # First, we change our Radiobutton global variables into a list
        colors = ["Blue", "Gold", "Red"]

        # create three Radiobuttons using one variable
        self.radVar = tk.IntVar()

        # Next we are selecting a non-existing index value for radVar
        self.radVar.set(99)

        # Now we are creating all three Radiobutton widgets within one loop
        for col in range(3):
            curRad = tk.Radiobutton(self.mighty2,
                                    text=colors[col],
                                    variable=self.radVar,
                                    value=col,
                                    command=self.radCall)
            curRad.grid(column=col, row=1, sticky=tk.W)
            # And now adding tooltips
            ToolTip(curRad, 'This is a Radiobutton control')

        # Add a Progressbar to Tab 2
        self.progress_bar = ttk.Progressbar(tab2,
                                            orient='horizontal',
                                            length=336,
                                            mode='determinate')
        self.progress_bar.grid(column=0, row=3, pady=2)

        # Create a container to hold buttons
        buttons_frame = ttk.LabelFrame(self.mighty2, text=' ProgressBar ')
        buttons_frame.grid(column=0, row=2, sticky='W', columnspan=2)

        # Add Buttons for Progressbar commands
        ttk.Button(buttons_frame,
                   text=" Run Progressbar   ",
                   command=self.run_progressbar).grid(column=0,
                                                      row=0,
                                                      sticky='W')
        ttk.Button(buttons_frame,
                   text=" Start Progressbar  ",
                   command=self.start_progressbar).grid(column=0,
                                                        row=1,
                                                        sticky='W')
        ttk.Button(buttons_frame,
                   text=" Stop immediately ",
                   command=self.stop_progressbar).grid(column=1,
                                                       row=0,
                                                       sticky='W')
        ttk.Button(buttons_frame,
                   text=" Stop after second ",
                   command=self.progressbar_stop_after).grid(column=1,
                                                             row=1,
                                                             sticky='W')

        for child in buttons_frame.winfo_children():
            child.grid_configure(padx=2, pady=2)

        for child in self.mighty2.winfo_children():
            child.grid_configure(padx=8, pady=2)

        # Create Manage Files Frame ------------------------------------------------
        mngFilesFrame = ttk.LabelFrame(tab2, text=' Manage Files: ')
        mngFilesFrame.grid(column=0, row=1, sticky='WE', padx=10, pady=5)

        # Button Callback
        def getFileName():
            print('hello from getFileName')
            fDir = path.dirname(__file__)
            fName = fd.askopenfilename(parent=self.win, initialdir=fDir)
            print(fName)
            self.fileEntry.config(state='enabled')
            self.fileEntry.delete(0, tk.END)
            self.fileEntry.insert(0, fName)

            if len(fName) > self.entryLen:
                self.fileEntry.config(width=len(fName) + 3)

        # Add Widgets to Manage Files Frame
        lb = ttk.Button(mngFilesFrame,
                        text="Browse to File...",
                        command=getFileName)
        lb.grid(column=0, row=0, sticky=tk.W)

        #-----------------------------------------------------
        file = tk.StringVar()
        self.entryLen = scrol_w - 4
        self.fileEntry = ttk.Entry(mngFilesFrame,
                                   width=self.entryLen,
                                   textvariable=file)
        self.fileEntry.grid(column=1, row=0, sticky=tk.W)

        #-----------------------------------------------------
        logDir = tk.StringVar()
        self.netwEntry = ttk.Entry(mngFilesFrame,
                                   width=self.entryLen,
                                   textvariable=logDir)
        self.netwEntry.grid(column=1, row=1, sticky=tk.W)

        def copyFile():
            import shutil
            src = self.fileEntry.get()
            file = src.split('/')[-1]
            dst = self.netwEntry.get() + '\\' + file
            try:
                shutil.copy(src, dst)
                msg.showinfo('Copy File to Network', 'Succes: File copied.')
            except FileNotFoundError as err:
                msg.showerror('Copy File to Network',
                              '*** Failed to copy file! ***\n\n' + str(err))
            except Exception as ex:
                msg.showerror('Copy File to Network',
                              '*** Failed to copy file! ***\n\n' + str(ex))

        cb = ttk.Button(mngFilesFrame,
                        text="Copy File To :   ",
                        command=copyFile)
        cb.grid(column=0, row=1, sticky=tk.E)

        # Add some space around each label
        for child in mngFilesFrame.winfo_children():
            child.grid_configure(padx=6, pady=6)

        # Creating a Menu Bar ==========================================================
        menu_bar = Menu(self.win)
        self.win.config(menu=menu_bar)

        # Add menu items
        file_menu = Menu(menu_bar, tearoff=0)
        file_menu.add_command(label="New")
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=self._quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

        # Display a Message Box
        def _msgBox():
            msg.showinfo(
                'Python Message Info Box',
                'A Python GUI created using tkinter:\nThe year is 2019.')

        # Add another Menu to the Menu Bar and an item
        help_menu = Menu(menu_bar, tearoff=0)
        help_menu.add_command(
            label="About", command=_msgBox)  # display messagebox when clicked
        menu_bar.add_cascade(label="Help", menu=help_menu)

        # Change the main windows icon
        self.win.iconbitmap('pyc.ico')

        # It is not necessary to create a tk.StringVar()
        # strData = tk.StringVar()
        strData = self.spin.get()

        # call function
        self.usingGlobal()

        # self.name_entered.focus()
        # Set focus to Tab 2
        #         tabControl.select(1)

        # Add Tooltips -----------------------------------------------------
        # Add a Tooltip to the Spinbox
        ToolTip(self.spin, 'This is a Spinbox control')

        # Add Tooltips to more widgets
        ToolTip(self.name_entered, 'This is an Entry control')
        ToolTip(self.action, 'This is a Button control')
        ToolTip(self.scrol, 'This is a ScrolledText control')
class OOP():
    def __init__(self, language='en'): 
        # Create instance
        self.win = tk.Tk()
        
        self.i18n = I18N(language)
#         self.i18n = I18N(language)

        # Add a title       
        self.win.title(self.i18n.title)   
        
        # Callback methods now in different module
        self.callBacks = Callbacks(self)
         
        # Disable resizing the window  
        self.win.resizable(0,0)  
        
        # Create a Queue
        self.guiQueue = Queue() 
                              
        self.createWidgets() 
        
        # populate Tab 2 Entries      
        self.callBacks.defaultFileEntries()
        
        # create MySQL instance
        self.mySQL = MySQL()
        
        # create Logger instance
        fullPath = path.realpath(__file__)
        self.log = Logger(fullPath)
        
        # create Log Level instance
        self.level = LogLevel()
          
    #####################################################################################    
    def createWidgets(self):    
        # Tab Control introduced here --------------------------------------
        tabControl = ttk.Notebook(self.win)     # Create Tab Control
        
        tab1 = ttk.Frame(tabControl)            # Create a tab 
#         tabControl.add(tab1, text='MySQL')    # Add the tab -- COMMENTED OUT FOR CH08
        
        tab2 = ttk.Frame(tabControl)            # Add a second tab
        tabControl.add(tab2, text='Widgets')    # Make second tab visible
        
        tabControl.pack(expand=1, fill="both")  # Pack to make visible
        # ~ Tab Control introduced here -----------------------------------------
        
        # We are creating a container frame to hold all other widgets
        self.mySQL = ttk.LabelFrame(tab1, text=' Python Database ')
        self.mySQL.grid(column=0, row=0, padx=8, pady=4)        
        
        # Creating a Label
        ttk.Label(self.mySQL, text="Book Title:").grid(column=0, row=0, sticky='W')
   
        # Adding a Textbox Entry widget
        book = tk.StringVar()
        self.bookTitle = ttk.Entry(self.mySQL, width=34, textvariable=book)
        self.bookTitle.grid(column=0, row=1, sticky='W')     

        # Adding a Textbox Entry widget
        book1 = tk.StringVar()
        self.bookTitle1 = ttk.Entry(self.mySQL, width=34, textvariable=book1)
        self.bookTitle1.grid(column=0, row=2, sticky='W')  
        
        # Adding a Textbox Entry widget
        book2 = tk.StringVar()
        self.bookTitle2 = ttk.Entry(self.mySQL, width=34, textvariable=book2)
        self.bookTitle2.grid(column=0, row=3, sticky='W')  
        
        # Creating a Label
        ttk.Label(self.mySQL, text="Page:").grid(column=1, row=0, sticky='W')
        
        # Adding a Textbox Entry widget
        page = tk.StringVar()
        self.pageNumber = ttk.Entry(self.mySQL, width=6, textvariable=page)
        self.pageNumber.grid(column=1, row=1, sticky='W')     
 
        # Adding a Textbox Entry widget
        page = tk.StringVar()
        self.pageNumber1 = ttk.Entry(self.mySQL, width=6, textvariable=page)
        self.pageNumber1.grid(column=1, row=2, sticky='W')    
        
        # Adding a Textbox Entry widget
        page = tk.StringVar()
        self.pageNumber2 = ttk.Entry(self.mySQL, width=6, textvariable=page)
        self.pageNumber2.grid(column=1, row=3, sticky='W')           
       
        # Adding a Button
        self.action = ttk.Button(self.mySQL, text="Insert Quote", command=self.callBacks.insertQuote)   
        self.action.grid(column=2, row=1)

        # Adding a Button
        self.action1 = ttk.Button(self.mySQL, text="Get Quotes", command=self.callBacks.getQuote)   
        self.action1.grid(column=2, row=2)
        
        # Adding a Button
        self.action2 = ttk.Button(self.mySQL, text="Mody Quote", command=self.callBacks.modifyQuote)   
        self.action2.grid(column=2, row=3)
                
        # Add some space around each widget
        for child in self.mySQL.winfo_children(): 
            child.grid_configure(padx=2, pady=4)
            

        quoteFrame = ttk.LabelFrame(tab1, text=' Book Quotation ')
        quoteFrame.grid(column=0, row=1, padx=8, pady=4)    

        # Using a scrolled Text control    
        quoteW  = 40; quoteH = 6
        self.quote = scrolledtext.ScrolledText(quoteFrame, width=quoteW, height=quoteH, wrap=tk.WORD)
        self.quote.grid(column=0, row=8, sticky='WE', columnspan=3)   

        # Add some space around each widget
        for child in quoteFrame.winfo_children(): 
            child.grid_configure(padx=2, pady=4)
                            
        #======================================================================================================               
        # Tab Control 2 
        #======================================================================================================
        # We are creating a container frame to hold all other widgets -- Tab2
        self.widgetFrame = ttk.LabelFrame(tab2, text=self.i18n.WIDGET_LABEL)
        self.widgetFrame.grid(column=0, row=0, padx=8, pady=4)
        
        # Creating three checkbuttons
        self.chVarDis = tk.IntVar()
        self.check1 = tk.Checkbutton(self.widgetFrame, text=self.i18n.disabled, variable=self.chVarDis, state='disabled')
        self.check1.select()
        self.check1.grid(column=0, row=0, sticky=tk.W)               
        
        self.chVarUn = tk.IntVar()
        self.check2 = tk.Checkbutton(self.widgetFrame, text=self.i18n.unChecked, variable=self.chVarUn)
        self.check2.deselect()
        self.check2.grid(column=1, row=0, sticky=tk.W )                  
         
        self.chVarEn = tk.IntVar()
        self.check3 = tk.Checkbutton(self.widgetFrame, text=self.i18n.toggle, variable=self.chVarEn)
        self.check3.deselect()
        self.check3.grid(column=2, row=0, sticky=tk.W)                 
     
        # trace the state of the two checkbuttons
        self.chVarUn.trace('w', lambda unused0, unused1, unused2 : self.checkCallback())    
        self.chVarEn.trace('w', lambda unused0, unused1, unused2 : self.checkCallback())   
        
        # Radiobutton list
        colors = self.i18n.colors
        
        self.radVar = tk.IntVar()
        
        # Selecting a non-existing index value for radVar
        self.radVar.set(99)    
        
        # Creating all three Radiobutton widgets within one loop
        for col in range(3):
            self.curRad = 'rad' + str(col)  
            self.curRad = tk.Radiobutton(self.widgetFrame, text=colors[col], variable=self.radVar, value=col, command=self.callBacks.radCall)
            self.curRad.grid(column=col, row=6, sticky=tk.W, columnspan=3)
            # And now adding tooltips
            tt.createToolTip(self.curRad, 'This is a Radiobutton control.')
            
        # Create a container to hold labels
        labelsFrame = ttk.LabelFrame(self.widgetFrame, text=self.i18n.labelsFrame)
        labelsFrame.grid(column=0, row=7, pady=6)
         
        # Place labels into the container element - vertically
        ttk.Label(labelsFrame, text=self.i18n.chooseNumber).grid(column=0, row=0)
        self.lbl2 = tk.StringVar()
        self.lbl2.set(self.i18n.label2)
        ttk.Label(labelsFrame, textvariable=self.lbl2).grid(column=0, row=1)
        
        # Add some space around each label
        for child in labelsFrame.winfo_children(): 
            child.grid_configure(padx=6, pady=1)
            
        number = tk.StringVar()
        self.combo = ttk.Combobox(self.widgetFrame, width=12, textvariable=number)
        self.combo['values'] = (1, 2, 4, 42, 100)
        self.combo.grid(column=1, row=7, sticky=tk.W)
        self.combo.current(0)       
        self.combo.bind('<<ComboboxSelected>>', self.callBacks._combo) 
             
        # Adding a Spinbox widget using a set of values
        self.spin = Spinbox(self.widgetFrame, values=(1, 2, 4, 42, 100), width=5, bd=8, command=self.callBacks._spin) 
        self.spin.grid(column=2, row=7, sticky='W,', padx=6, pady=1)
        
        # Using a scrolled Text control    
        scrolW  = 40; scrolH = 1
        self.scr = scrolledtext.ScrolledText(self.widgetFrame, width=scrolW, height=scrolH, wrap=tk.WORD)
        self.scr.grid(column=0, row=8, sticky='WE', columnspan=3)      

        # Adding a TZ Button
        self.allTZs = ttk.Button(self.widgetFrame, text=self.i18n.timeZones, command=self.callBacks.allTimeZones)   
        self.allTZs.grid(column=0, row=9, sticky='WE')

        # Adding local TZ Button
        self.localTZ = ttk.Button(self.widgetFrame, text=self.i18n.localZone, command=self.callBacks.localZone)   
        self.localTZ.grid(column=1, row=9, sticky='WE')

        # Adding getTime TZ Button
        self.dt = ttk.Button(self.widgetFrame, text=self.i18n.getTime, command=self.callBacks.getDateTime)   
        self.dt.grid(column=2, row=9, sticky='WE')
        
                                
        # Create Manage Files Frame ------------------------------------------------
        mngFilesFrame = ttk.LabelFrame(tab2, text=self.i18n.mgrFiles)
        mngFilesFrame.grid(column=0, row=1, sticky='WE', padx=10, pady=5)
        
        # Button Callback
        def getFileName():
            print('hello from getFileName')
            fDir  = path.dirname(__file__)
            fName = fd.askopenfilename(parent=self.win, initialdir=fDir)
            print(fName)
            self.fileEntry.config(state='enabled')
            self.fileEntry.delete(0, tk.END)
            self.fileEntry.insert(0, fName)
            
            if len(fName) > self.entryLen:
                self.fileEntry.config(width=len(fName) + 3)
                        
        # Add Widgets to Manage Files Frame
        lb = ttk.Button(mngFilesFrame, text=self.i18n.browseTo, command=getFileName)     
        lb.grid(column=0, row=0, sticky=tk.W) 
        
        #-----------------------------------------------------        
        file = tk.StringVar()
        self.entryLen = scrolW - 4
        self.fileEntry = ttk.Entry(mngFilesFrame, width=self.entryLen, textvariable=file)
        self.fileEntry.grid(column=1, row=0, sticky=tk.W)
              
        #-----------------------------------------------------
        logDir = tk.StringVar()
        self.netwEntry = ttk.Entry(mngFilesFrame, width=self.entryLen, textvariable=logDir)
        self.netwEntry.grid(column=1, row=1, sticky=tk.W) 

        
        def copyFile():
            import shutil   
            src = self.fileEntry.get()
            file = src.split('/')[-1]  
            dst = self.netwEntry.get() + '\\'+ file
            try:
                shutil.copy(src, dst)   
                mBox.showinfo('Copy File to Network', 'Succes: File copied.')     
            except FileNotFoundError as err:
                mBox.showerror('Copy File to Network', '*** Failed to copy file! ***\n\n' + str(err))
            except Exception as ex:
                mBox.showerror('Copy File to Network', '*** Failed to copy file! ***\n\n' + str(ex))   
        
        cb = ttk.Button(mngFilesFrame, text=self.i18n.copyTo, command=copyFile)     
        cb.grid(column=0, row=1, sticky=tk.E) 
                
        # Add some space around each label
        for child in mngFilesFrame.winfo_children(): 
            child.grid_configure(padx=6, pady=6)            
            
        # Creating a Menu Bar ==========================================================
        menuBar = Menu(tab1)
        self.win.config(menu=menuBar)
        
        # Add menu items
        fileMenu = Menu(menuBar, tearoff=0)
        fileMenu.add_command(label=self.i18n.new)
        fileMenu.add_separator()
        fileMenu.add_command(label=self.i18n.exit, command=self.callBacks._quit)
        menuBar.add_cascade(label=self.i18n.file, menu=fileMenu)
        
        # Add another Menu to the Menu Bar and an item
        helpMenu = Menu(menuBar, tearoff=0)
        helpMenu.add_command(label=self.i18n.about)
        menuBar.add_cascade(label=self.i18n.help, menu=helpMenu)
        
        # Change the main windows icon
        self.win.iconbitmap(r'C:\Python34\DLLs\pyc.ico')
        
        # Using tkinter Variable Classes
        strData = tk.StringVar()
        strData.set('Hello StringVar')
        
        # It is not necessary to create a tk.StringVar() 
        strData = tk.StringVar()
        strData = self.spin.get()
        
        # Place cursor into name Entry
        self.bookTitle.focus()        
      
        # Add a Tooltip to the Spinbox
        tt.createToolTip(self.spin, 'This is a Spin control.')         
        
        # Add Tooltips to more widgets
        tt.createToolTip(self.bookTitle, 'This is an Entry control.')  
        tt.createToolTip(self.action, 'This is a Button control.')                      
        tt.createToolTip(self.scr,    'This is a ScrolledText control.')   
class OOP():
    def __init__(self): 
        # Create instance
        self.win = tk.Tk()   
        
        # Add a title       
        self.win.title("Python GUI")      
        self.createWidgets()
    
    # Button callback
    def clickMe(self):
        self.action.configure(text='Hello ' + self.name.get())
    
    # Button callback Clear Text   
    def clearScrol(self):
        self.scr.delete('1.0', tk.END)    
    
    # Spinbox callback 
    def _spin(self):
        value = self.spin.get()
        print(value)
        self.scr.insert(tk.INSERT, value + '\n')
        
    # Checkbox callback  
    def checkCallback(self, *ignoredArgs):
        # only enable one checkbutton
        if self.chVarUn.get(): self.check3.configure(state='disabled')
        else:             self.check3.configure(state='normal')
        if self.chVarEn.get(): self.check2.configure(state='disabled')
        else:             self.check2.configure(state='normal') 
        
    # Radiobutton callback function
    def radCall(self):
        radSel=self.radVar.get()
        if   radSel == 0: self.monty2.configure(text='Blue')
        elif radSel == 1: self.monty2.configure(text='Gold')
        elif radSel == 2: self.monty2.configure(text='Red')        

    # Exit GUI cleanly
    def _quit(self):
        self.win.quit()
        self.win.destroy()
        exit() 
    
    def usingGlobal(self):
        GLOBAL_CONST = 777
        print(GLOBAL_CONST)
            
    #####################################################################################    
    def createWidgets(self):    
        # Tab Control introduced here --------------------------------------
        tabControl = ttk.Notebook(self.win)     # Create Tab Control
        
        tab1 = ttk.Frame(tabControl)            # Create a tab 
        tabControl.add(tab1, text='Tab 1')      # Add the tab
        
        tab2 = ttk.Frame(tabControl)            # Add a second tab
        tabControl.add(tab2, text='Tab 2')      # Make second tab visible
        
        tabControl.pack(expand=1, fill="both")  # Pack to make visible
        # ~ Tab Control introduced here -----------------------------------------
        
        # We are creating a container frame to hold all other widgets
        self.monty = ttk.LabelFrame(tab1, text=' Monty Python ')
        self.monty.grid(column=0, row=0, padx=8, pady=4)        
        
        # Changing our Label
        ttk.Label(self.monty, text="Enter a name:").grid(column=0, row=0, sticky='W')
        
        # Adding a Textbox Entry widget
        self.name = tk.StringVar()
        nameEntered = ttk.Entry(self.monty, width=12, textvariable=self.name)
        nameEntered.grid(column=0, row=1, sticky='W')
        
        # Adding a Button
        self.action = ttk.Button(self.monty, text="Click Me!", command=self.clickMe)   
        self.action.grid(column=2, row=1)
        
        ttk.Label(self.monty, text="Choose a number:").grid(column=1, row=0)
        number = tk.StringVar()
        numberChosen = ttk.Combobox(self.monty, width=12, textvariable=number)
        numberChosen['values'] = (1, 2, 4, 42, 100)
        numberChosen.grid(column=1, row=1)
        numberChosen.current(0)
             
        # Adding a Spinbox widget using a set of values
        self.spin = Spinbox(self.monty, values=(1, 2, 4, 42, 100), width=5, bd=8, command=self._spin) 
        self.spin.grid(column=0, row=2)
                  
        # Using a scrolled Text control    
        scrolW  = 30; scrolH  =  3
        self.scr = scrolledtext.ScrolledText(self.monty, width=scrolW, height=scrolH, wrap=tk.WORD)
        self.scr.grid(column=0, row=3, sticky='WE', columnspan=3)
        
# TODO: ch11 new
    #------------------------------------------------------------------------- 
        #-------------------------------------------------------------------------    
        # Adding another Button
        self.action = ttk.Button(self.monty, text="Clear Text", command=self.clearScrol)   
        self.action.grid(column=2, row=2)
    
        # Adding more Feature Buttons
        startRow = 4
        for idx in range(12):
            if idx < 2:
                colIdx = idx
                col = colIdx
            else:
                col += 1
            if not idx % 3: 
                startRow += 1
                col = 0

            b = ttk.Button(self.monty, text="Feature " + str(idx+1))   
            b.grid(column=col, row=startRow)   
            
        # Tab Control 3  -----------------------------------------            
        tab3 = ttk.Frame(tabControl)            # Add a tab
        tabControl.add(tab3, text='Tab 3')      # Make tab visible
        
        # We are creating a container frame to hold all other widgets -- Tab3
        monty3 = ttk.LabelFrame(tab3, text=' New Features ')
        monty3.grid(column=0, row=0, padx=8, pady=4)

        # Adding more Feature Buttons
        startRow = 4
        for idx in range(24):
            if idx < 2:
                colIdx = idx
                col = colIdx
            else:
                col += 1
            if not idx % 3: 
                startRow += 1
                col = 0

            b = ttk.Button(monty3, text="Feature " + str(idx+1))   
            b.grid(column=col, row=startRow)    
            
        # Add some space around each label
        for child in monty3.winfo_children(): 
            child.grid_configure(padx=8)                                                                         
    #-------------------------------------------------------------------------    
# TODO: ch11 new end        
                       
        # Tab Control 2 refactoring  -----------------------------------------
        # We are creating a container frame to hold all other widgets -- Tab2
        self.monty2 = ttk.LabelFrame(tab2, text=' Holy Grail ')
        self.monty2.grid(column=0, row=0, padx=8, pady=4)
        # Creating three checkbuttons
        chVarDis = tk.IntVar()
        check1 = tk.Checkbutton(self.monty2, text="Disabled", variable=chVarDis, state='disabled')
        check1.select()
        check1.grid(column=0, row=0, sticky=tk.W)                 
        
        self.chVarUn = tk.IntVar()
        self.check2 = tk.Checkbutton(self.monty2, text="UnChecked", variable=self.chVarUn)
        self.check2.deselect()
        self.check2.grid(column=1, row=0, sticky=tk.W )                  
         
        self.chVarEn = tk.IntVar()
        self.check3 = tk.Checkbutton(self.monty2, text="Toggle", variable=self.chVarEn)
        self.check3.deselect()
        self.check3.grid(column=2, row=0, sticky=tk.W)                 
    
        # trace the state of the two checkbuttons
        self.chVarUn.trace('w', lambda unused0, unused1, unused2 : self.checkCallback())    
        self.chVarEn.trace('w', lambda unused0, unused1, unused2 : self.checkCallback())   
        # ~ Tab Control 2 refactoring  -----------------------------------------
        
        # Radiobutton list
        colors = ["Blue", "Gold", "Red"]
        
        self.radVar = tk.IntVar()
        
        # Selecting a non-existing index value for radVar
        self.radVar.set(99)    
        
        # Creating all three Radiobutton widgets within one loop
        for col in range(3):
            curRad = 'rad' + str(col)  
            curRad = tk.Radiobutton(self.monty2, text=colors[col], variable=self.radVar, value=col, command=self.radCall)
            curRad.grid(column=col, row=6, sticky=tk.W, columnspan=3)
            # And now adding tooltips
            tt.createToolTip(curRad, 'This is a Radiobutton control.')
            
        # Create a container to hold labels
        labelsFrame = ttk.LabelFrame(self.monty2, text=' Labels in a Frame ')
        labelsFrame.grid(column=0, row=7)
         
        # Place labels into the container element - vertically
        ttk.Label(labelsFrame, text="Label1").grid(column=0, row=0)
        ttk.Label(labelsFrame, text="Label2").grid(column=0, row=1)
        
        # Add some space around each label
        for child in labelsFrame.winfo_children(): 
            child.grid_configure(padx=8)
        
        
        # Creating a Menu Bar
        menuBar = Menu(tab1)
        self.win.config(menu=menuBar)
        
        # Add menu items
        fileMenu = Menu(menuBar, tearoff=0)
        fileMenu.add_command(label="New")
        fileMenu.add_separator()
        fileMenu.add_command(label="Exit", command=self._quit)
        menuBar.add_cascade(label="File", menu=fileMenu)
        
        # Add another Menu to the Menu Bar and an item
        helpMenu = Menu(menuBar, tearoff=0)
        helpMenu.add_command(label="About")
        menuBar.add_cascade(label="Help", menu=helpMenu)
        
        # Change the main windows icon
        self.win.iconbitmap(r'C:\Python34\DLLs\pyc.ico')
        
        # Using tkinter Variable Classes
        strData = tk.StringVar()
        strData.set('Hello StringVar')
        print(strData.get())
        
        # Default tkinter Variable Classes
        intData = tk.IntVar()
        print(intData.get())
        print(tk.DoubleVar())
        print(tk.BooleanVar())
        
        # It is not necessary to create a tk.StringVar() 
        strData = tk.StringVar()
        strData = self.spin.get()
        print("Hello " + strData)
        
        # Printing the Global works
        print(GLOBAL_CONST)
         
        # call method
        self.usingGlobal()
        
        # Place cursor into name Entry
        nameEntered.focus()     
        
        # Add a Tooltip to the Spinbox
        tt.createToolTip(self.spin, 'This is a Spin control.')         
        
        # Add Tooltips to more widgets
        tt.createToolTip(nameEntered, 'This is an Entry control.')  
        tt.createToolTip(self.action, 'This is a Button control.')                      
        tt.createToolTip(self.scr,    'This is a ScrolledText control.')
示例#8
0
文件: itsm.py 项目: saha65536/itsm
class AppUI():
    m_branchs = ['分行本部', '柯桥支行', '嵊州支行', '上虞支行', '世纪街支行', '诸暨支行', '新昌支行']
    m_ips = [
        '', '11.43.1.', '11.43.2.', '11.43.3.', '11.43.4.', '11.43.5.',
        '11.43.6.'
    ]
    m_floorIPs = [
        '11.43.128.', '11.43.129.', '11.43.130.', '11.43.131.', '11.43.132.',
        '11.43.133.', '11.43.134.'
    ]
    m_floors = ['一楼', '二楼', '三楼', '四楼', '五楼', '六楼', '十八楼']

    def __init__(self):
        self.root = Tk()
        self.root.option_add('*Dialog.msg.font', 'Helvetica 12')
        self.ft = tkFont.Font(family='FangSong', size=20, weight=tkFont.BOLD)

        self.selectedBranch = ''
        self.selectedFloor = ''

        self.create_menu(self.root)
        self.create_content(self.root)
        self.root.title("绍兴分行运维自动化工具")
        self.root.update()

        self.center_window()

    def center_window(self):
        curWidth = self.root.winfo_width()  # get current width
        curHeight = self.root.winfo_height()  # get current height
        scnWidth, scnHeight = self.root.maxsize(
        )  # get screen width and height
        tmpcnf = '+%d+%d' % ((scnWidth - curWidth) / 2,
                             (scnHeight - curHeight) / 2)
        self.root.geometry(tmpcnf)
        self.root.mainloop()

    def create_menu(self, root):
        #创建菜单栏
        menu = Menu(root)

        #创建二级菜单
        help_menu = Menu(menu, tearoff=0)
        help_menu.add_command(label="本系统由宁波银行绍兴分行金融科技部开发。" +
                              "\r\n如有问题请联系运维阮金国 王立刚8831")

        about_menu = Menu(menu, tearoff=0)
        about_menu.add_command(label="version:1.0")

        #在菜单栏中添加以下一级菜单
        menu.add_cascade(label="帮助", menu=help_menu)
        menu.add_cascade(label="关于", menu=about_menu)
        root['menu'] = menu

    def create_content(self, root):
        frm = LabelFrame(height=200, width=300, text='IP管理', borderwidth=3)
        frm.grid(row=0, column=0, pady=10)

        ttk.Label(frm, text=" 机 构: ", font=self.ft).grid(row=0,
                                                         column=0,
                                                         pady=10)
        self.branchWidget = ttk.Combobox(frm,
                                         textvariable=StringVar,
                                         state="readonly",
                                         width=10,
                                         font=self.ft)
        self.branchWidget['values'] = self.m_branchs
        self.branchWidget.bind("<<ComboboxSelected>>", self.branchGet)
        self.branchWidget.grid(row=0, column=1, columnspan=3, padx=10, pady=10)

        ttk.Label(frm, text=" 楼 层: ", font=self.ft).grid(row=1,
                                                         column=0,
                                                         pady=10)
        self.floorWidget = ttk.Combobox(frm,
                                        textvariable=StringVar,
                                        state="disabled",
                                        width=10,
                                        font=self.ft)

        self.floorWidget.bind("<<ComboboxSelected>>", self.floorGet)
        self.floorWidget.grid(row=1, column=1, columnspan=3, padx=10, pady=10)

        ttk.Label(frm, text=" 座位号: ", font=self.ft).grid(row=2,
                                                         column=0,
                                                         pady=10)
        ttk.Label(frm, text="  A", font=self.ft).grid(row=2, column=1, pady=10)
        self.netportWidget = Spinbox(frm,
                                     from_=0,
                                     to=255,
                                     width=5,
                                     bd=8,
                                     font=self.ft)
        self.netportWidget.grid(row=2, column=2)
        button = ttk.Button(frm, text="点我查看座位号", command=self.viewHelp)
        button.grid(row=2, column=3)

        ttk.Button(frm, text="设置IP", command=self.changeIP).grid(row=3,
                                                                 column=0,
                                                                 padx=10,
                                                                 pady=10)
        self.progress_bar = ttk.Progressbar(frm,
                                            orient='horizontal',
                                            mode='determinate',
                                            maximum=100,
                                            length=180)
        self.progress_bar.grid(row=3, column=1, columnspan=3, padx=10, pady=10)

    def viewHelp(self):
        tkinter.messagebox.showwarning(
            '提示',
            '请查座位下网口号上\n    A口后面的数字' + '\n     Axx   Bxx' + '\n      口      口')

    def branchGet(self, Event):
        self.selectedBranch = self.branchWidget.get()
        if self.m_branchs[0] == self.selectedBranch:
            self.floorWidget['values'] = self.m_floors
            self.floorWidget.configure(state='readonly')
        else:
            self.floorWidget.set('')
            self.floorWidget.configure(state='disabled')

    def floorGet(self, Event):
        self.selectedFloor = self.floorWidget.get()

    def getArrIndex(self, ele, array):
        for i in range(len(array)):
            if ele == array[i]:
                return i

        return -1

    def updateProcess(self, process):
        self.progress_bar['value'] = process
        self.progress_bar.update()

    def changeIP(self):

        ip = ''
        subnetmask = '255.255.255.0'
        gateway = ''

        self.updateProcess(10)

        selectedBranch = self.getArrIndex(self.selectedBranch, self.m_branchs)
        if -1 == selectedBranch:
            self.updateProcess(0)
            tkinter.messagebox.showwarning('提示', '请选择机构')
            return
        elif 0 == selectedBranch:  #分行本级
            selectedFloor = self.getArrIndex(self.selectedFloor, self.m_floors)
            if -1 == selectedFloor:
                self.updateProcess(0)
                tkinter.messagebox.showwarning('提示', '请选择楼层')
                return
            ip = self.m_floorIPs[selectedFloor]
        else:
            ip = self.m_ips[selectedBranch]

        self.updateProcess(30)

        netport = self.netportWidget.get()
        if '0' == netport:
            self.updateProcess(0)
            tkinter.messagebox.showwarning('提示', '请选择座位号')
            return
        gateway = ip + '254'
        ip = ip + netport
        dns = ['11.43.240.193', '11.43.240.194']

        print('ip:' + ip + ',gateway:' + gateway)

        self.updateProcess(40)

        # Obtain network adaptors configurations
        nic_configs = wmi.WMI().Win32_NetworkAdapterConfiguration(
            IPEnabled=True)
        # First network adaptor
        nic = nic_configs[0]

        self.updateProcess(60)

        # Set IP address, subnetmask and default gateway
        # Note: EnableStatic() and SetGateways() methods require *lists* of values to be passed
        returnValue = nic.EnableStatic(IPAddress=[ip], SubnetMask=[subnetmask])
        self.updateProcess(80)
        nic.SetDNSServerSearchOrder(DNSServerSearchOrder=dns)
        nic.SetGateways(DefaultIPGateway=[gateway])

        self.updateProcess(100)

        if 0 == returnValue[0]:
            tkinter.messagebox.showwarning('提示', 'ip修改成功!')
        else:
            tkinter.messagebox.showerror('错误', 'ip修改失败!')

        self.updateProcess(0)
示例#9
0
class VisAnaGUI(tk.LabelFrame):

    ## constants for current mode
    PLOT_MODE = 10
    ANALYTICS_MODE = 11
    ## constants for shown cluster plot
    SMALL_MULTIPLES = 20
    SMALL_HISTOS = 21

    #update levels, each level includes all lower ones
    NOTHING=0
    TIMELINE_SELECTION=1
    TIMELINE_DAYSINPLOT=2
    PLOT=3
    PLOT_DATA=4
    DATA_TIDYUP=5






    def __init__(self, master=None, ds=None):

        #self.dates = []
        #for dt in rrule.rrule(rrule.DAILY,
        #                      dtstart=datetime(2014,1,1,0,0,0),
        #                      until=datetime(2015,1,1,0,0,0)):
        #    self.dates.append(dt.date())
        self.mode = self.PLOT_MODE
        self.cluster_k = 4

        self.mininterval=60


        ## save data source
        self.ds = ds #type:datasource.DataSource
        # self.ds.groupby("all_days", datasource.TIME_ATTR, "COUNT","base", bydate=True)
        #self.ds.aggregateTime("all_days", "COUNT",60,"base")
        # self.ds.aggregateTime("all_days", "COUNT",24*60,"base")
        #self.ds.link("show")
        #self.df=ds.get_base_data().df()

        ## parameter variables for listboxes
        self.param_list = list(ds.get_data("base").get_attr_names())#["MasterTime", "Small", "Large", "OutdoorTemp","RelHumidity"]

        self.param2 = self.param_list[1]
        self.param1 = self.param_list[2]
        self.aggregation_limit=360

        ## simple string to describe last action (for history)
        self.action_str = "Show base data"

        self.plot_tooltip=None
        self.select_rect=None

        self.draw_frame(master)

        self.mouse_pressed=None
        self.clause=dict()

        ## save time of last update to prevent too many
        ## updates when using sliders
        self.last_action = time()
        ## delay after last data update and action (in ms)
        self.UPDATE_DELAY = 500
        ## was there an action triggering an update?
        # (0=no, 1=only the timeline, 2=axes and timeline, 3=with selection, 4 with tidyup)
        self.unprocessed_action = self.DATA_TIDYUP
        ## calls check_for_update() method after delay has passed
        self.after(self.UPDATE_DELAY, self.check_for_update)
        ## dummy variable to ignore first update. sliders trigger an
        ## event at startup, which would lead to redundant update of data
        self.ignore_start_trigger = True

        ## draw data at startup
        self.update_data()

    #######################
    # UI CREATION

    def draw_frame(self, master):
        tk.LabelFrame.__init__(self, master)#, bg="red")

        root.columnconfigure(0, weight=1)
        root.rowconfigure(0, weight=1)

        root.title("Visual Analyser - Gui")

        self.grid(column=0, row=0, sticky=(tk.N,tk.W,tk.E,tk.S))
        self.columnconfigure(1, weight=1)
        self.rowconfigure(3,weight=1)
        self.rowconfigure(2,minsize=100)
        #self.configure(background="red")

        self.create_widgets()

    ## creates all GUI elements
    def create_widgets(self):
        self.toolbar=tk.LabelFrame(self)
        self.toolbar.grid(column=0, row=0, sticky=(tk.W, tk.N, tk.E), columnspan=5)


        self.QUIT = tk.Button(self.toolbar, text="QUIT", fg="red", command=root.destroy)
        self.QUIT.grid(column=0, row=0, sticky=(tk.W, tk.N))

        self.reset_view_btn = tk.Button(self.toolbar)
        self.reset_view_btn["text"] = "Reset the View"
        self.reset_view_btn["command"] = self.reset_to_start
        self.reset_view_btn.grid(column=1, row=0, sticky=(tk.W, tk.N))

        self.toggle_hist_btn = tk.Button(self.toolbar)
        self.toggle_hist_btn["text"] = "Toggle History"
        self.toggle_hist_btn["command"] = self.toggle_history
        self.toggle_hist_btn.grid(column=4, row=0, sticky=(tk.W, tk.N))

        #        self.tdvar = tk.StringVar(value="0")
        #        self.tidy_up = tk.Checkbutton(self.toolbar, text='Tidy Up Data', command=self.handle_tidy_up,
        #                                      variable=self.tdvar)
        #        self.tidy_up.grid(column=2, row=0, sticky=(tk.W, tk.N))

        self.rgvar = tk.StringVar(value="0")
        self.regression = tk.Checkbutton(self.toolbar, text='Draw Regression', command=self.handle_regression,
                                         variable=self.rgvar)
        self.regression.grid(column=3, row=0, sticky=(tk.W, tk.N))

        self.left_sidebar = tk.Frame(self)
        self.left_sidebar.grid(column=0, row=3, sticky=(tk.N, tk.E, tk.W))

        self.projector = self.create_listboxes(self.left_sidebar)
        self.projector.grid(column=0, row=0, sticky=(tk.N, tk.E, tk.W))

        self.selector = Selector_old.Selector_old(self.left_sidebar, self.ds, self.handle_selector_change)
        self.selector.grid(column=0, row=1, sticky=(tk.N, tk.E, tk.W))



        self.history_text = "::LOG::\n"
        self.create_history()

        self.create_plot()

    def create_history(self):
        self.history_shown = True

        self.history = tk.Text(self, width=45)
        self.history.grid(column=2, row=3, sticky=(tk.N, tk.E, tk.S), rowspan=2)
        self.history.insert('end', self.history_text)

        self.history.see("end")

        self.historyslider = tk.Scrollbar(self,orient=tk.VERTICAL, command=self.history.yview)
        self.historyslider.grid(column=3, row=3, sticky=(tk.N, tk.S), rowspan=2)
        self.history['yscrollcommand'] = self.historyslider.set



    def create_listboxes(self, parent) -> tk.LabelFrame:
        frame=tk.LabelFrame(parent)#, bg="red")


        self.paramlabel = tk.Label(frame, text="Choose Parameters")
        self.paramlabel.grid(column=0, row=0, sticky=(tk.N, tk.E, tk.W), columnspan=2)

        ## listboxes for parameter selection
        self.param1lbl = tk.Label(frame, text="X-Axis:")
        self.param1lbl.grid(column=0, row=1, sticky=(tk.N, tk.E, tk.W))
        self.param1var = StringVar()
        self.param1var.set(self.param1)
        self.param1box=Combobox(frame, textvariable=self.param1var, state="readonly")
        self.param1box['values'] = self.param_list
        self.param1box.bind('<<ComboboxSelected>>', self.handle_paramsChanged)
        self.param1box.grid(column=1, row=1, sticky=(tk.N, tk.E, tk.W))


        self.param1lbl = tk.Label(frame, text="Y-Axis:")
        self.param1lbl.grid(column=0, row=2, sticky=(tk.N, tk.E, tk.W))
        self.param2var = StringVar()
        self.param2var.set(self.param2)
        self.param2box = Combobox(frame, textvariable=self.param2var, state="readonly")
        self.param2box['values'] = self.param_list
        self.param2box.bind('<<ComboboxSelected>>', self.handle_paramsChanged)
        self.param2box.grid(column=1, row=2, sticky=(tk.N, tk.E, tk.W))

        #        self.param2box = Listbox(self.projector, exportselection=0)
        #        for item in self.param_list:
        #            self.param2box.insert("end", item)
        #        param2_index = self.param_list.index(self.param2)
        #        self.param2box.select_set(param2_index)
        #        self.param2box.bind('<<ComboboxSelected>>', self.handle_paramsChanged)
        #        self.param2box.grid(column=0, row=2, sticky=(tk.N, tk.E, tk.W))

        self.var = StringVar(frame)
        self.var.set(str(self.aggregation_limit))
        self.noise_spin = Spinbox(frame, from_=1, to=1440, textvariable=self.var ,width=4)
        self.noise_spin.grid(column=0, row=3, sticky=(tk.E, tk.W))

        self.testbutton = tk.Button(frame)
        self.testbutton["text"] = "Aggregate values (minutes)"
        self.testbutton["command"] = self.handle_aggregate_btn
        self.testbutton.grid(column=1, row=3, sticky=(tk.W, tk.N))
        return frame

    # ## add sliders to GUI
    # def create_sliders(self):
    #     ## init sliders
    #
    #     #self.filter = tk.LabelFrame(self, bg="#0066ff")
    #     self.filter = tk.LabelFrame(self, bg="red")
    #     self.filter.grid(column=0, row=1, sticky=(tk.N, tk.E, tk.W),columnspan=5)
    #     self.filter.columnconfigure(1, weight=1)
    #     self.filter.columnconfigure(0, weight=0)
    #
    #     self.startSlider = Scale(self.filter, from_=0, to=365, orient=HORIZONTAL, command=self.update_start)
    #     self.startSlider.set(0)
    #     self.endSlider = Scale(self.filter, from_=0, to=365, orient=HORIZONTAL, command=self.update_end)
    #     self.endSlider.set(365)
    #
    #     ## add sliders and labels to GUI
    #     self.startSlider.grid(column=1, row=0, sticky=(tk.W, tk.N, tk.E))
    #     self.startlabel = tk.Label(self.filter, text="FROM \tVALUE")
    #     self.startlabel.grid(column=0, row=0, sticky=(tk.W))
    #     self.endSlider.grid(column=1, row=1, sticky=(tk.W, tk.S, tk.E))
    #     self.endlabel = tk.Label(self.filter, text="TO \tVALUE")
    #     self.endlabel.grid(column=0, row=1, sticky=(tk.W))

    #add an empty plot to the GUI
    def create_plot(self):
        self.fig = Figure(figsize=(5, 5), dpi=100) #type:Figure
        self.ax = self.fig.add_subplot(111) #type:Axes
        #self.ax2 = self.fig.add_subplot(212)
        self.ax.grid(True)
        self.canvas = FigureCanvasTkAgg(self.fig, self) ##type:FigureCanvasTkAgg

        self.canvas.mpl_connect('motion_notify_event', self.handle_hover)
        self.canvas.mpl_connect('button_press_event', self.handle_mouse_down)
        self.canvas.mpl_connect('button_release_event', self.handle_mouse_up)
        #self.canvas.mpl_connect('pick_event', self.draw_tooltip)

        self.canvas.get_tk_widget().grid(column=1, row=3, sticky=(tk.N, tk.E, tk.W, tk.S))

        # self.canvas_tb = NavigationToolbar2TkAgg(self.canvas, self.canvas.get_tk_widget())
        #self.ctbwidget=tk.Frame(self)
        #self.ctbwidget.grid(column=1, row=4, sticky=(tk.N, tk.E, tk.W, tk.S))
        #self.canvas_tb = NavigationToolbar2TkAgg(self.canvas, self.ctbwidget)

        util.zoom_factory(self.ax)


    ############################
    # UI HANDLER

    ## generate clusters and asks for custom grain classes
    def create_clusters(self, in_table="base"):
        ## call dialogue window to ask for custom grain classes
        Mbox = GrainSelection.Mbox
        Mbox.root = root
        mbox = Mbox()
        ## wait for answer
        root.wait_window(mbox.top)
        ## -> result is in mbox.classesDict

        ## ask if valid answer has been submitted
        if mbox.success:
            ## fetch answers in dict with changed labels
            custom_classes_dict = {}
            #print(mbox.classesDict)
            for k,v in mbox.classesDict.items():
                col = "GRAIN_CLASS_"+str(k)
                custom_classes_dict[col] = v
            self.c_param_list = sorted(list(custom_classes_dict.keys()))

            #print("CREATE CLUSTERS")

            ## call analytics functions
            analytics.create_distributions(in_table, "out", self.ds, custom_classes_dict=custom_classes_dict)
            self.centroids = analytics.calc_clusters(in_table="cluster_distr", out_table="clustered", datasource=self.ds, k=self.cluster_k, colNames=self.c_param_list)
            #print("\tCLUSTERED")

            ## change state variables so the proper graph is displayed
            self.mode = self.ANALYTICS_MODE
            #self.plot_type = self.SMALL_HISTOS
            self.plot_type = self.SMALL_MULTIPLES
            #print("change mode to ",self.mode)

            ## TODO: might need to be changed?!
            self.unprocessed_action=self.PLOT_DATA

            self.add_to_history("generate clusters")
            self.action_str = "Generate clusters"
            #print("\tCLUSTERING FINISHED")

    ## dummy method
    def reset_to_start(self):
        self.create_clusters()


        self.clean_tooltip(True)
        #self.param1box.select_set(self.param_list.index("Large"))
        #self.param2box.select_set(self.param_list.index("Small"))
        #        self.startSlider.set(0)
        #        self.endSlider.set(365)
        self.var.set("1")
        self.handle_aggregate_btn()
        #self.tdvar.set("0")
        self.unprocessed_action=self.DATA_TIDYUP

        self.add_to_history("reset to basedata")
        self.action_str = "Show base data"
        #print("hi there, everyone!")

    def toggle_history(self):
        if self.history_shown:
            self.destroy_history()
        else:
            self.create_history()

    def destroy_history(self):
        self.history_shown = False
        self.history.destroy()
        self.historyslider.destroy()
    #self.history_text = self.history.

    def handle_aggregate_btn(self):
        self.aggregation_limit = int(self.noise_spin.get())

        self.action_str = "Aggregated values: "+str(self.aggregation_limit)+"min"

        self.trigger_update(level=self.PLOT_DATA)

    #    def handle_tidy_up(self):
    #        if self.tdvar.get() is "0":
    #            self.action_str="show raw data"
    #        else:
    #            self.action_str="tidy up data, remove all points where:" \
    #                            "\n  OutdoorTemp>40 or Small<0 or Large<0 or " \
    #                            "\n  RelHumidity<0"
    #        self.trigger_update(level=self.DATA_TIDYUP)

    def handle_regression(self):
        if self.rgvar.get() is "0":
            self.action_str="hide regression"
        else:
            self.action_str="draw regression"
        self.trigger_update(level=self.PLOT)

    def handle_view_change(self,ax=None):
        if ax is None:
            ax=self.ax
        self.handle_changed_axes()
        print("viewport changed to", ax.get_xlim(), ax.get_ylim())

    #########
    ## SLIDER METHODS
    ## we need separate update functions for the sliders, 
    ## as we could otherwise not distinguish between changing
    ## the first or second slider
    #########

    # ## triggered by changing startslider value
    # def update_start(self, event):
    #     fromVal = self.startSlider.get()
    #     endVal = self.endSlider.get()
    #     if endVal < fromVal:
    #         self.endSlider.set(fromVal)
    #
    #     self.handle_slider_update()
    #
    # ## triggered by changing endslider value
    # def update_end(self, event):
    #     fromVal = self.startSlider.get()
    #     endVal = self.endSlider.get()
    #     if endVal < fromVal:
    #         self.startSlider.set(endVal)
    #
    #     self.handle_slider_update()
    #
    # ## handle data update event, i.e. a slider changed.
    # def handle_slider_update(self):
    #     fromVal = self.startSlider.get()
    #     endVal = self.endSlider.get()
    #     self.startlabel["text"] = "FROM \t"+str(self.dates[fromVal])
    #     self.endlabel["text"] = "TO \t"+str(self.dates[endVal])
    #     self.trigger_update(level=self.PLOT_DATA)
    #     self.last_action = time()
    #     self.action_str = "New time interval: "+str(self.dates[fromVal])+" - "+str(self.dates[endVal])

    ## handle data update event, i.e. a slider changed.
    def handle_selector_change(self,clause):
        self.clause=clause

        self.trigger_update(level=self.PLOT_DATA)
        self.last_action = time()
        self.action_str = "New selection: "+str(clause)



    ## a different parameter was chosen
    def handle_paramsChanged(self, e):
        #self.param1 = self.param_list[self.param1box.curselection()[0]]
        self.param1 = self.param1var.get()
        self.param1box.select_clear()


        self.param2 = self.param2var.get()
        self.param2box.select_clear()
        #        self.param2 = self.param_list[self.param2box.curselection()[0]]

        self.action_str = "New parameters: " + self.param1 + " & " + self.param2
        self.trigger_update(level=self.PLOT)



    ###################
    # PLOT-EVENT HANDLER

    def handle_changed_axes(self):
        self.clean_tooltip()
        xlim = self.ax.get_xlim()
        ylim = self.ax.get_xlim()

        text="Focus changed to: x=[{:.1f};{:.1f}] and y=[{:.1f};{:.1f}]".format(xlim[0], xlim[1], ylim[0], ylim[1])
        self.add_to_history(text)
    ## is called by the plot to confirm if the mouseevent was inside/on a plotted line or a marker
    def handle_pick(self, line, mouseevent):

        if mouseevent.button == 1:
            return self.handle_mouse_event(mouseevent)
        else:
            return False,dict()

    ## is called to to do something when the mouse hovers over the plot and has changed its position.
    ## if no mousebutton is pressed and no points were selected, a hover-tooltip is shown.
    ## if the left button is pressed, (re-)draw the selection indicator
    i=1
    def handle_hover(self, mouseevent):
        if not mouseevent.button in [1,3] and self.select_rect is None:
            isover, props = self.handle_mouse_event(mouseevent)

            if isover:
                self.draw_tooltip(mouseevent, props["ind"])

        elif mouseevent.button in [1,3]:
            ## handle case if mouse is outside the canvas
            if mouseevent.xdata == None:
                xmin = self.mouse_pressed[0]
                xmax = self.mouse_pressed[0]
                ymin = self.mouse_pressed[1]
                ymax = self.mouse_pressed[1]
            else:
                xmin = min(mouseevent.xdata, self.mouse_pressed[0])
                xmax = max(mouseevent.xdata, self.mouse_pressed[0])
                ymin = min(mouseevent.ydata, self.mouse_pressed[1])
                ymax = max(mouseevent.ydata, self.mouse_pressed[1])
            bbox=(xmin, ymin, xmax, ymax)
            self.clean_tooltip(True, emit=False)
            bbox2=self.ax.transData.transform(bbox)
            c_height = self.canvas.figure.bbox.height
            bbox3=(bbox2[0], c_height-bbox2[1], bbox2[2],c_height-bbox2[3])
            self.select_rect = self.canvas.get_tk_widget().create_rectangle(bbox3, dash=".")

    ## is called whenever a mousebutton is clicked while the mouse is over the plot.
    ##  if the left button is pushed, we begin to draw a selection area
    def handle_mouse_down(self, mouseevent):
        if mouseevent.button in [1,3]:
            self.clean_tooltip(True)
            self.mouse_pressed=(mouseevent.xdata, mouseevent.ydata)

    ## is called whenever a mouse button is released while hovering over the plot
    ## if the left button was pressed and there are points within the selection area, select those points and show a
    ##  tooltip containing information about those selected points. If not, clean up.
    def handle_mouse_up(self, mouseevent):
        if mouseevent.button in [1,3]:
            ## handle case if mouse is outside the canvas
            if mouseevent.xdata == None:
                xmin = self.mouse_pressed[0]
                xmax = self.mouse_pressed[0]
                ymin = self.mouse_pressed[1]
                ymax = self.mouse_pressed[1]
            else:
                xmin = min(mouseevent.xdata, self.mouse_pressed[0])
                xmax = max(mouseevent.xdata, self.mouse_pressed[0])
                ymin = min(mouseevent.ydata, self.mouse_pressed[1])
                ymax = max(mouseevent.ydata, self.mouse_pressed[1])
            if xmin == xmax and ymin == ymax:
                self.clean_tooltip(True)
            else:
                if mouseevent.button == 1:
                    if self.param1 == datasource.TIME_ATTR:
                        xmin = mdates.num2date(xmin)
                        xmax = mdates.num2date(xmax)
                    if self.param2 == datasource.TIME_ATTR:
                        ymin = mdates.num2date(ymin)
                        ymax = mdates.num2date(ymax)
                    self.ds.select("selected", self.param1, xmin, xmax, "show")
                    self.ds.select("selected", self.param2, ymin, ymax, "selected")
                    ind=self.df("selected").index.values
                    if len(ind)>0:
                        self.action_str="Selected area from ({:.1f}; {:.1f})\n\t to ({:.1f}; {:.1f})".format(xmin,ymin,xmax,ymax)
                        #self.add_to_history(text)
                        self.draw_tooltip(mouseevent,ind, True)
                        self.trigger_update(level=self.TIMELINE_SELECTION)
                    else:
                        self.clean_tooltip(True)
                else:
                    self.clean_tooltip(True, emit=False)
                    self.ax.set_xlim((xmin,xmax))
                    self.ax.set_ylim((ymin,ymax))
                    self.canvas.draw()

    ## handle any mouse event where it has to be clarified whether there's a marker under the mouse or not. If so,
    ##  return all index values of the concerning markers.
    def handle_mouse_event(self, mouseevent, radius=5):
        """
        find the points within a certain radius from the mouse in
        data coords and attach the index numbers of the found elements
        which are the data points that were picked
        """
        self.clean_tooltip()

        #print("PICKER")
        #print(mouseevent, vars(mouseevent))
        if self.param1 == datasource.TIME_ATTR or self.param2 == datasource.TIME_ATTR:
            return False,dict()
        xydata=self.ax.transData.transform(self.df("show")[[self.param1, self.param2]]).transpose()
        try:
            mxy= self.ax.transData.transform([mouseevent.xdata,mouseevent.ydata])
        except ValueError:
            return False,dict()
        xdata=xydata[0]
        ydata=xydata[1]
        mousex=mxy[0]
        mousey=mxy[1]
        if mouseevent.xdata is None:
            return False, dict()

        d = pd.np.sqrt((xdata - mousex)**2. + (ydata - mousey)**2.)
        ind = self.df("show").index.values[pd.np.nonzero(pd.np.less_equal(d, radius))[0]]

        if len(ind) >0:
            props = dict(ind=ind)
            return True, props
        else:
            return False, dict()

    ## draws a tooltip and generates the information it contains from an event with/and a list of index values
    def draw_tooltip(self, event, ind=None, selected=False):
        if ind is None:
            ind=event.ind
            event=event.mouseevent

        # Generate the Tooltip-String
        selstr=""
        if selected:
            selstr= "selected "

        if len(ind) is 1:
            text=selstr + "value:"
            self.ds.select_ids("selected", ind, "show")
            for col,cdata in self.df("selected").iteritems():
                text += '\n {}: \t{}'.format(col, cdata[ind[0]])
        else:
            text = selstr + "%s values:" % len(ind)
            if not selected:
                self.ds.select_ids("selected", ind, "show")
            self.ds.aggregate("sel_aggremin", "MIN", in_table="selected")
            self.ds.aggregate("sel_aggremax", "MAX", in_table="selected")

            for col,cdata in self.df("sel_aggremin").iteritems():
                text += '\n {}: \t{} to {}'.format(col, cdata[0], self.df("sel_aggremax")[col][0])

        # Draw the box and write the string on it

        c_height=self.canvas.figure.bbox.height
        c_width=self.canvas.figure.bbox.width
        y=c_height-event.y
        x=event.x

        #get bounding box of a possible tooltip
        self.plot_tooltip=self.canvas.get_tk_widget().create_text(x+2, y, anchor=tk.NW,text=text)
        bbox=self.canvas.get_tk_widget().bbox(self.plot_tooltip)
        self.canvas.get_tk_widget().delete(self.plot_tooltip)

        # print("bbox:", bbox)

        #make sure the tooltip is within bounds
        if bbox[2]>c_width:
            adj = -2
            if bbox[3]>c_height:
                anchor=tk.SE
            else:
                anchor=tk.NE
        else:
            adj = 2
            if bbox[3]>c_height:
                anchor=tk.SW
            else:
                anchor=tk.NW
        #get the new bounding box
        if anchor is not tk.NW: # =^= the anchor had to be modified
            self.plot_tooltip=self.canvas.get_tk_widget().create_text(x+adj, y, anchor=anchor,text=text)
            bbox=self.canvas.get_tk_widget().bbox(self.plot_tooltip)
            self.canvas.get_tk_widget().delete(self.plot_tooltip)

        self.plot_tooltip_rect = self.canvas.get_tk_widget().create_rectangle(bbox, fill="yellow")
        self.plot_tooltip=self.canvas.get_tk_widget().create_text(x+adj, y, anchor=anchor,text=text)


    # draws a timeline (as a plot)
    def draw_timeline(self):

        #df = self.df("show")
        ## create value for each day in data,
        ## depending on whether it is selected, shown etc.
        #shown_dates = self.build_contained_dict(df)
        if self.aggregation_limit <= self.mininterval:
            self.ds.aggregateTime("all_days", "COUNT", self.mininterval, "base")
        else:
            self.ds.aggregateTime("all_days", "COUNT", self.aggregation_limit, "base")

        selected_dates=[]
        if self.select_rect is not None:
            print("b",self.ds.exists("selected"))
            #self.ds.groupby2("selected_days", datasource.TIME_ATTR, "COUNT", "selected", bydate=True)
            #self.ds.aggregateTime("selected_days", "COUNT",24*60, "selected")
            self.ds.aggregateTime("selected_days", "COUNT",1, "selected")
            selected_dates = self.df("selected_days").index.values
        shown_dates=self.df("shown_dates").index.values

        base_dates=self.df("all_days").index.values

        ## extract first and last date
        start_date = base_dates[0]
        end_date = base_dates[-1]
        #days_diff = ((end_date-start_date) / np.timedelta64(1, 'D'))

        ## prepare data for timeline
        days = []
        values = []
        #print(self.df("all_days").head(2))

        #self.df("all_days").
        for date in self.df("all_days").index.values:
            self.df("all_days")
            col1_has_values=((self.param1 == datasource.TIME_ATTR) or (self.df("all_days")[self.param1][date]>0))
            col2_has_values=((self.param2 == datasource.TIME_ATTR) or (self.df("all_days")[self.param2][date]>0))
            if col1_has_values and col2_has_values:
                days.append(date)
                ##if random() < 0.01:
                #if self.dates[self.startSlider.get()] <= day < self.dates[self.endSlider.get()]:
                if date in shown_dates:
                    values.append("blue")
                    if date in selected_dates:
                        #if random() < 0.05:
                        values.append("red")
                else:
                    values.append("lightskyblue")
        #print("d:",days, values)

        ## plot timeline
        fig = Figure(figsize=(12,1), dpi=75)
        ax = fig.add_subplot(111)

        ax.scatter(days, [1]*len(days), c=values,
                   marker='|', s=300)#, fontsize=10)
        #fig.xt
        hfmt = mdates.DateFormatter("1. %b '%y")
        # fig.subplots_adjust(left=0.03, right=0.97, top=1)

        ax.xaxis.set_major_formatter(hfmt)
        fig.autofmt_xdate()
        #ax.set_xticklabels(ax.xaxis.get_minorticklabels(), rotation=0)

        #ax.set_xlim([datetime(2014,1,1,0,0,0), datetime(2015,1,1,0,0,0)])
        ax.set_xlim([start_date, end_date])


        ## everything after this is turning off stuff that's plotted by default
        ax.yaxis.set_visible(False)
        ax.spines['right'].set_visible(False)
        ax.spines['left'].set_visible(False)
        ax.spines['top'].set_visible(False)
        ax.xaxis.set_ticks_position('bottom')
        ax.get_yaxis().set_ticklabels([])
        fig.tight_layout(pad=0)

        #print(fig.get_figheight())
        #fig.subplots_adjust(top=1, right=0.99)

        ## add to GUI
        self.timeline = FigureCanvasTkAgg(fig, self)
        self.timeline.get_tk_widget().grid(column=0, row=2, sticky=(tk.N, tk.E, tk.W, tk.S),columnspan=5)
        #print("h:",self.timeline.figure.bbox.height)

    #####################
    # UPDATE-FUNCTIONS

    ## is called regularly, after the given delay
    def check_for_update(self):
        ## if there is an unprocessed action older than
        ## the given delay, update data

        #self.check_listbox_changes()

        if self.unprocessed_action>self.NOTHING and \
                        (time() - self.last_action) > self.UPDATE_DELAY/1000:
            ## simply block the very first update...
            ## (there might be prettier solutions)
            if self.ignore_start_trigger:
                self.ignore_start_trigger = False
            else:
                ## update data
                self.update_data()
        #print("checking for updates...")
        self.after(self.UPDATE_DELAY, self.check_for_update)

    """
     general data tasks:
     after_tidyup [-> apply sliders ->]
     time-limited [-> (don't) aggregate ->]
     show

     show [-> select ->]
     selected [-> get min and max ->]



    """
    ## draw new data according to current positions of date sliders and the aggregation limit
    def update_data(self):
        #if self.unprocessed_action >= self.DATA_TIDYUP:
            #if self.tdvar.get() is "0":
            #    self.ds.link("after_tidyup","base")
            #else:
            #    self.ds.select("after_tidyup", "Large",a=0, in_table="base")
            #    self.ds.select("after_tidyup", "OutdoorTemp",b=40, in_table="after_tidyup")
            #    self.ds.select("after_tidyup", "RelHumidity",a=0, in_table="after_tidyup")
            #    self.ds.select("after_tidyup", "Small",a=0, in_table="after_tidyup")
                #self.action_str = "tidy up data, remove all points where:" \
                #                  "\n\tOutdoorTemp>40 or Small<0 or Large<0 or " \
                #                  "\n\tRelHumidity<0 or RelHumidity>100"

        if self.unprocessed_action >=self.PLOT_DATA:
            #fromVal = self.startSlider.get()
            #endVal = self.endSlider.get()

            #self.ds.link("time-limited","after_tidyup")
            #self.ds.select(out_table="time-limited", attr_name=datasource.TIME_ATTR,
            #    a=self.dates[fromVal], b=self.dates[endVal], in_table="after_tidyup")
            #self.df = self.ds.get_data("time_filter").df()
            self.ds.select_complex("sel",self.clause, "base")
            if self.aggregation_limit==1:
                self.ds.link("show", "sel")
            else:
                self.ds.aggregateTime(out_table="show", mode="AVG", minutes=self.aggregation_limit, in_table="sel")
                #self.ds.aggregate(out_table="show", mode="AVG", limit=self.aggregation_limit, in_table="base")
            #self.ds.groupby("shown_dates",datasource.TIME_ATTR, "COUNT", "show", bydate=True)
            self.ds.aggregateTime("shown_dates","COUNT", self.aggregation_limit, in_table="sel")
            #self.ds.aggregateTime("shown_dates","COUNT", 24*60,"show")
        #        try:
        if self.unprocessed_action>=self.PLOT:
            if self.mode == self.PLOT_MODE:
                print("draw normal plots")
                self.draw_plot()
            elif self.mode == self.ANALYTICS_MODE:
                print("draw cluster plots")
                if self.plot_type == self.SMALL_MULTIPLES:
                    print("\tdraw small multiples")
                    self.create_multiple_plots()
                elif self.plot_type == self.SMALL_HISTOS:
                    print("\tdraw small histograms")
                    self.create_distr_plots()

        self.draw_timeline()
        #print("add_to_history:",self.action_str)
        if self.action_str is not None:
            self.add_to_history(self.action_str)
        #        except:
        #            pass
        self.unprocessed_action=self.NOTHING

    def create_distr_plots(self):
        self.clean_tooltip(True)
        self.fig = Figure(figsize=(5, 5), dpi=100) #type:Figure
        self.ax = self.fig.add_subplot(111) #type:Axes

        #subplot_num = 0
        #print(self.centroids)
        y_pos = np.arange(len(self.c_param_list))
        #print(y_pos)
        width = 0.95/self.cluster_k
        #colors = ["#d62728", "blue", "green", "brown"]
        for c in range(0, self.cluster_k):
            #subplot_num += 1
            ystdev = []
            one_value_cluster = self.df("clustered").loc[self.df("clustered")['clusterlabels'] == c]

            #for i in range(0, len(datasource.GRAIN_COLS)):
            for i in range(0, len(self.c_param_list)):
                col = one_value_cluster[self.c_param_list[i]]
                stdev = np.std(col)
                ystdev.append(stdev)

            cen = [self.centroids[c][i] for i in range(0, len(self.c_param_list))]
            ## cluster label for legend 
            c_label = "Cluster "+str(c)
            self.ax.bar(y_pos + width*(c-(self.cluster_k/2.3)), cen, width, align="center", alpha=0.75, color=COLORS[c], ecolor="black", yerr=ystdev, label=c_label)
        self.ax.grid(True)
        #self.ax.set_xticklabels
        #self.ax.set_ylim(0, 1, emit=False)
        max_y_val = max(map(max, self.centroids))
        self.ax.set_ylim(0, max_y_val+0.1, emit=False)

        self.ax.set_xticks(y_pos + width / 4)
        self.ax.set_xticklabels(self.c_param_list)

        self.ax.callbacks.connect('xlim_changed', self.handle_view_change)
        self.ax.callbacks.connect('ylim_changed', self.handle_view_change) 
        
        ## add legend
        self.ax.legend(loc="upper right", shadow=True)

        self.canvas = FigureCanvasTkAgg(self.fig, self) ##type:FigureCanvasTkAgg

        #self.canvas.mpl_connect('motion_notify_event', self.handle_hover)
        #self.canvas.mpl_connect('button_press_event', self.handle_mouse_down)
        #self.canvas.mpl_connect('button_release_event', self.handle_mouse_up)
        #self.canvas.mpl_connect('pick_event', self.draw_tooltip)

        self.canvas.get_tk_widget().grid(column=1, row=3, sticky=(tk.N, tk.E, tk.W, tk.S))

        # self.canvas_tb = NavigationToolbar2TkAgg(self.canvas, self.canvas.get_tk_widget())
        #self.ctbwidget=tk.Frame(self)
        #self.ctbwidget.grid(column=1, row=4, sticky=(tk.N, tk.E, tk.W, tk.S))
        #self.canvas_tb = NavigationToolbar2TkAgg(self.canvas, self.ctbwidget)

        util.zoom_factory(self.ax)

        self.fig.tight_layout(pad=0)
        self.canvas.draw()

        #print("DISTRIBUTIONS PLOTTED")


    #add an empty plot to the GUI
    def create_multiple_plots(self):
        self.clean_tooltip(True)
        self.fig = Figure(figsize=(5, 5), dpi=100) #type:Figure

        param_combos = []
        subplot_num = 0
        paraLen = len(self.c_param_list)
        axarr = [[]]
        dummy = [[]]
        sharey = {}

        for qi in range(0, paraLen):
            q = self.c_param_list[qi]
            #subplot_num = ((subplot_num%10)*10)+111
            #print("subplot_num=",str(subplot_num))
            for pi in range(0, paraLen):
                #print("qi =",str(qi))
                p = self.c_param_list[pi]
                #subplot_num += 1
                if pi < qi:#not p == q: 
                    subplot_num = (qi-1)*(paraLen-1) + (pi+1)
                    print(subplot_num)
                    #print("\tsubplot_num=",str(subplot_num))
                    param_combos.append((p,q))
                    x = self.df("clustered")[p]
                    y = self.df("clustered")[q]
                    print("pi=",str(pi),"qi=",str(qi))
                    #if qi>0 & pi>0:
                    #    self.ax = self.fig.add_subplot(paraLen-1, paraLen-1, subplot_num, sharex=axarr[0][pi-1], sharey=axarr[qi][0])
                    #if qi>1:
                    #    ax1 = self.fig.add_subplot(paraLen-1, paraLen-1, subplot_num, sharex=sharex[pi])
                    #if pi>1:
                    #    ax1 = self.fig.add_subplot(paraLen-1, paraLen-1, subplot_num, sharey=sharey[qi])
                    #else:
                    ax1 = self.fig.add_subplot(paraLen-1, paraLen-1, subplot_num) 

                    #if pi==0:
                    #    print("add sharey for",str(qi))
                    #    sharey[qi] = ax1

                    #print(self.centroids[1,0])
                    for i in range(self.cluster_k):
                        one_value_cluster = self.df("clustered").loc[self.df("clustered")['clusterlabels'] == i]
                        ax1.scatter(one_value_cluster[self.c_param_list[pi]], one_value_cluster[self.c_param_list[qi]], color=COLORS[i], marker=".", alpha=0.1, s=2)
                        #print("i:",str(i),"pi:",str(pi),"qi:",str(qi))
                        ax1.plot(self.centroids[i][pi],self.centroids[i][qi],'kx')

                    #self.plot=self.ax.scatter(x=x, y=y, marker="o", linewidths=0,picker=self.handle_pick)

                    if qi == paraLen-1:
                        paraLabel = p
                        if "GRAIN_CLASS" in p: #custom class
                            paraLabel = "CLASS"+p[-1]
                        ax1.set_xlabel(paraLabel)
                    else:
                        ax1.set_xticklabels([])

                    if pi == 0:
                        paraLabel = q
                        if "GRAIN_CLASS" in q: #custom class
                            paraLabel = "CLASS"+q[-1]
                        ax1.set_ylabel(paraLabel)
                    else:
                        ax1.set_yticklabels([])

                    ax1.grid(True)
                    ax1.set_xlim(x.min(), x.max(), emit=False)
                    ax1.set_ylim(y.min(), y.max(), emit=False)
                    #ax1.callbacks.connect('xlim_changed', self.handle_view_change)
                    #ax1.callbacks.connect('ylim_changed', self.handle_view_change) 
                    #axarr[-1].append(ax1)
                    #dummy[-1].append(0)
                    #if pi == paraLen-1:
                    #    axarr.append([])
                    #    dummy.append([])
                    #print(axarr)


        self.canvas = FigureCanvasTkAgg(self.fig, self) ##type:FigureCanvasTkAgg

        #self.canvas.mpl_connect('motion_notify_event', self.handle_hover)
        #self.canvas.mpl_connect('button_press_event', self.handle_mouse_down)
        #self.canvas.mpl_connect('button_release_event', self.handle_mouse_up)
        #self.canvas.mpl_connect('pick_event', self.draw_tooltip)

        self.canvas.get_tk_widget().grid(column=1, row=3, sticky=(tk.N, tk.E, tk.W, tk.S))

        # self.canvas_tb = NavigationToolbar2TkAgg(self.canvas, self.canvas.get_tk_widget())
        #self.ctbwidget=tk.Frame(self)
        #self.ctbwidget.grid(column=1, row=4, sticky=(tk.N, tk.E, tk.W, tk.S))
        #self.canvas_tb = NavigationToolbar2TkAgg(self.canvas, self.ctbwidget)

        util.zoom_factory(self.ax)

        self.fig.tight_layout(pad=0)
        self.canvas.draw()

    ## update view with specified data
    def draw_plot(self):
        #ax.plot(self.df[self.param1], self.df[self.param2], marker="o", linewidth=0, picker=self.line_picker)
        self.clean_tooltip(True)
        self.ax.clear()
        self.ax.grid(True)
        x=self.ds.get_data("show").get_column(self.param1)
        y=self.ds.get_data("show").get_column(self.param2)
        #if self.param1 == datasource.TIME_ATTR or self.param2 == datasource.TIME_ATTR:
        #    #self.plot=self.ax.plot(x, y,picker=self.handle_pick)#, marker="o", linewidths=0,picker=self.handle_pick)
        #    self.plot = self.ax.scatter(x=x, y=y, picker=self.handle_pick)
        #else:
        self.plot=self.ax.scatter(x=x, y=y, marker="o",color="black", s=4, alpha=0.2,linewidths=0,
                                  picker=self.handle_pick)

        self.ax.set_xlabel(self.param1)
        self.ax.set_ylabel(self.param2)
        self.ax.set_xlim(x.min(), x.max(), emit=False)
        self.ax.set_ylim(y.min(), y.max(), emit=False)
        self.ax.callbacks.connect('xlim_changed', self.handle_view_change)
        self.ax.callbacks.connect('ylim_changed', self.handle_view_change)
        #self.canvas.
        self.fig.tight_layout(pad=0)

        if self.rgvar.get() is not "0" and not (self.param2 == datasource.TIME_ATTR):
            self.draw_regression()
        self.canvas.draw()

    def draw_regression(self):
        ## we need to remove rows with NaNs first
        completedf = self.df("show")
        completedf = completedf[pd.notnull(completedf[self.param1])]
        completedf = completedf[pd.notnull(completedf[self.param2])]
        if self.param1 == datasource.TIME_ATTR:
            completedf["delta_time"] = (completedf[datasource.TIME_ATTR] - completedf[datasource.TIME_ATTR].min()) / np.timedelta64(1, "m")
            X = completedf["delta_time"].to_frame()
        else:
            X = completedf[self.param1].to_frame()
        y = completedf[self.param2].to_frame()

        lr = LinearRegression()
        lr.fit(X,y)
        print(lr.coef_)
        if self.param1 == datasource.TIME_ATTR:
            self.ax.plot(completedf[datasource.TIME_ATTR], lr.predict(X), color="red")
        else:
            self.ax.plot(X, lr.predict(X), color="red")

    #################
    # helper-functions

    def df(self, name=None) -> pd.DataFrame:
        return self.ds.get_data(name).df()

    ## add line to history window
    def add_to_history(self, text):
        self.history_text += "\n" + text
        if self.history_shown:
            self.history.insert('end', "\n" + text)  # + "\n")
            self.history.see("end")

    ## remove the tooltip if shown
    def clean_tooltip(self, with_select_rect=False, emit=True):
        if self.plot_tooltip is not None:
            self.canvas.get_tk_widget().delete(self.plot_tooltip)
            self.canvas.get_tk_widget().delete(self.plot_tooltip_rect)
            self.plot_tooltip = None
        if with_select_rect and self.select_rect is not None:
            self.canvas.get_tk_widget().delete(self.select_rect)
            self.select_rect=None
            if emit:
                self.action_str = None
                self.trigger_update(self.TIMELINE_SELECTION)

    def trigger_update(self,level):
        self.unprocessed_action = max(self.unprocessed_action,level)
示例#10
0
class BlackHoleGUI:
    """GUI controling a blackhole instance."""
    def __init__(self, blackhole=None):
        """GUI controling a blackhole instance."""
        if blackhole is None:
            self.blackhole = BlackHole()
        else:
            self.blackhole = blackhole

        self.create_interface()

    def create_interface(self):
        """Create the interface."""
        root = Tk()
        frame = Frame(root)
        root.title("Black hole options")
        frame.pack()

        open_file_button = Button(frame, text="Open image", width=14, command=self.open_file_name)
        open_file_button.grid(row=0, column=0)

        L1 = Label(frame, text="radius")
        L1.grid(row=1, column=0)
        var = StringVar(root)
        var.set(self.blackhole.Rs)
        self.radius = Spinbox(frame, from_=1e-100, to=1e100, textvariable=var, bd=2, width=7)
        self.radius.grid(row=1, column=1)

        L2 = Label(frame, text="distance")
        L2.grid(row=2, column=0)
        var = StringVar(root)
        var.set(self.blackhole.D)
        self.distance = Spinbox(frame, from_=1e-100, to=1e100, textvariable=var, bd=2, width=7)
        self.distance.grid(row=2, column=1)

        compute_button = Button(frame, text="Compute", width=14, command=self.compute)
        compute_button.grid(row=1, column=2)

        self.message = Label(frame, text="", width=20)
        self.message.grid(row=1, column=3)
        self.message5 = Label(frame, text="", width=20)
        self.message5.grid(row=2, column=3)

        L3 = Label(frame, text="Image size")
        L3.grid(row=3, column=0)
        var = StringVar(root)
        var.set(self.blackhole.axe_X)
        self.size = Spinbox(frame, from_=1, to=1e100, textvariable=var, bd=2, width=7)
        self.size.grid(row=3, column=1)

        self.message2 = Label(frame, text="", width=20)
        self.message2.grid(row=3, column=3)

        save_button = Button(frame, text="Save image", width=14, command=self.img_save)
        save_button.grid(row=4, column=2)

        self.message4 = Label(frame, text="")
        self.message4.grid(row=4, column=3)

        message6 = Label(frame, text="Fix background")
        message6.grid(row=5, column=0)

        fixed_background = BooleanVar()
        C1 = Checkbutton(frame, text="", variable=fixed_background,
                         onvalue=True, offvalue=False)
        C1.grid(row=5, column=1)

        L4 = Label(frame, text="images")
        L4.grid(row=6, column=0)

        var = StringVar(root)
        var.set(10)
        self.number = Spinbox(frame, from_=1, to=1e100, textvariable=var, bd=2, width=7)
        self.number.grid(row=6, column=1)

        save_gif_button = Button(frame, text="Save animation", width=14, command=self.save_gif)
        save_gif_button.grid(row=6, column=2)

        self.message3 = Label(frame, text="")
        self.message3.grid(row=6, column=3)

        root.mainloop()

    def compute(self):
        """Call the compute method of the blackhole instance."""
        if not self.test_GUI():
            return None
        self.reset_msg()

        try:
            if float(self.distance.get()) <= 0 or float(self.radius.get()) <= 0:
                self.message["text"] = "Can't be 0 or negative"
                return None
            elif (float(self.distance.get()) == self.blackhole.D
                      and float(self.radius.get()) == self.blackhole.Rs
                      and int(self.size.get()) == self.blackhole.axe_X
                      and self.blackhole.img_matrix_x is not None):
                self.message["text"] = "same values as before"
                return None
            elif float(self.distance.get()) < float(self.radius.get()):
                self.message["text"] = "Inside black hole !"
                return None
            else:
                self.blackhole.D = float(self.distance.get())
                self.blackhole.Rs = float(self.radius.get())

        except ValueError:
            self.message["text"] = "radius, distance"
            self.message5["text"] = "& image size are floats"
            return None

        if self.blackhole.axe_X != int(self.size.get()):
            try:
                self.increase_resolution()
            except ValueError as ex:
                print(ex)
                return None

        self.message["text"] = "Computing"

        self.blackhole.compute(self.blackhole.Rs, self.blackhole.D)
        self.message["text"] = "Done !"

    def increase_resolution(self):
        """Increase the image size and correct offset and zoom to match the new
        size."""
        if not self.test_GUI():
            return None
        self.reset_msg()

        if int(self.size.get()) <= 0:
            self.message2["text"] = "Can't be 0 or negative"
            raise ValueError("Can't be 0 or negative")
        elif int(self.size.get()) == self.blackhole.axe_X:
            self.message2["text"] = "same size as before"
        else:
            # self.message2["text"] = "Computing"
            new_size_image = int(self.size.get())
            self.blackhole.offset_X += self.blackhole.offset_X2
            self.blackhole.offset_X2 = 0
            res_fact = new_size_image/self.blackhole.axe_X

            self.blackhole.axe_X = new_size_image

            self.blackhole.offset_X *= res_fact
            self.blackhole.zoom *= res_fact

            try:
                self.blackhole.img_resize(self.blackhole.axe_X)
                self.blackhole.img_debut = img_offset_X(
                    self.blackhole.img_debut, self.blackhole.offset_X)
            except ValueError as ex:
                print("error when resizing image")
                raise ValueError(ex)

    def img_save(self):
        """Save the image img2 with the parameters values. GUI version."""
        if not self.test_GUI():
            return None
        self.reset_msg()

        file_name, extension = return_folder_file_extension(self.blackhole.img_name)[1:]
        image_name_save = "%s_D=%s_Rs=%s_size=%s_offset=%i%s" % (file_name, self.blackhole.D, self.blackhole.Rs, self.blackhole.axe_X, self.blackhole.offset_X+self.blackhole.offset_X2, extension)

        if self.blackhole.img2 is not None:
            self.blackhole.img2.save(image_name_save)
            print("Saved "+image_name_save)
            self.message4["text"] = "Saved "+image_name_save
        else:
            self.message4["text"] = "No image to save"

    def save_gif(self):
        """Call the gif method if the blackhole instance."""
        if not self.test_GUI():
            return None
        self.reset_msg()

        file_name, extension = return_folder_file_extension(self.blackhole.img_name)[1:]

        if self.blackhole.img2 is not None:
            self.message3["text"] = "Computing"
        else:
            self.message3["text"] = "No image to save"
            return None
        try:
            if int(self.number.get()) <= 0:
                print("Can't be 0 or negative")
                self.message3["text"] = "Can't be 0 or negative"
            else:
                self.blackhole.gif(int(self.number.get()))
                image_name_save = "%s_D=%s_Rs=%s_size=%s_offset=%s%s" % (file_name, self.blackhole.D, self.blackhole.Rs, self.blackhole.axe_X, "*", extension)
                self.message3["text"] = "Saved "+image_name_save
        except Exception:
            print("need integer")
            self.message3["text"] = "need integer"

    def open_file_name(self):
        """Open a new image and aply the previous parameters.
        Compute a new black hole if parameters were changed.
        Source: https://gist.github.com/Yagisanatode/0d1baad4e3a871587ab1"""
        if not self.test_GUI():
            return None
        self.reset_msg()

        img_name = askopenfilename(
            # initialdir="",
            filetypes=[("Image File", ".png .jpg")],
            title="Image file")

        if img_name:
            size = int(self.size.get())
            self.blackhole.open(img_name, size=size)
            if self.blackhole.img_matrix_x is not None:
                if self.blackhole.axe_X != self.blackhole.img_matrix_x.shape[1]:
                    self.blackhole.compute(self.blackhole.Rs, self.blackhole.D)

                self.blackhole.offset_X += self.blackhole.offset_X2
                self.blackhole.offset_X2 = 0
                self.blackhole.img_debut = img_offset_X(
                    self.blackhole.img_debut, self.blackhole.offset_X)
                self.blackhole.img2 = self.blackhole.img_pixels(self.blackhole.img_debut)

                self.blackhole.plot()

    def reset_msg(self):
        """Reset all GUI messages."""
        if not self.test_GUI():
            return None
        self.message5["text"] = ""
        self.message4["text"] = ""
        self.message3["text"] = ""
        self.message2["text"] = ""
        self.message["text"] = ""

    def test_GUI(self):
        """Return True if the GUI is active and False otherwise."""
        try:
            temp = self.message["text"]
            self.message["text"] = ""
            self.message["text"] = temp
            return True
        except Exception:
            print("The GUI is not openned, function ignored")
            return False
示例#11
0
class OOP():
    def __init__(self): 
        # Create instance
        self.win = tk.Tk()   
        
        # Add a title       
        self.win.title("Python GUI")      
        self.createWidgets()
    
    # Button callback
    def clickMe(self):
        self.action.configure(text='Hello ' + self.name.get())
    
    # Button callback Clear Text   
    def clearScrol(self):
        self.scr.delete('1.0', tk.END)    
    
    # Spinbox callback 
    def _spin(self):
        value = self.spin.get()
        print(value)
        self.scr.insert(tk.INSERT, value + '\n')
        
    # Checkbox callback  
    def checkCallback(self, *ignoredArgs):
        # only enable one checkbutton
        if self.chVarUn.get(): self.check3.configure(state='disabled')
        else:             self.check3.configure(state='normal')
        if self.chVarEn.get(): self.check2.configure(state='disabled')
        else:             self.check2.configure(state='normal') 
        
    # Radiobutton callback function
    def radCall(self):
        radSel=self.radVar.get()
        if   radSel == 0: self.monty2.configure(text='Blue')
        elif radSel == 1: self.monty2.configure(text='Gold')
        elif radSel == 2: self.monty2.configure(text='Red')        

    # Exit GUI cleanly
    def _quit(self):
        self.win.quit()
        self.win.destroy()
        exit() 
    
    def usingGlobal(self):
        GLOBAL_CONST = 777
        print(GLOBAL_CONST)
            
    #####################################################################################    
    def createWidgets(self):    
        # Tab Control introduced here --------------------------------------
        tabControl = ttk.Notebook(self.win)     # Create Tab Control
        
        tab1 = ttk.Frame(tabControl)            # Create a tab 
        tabControl.add(tab1, text='Tab 1')      # Add the tab
        
        tab2 = ttk.Frame(tabControl)            # Add a second tab
        tabControl.add(tab2, text='Tab 2')      # Make second tab visible
        
        tabControl.pack(expand=1, fill="both")  # Pack to make visible
        # ~ Tab Control introduced here -----------------------------------------
        
        # We are creating a container frame to hold all other widgets
        self.monty = ttk.LabelFrame(tab1, text=' Mighty Python ')
        self.monty.grid(column=0, row=0, padx=8, pady=4)        
        
        # Changing our Label
        ttk.Label(self.monty, text="Enter a name:").grid(column=0, row=0, sticky='W')
        
        # Adding a Textbox Entry widget
        self.name = tk.StringVar()
        nameEntered = ttk.Entry(self.monty, width=12, textvariable=self.name)
        nameEntered.grid(column=0, row=1, sticky='W')
        
        # Adding a Button
        self.action = ttk.Button(self.monty, text="Click Me!", command=self.clickMe)   
        self.action.grid(column=2, row=1)
        
        ttk.Label(self.monty, text="Choose a number:").grid(column=1, row=0)
        number = tk.StringVar()
        numberChosen = ttk.Combobox(self.monty, width=12, textvariable=number)
        numberChosen['values'] = (1, 2, 4, 42, 100)
        numberChosen.grid(column=1, row=1)
        numberChosen.current(0)
             
        # Adding a Spinbox widget using a set of values
        self.spin = Spinbox(self.monty, values=(1, 2, 4, 42, 100), width=5, bd=8, command=self._spin) 
        self.spin.grid(column=0, row=2)
                  
        # Using a scrolled Text control    
        scrolW  = 30; scrolH  =  3
        self.scr = scrolledtext.ScrolledText(self.monty, width=scrolW, height=scrolH, wrap=tk.WORD)
        self.scr.grid(column=0, row=3, sticky='WE', columnspan=3)
        
        #-------------------------------------------------------------------------    
        # Adding another Button
        self.action = ttk.Button(self.monty, text="Clear Text", command=self.clearScrol)   
        self.action.grid(column=2, row=2)
        
                               
        # Tab Control 2 refactoring  -----------------------------------------
        # We are creating a container frame to hold all other widgets -- Tab2
        self.monty2 = ttk.LabelFrame(tab2, text=' Holy Grail ')
        self.monty2.grid(column=0, row=0, padx=8, pady=4)
        # Creating three checkbuttons
        chVarDis = tk.IntVar()
        check1 = tk.Checkbutton(self.monty2, text="Disabled", variable=chVarDis, state='disabled')
        check1.select()
        check1.grid(column=0, row=0, sticky=tk.W)                 
        
        self.chVarUn = tk.IntVar()
        self.check2 = tk.Checkbutton(self.monty2, text="UnChecked", variable=self.chVarUn)
        self.check2.deselect()
        self.check2.grid(column=1, row=0, sticky=tk.W )                  
         
        self.chVarEn = tk.IntVar()
        self.check3 = tk.Checkbutton(self.monty2, text="Toggle", variable=self.chVarEn)
        self.check3.deselect()
        self.check3.grid(column=2, row=0, sticky=tk.W)                 
    
        # trace the state of the two checkbuttons
        self.chVarUn.trace('w', lambda unused0, unused1, unused2 : self.checkCallback())    
        self.chVarEn.trace('w', lambda unused0, unused1, unused2 : self.checkCallback())   
        # ~ Tab Control 2 refactoring  -----------------------------------------
        
        # Radiobutton list
        colors = ["Blue", "Gold", "Red"]
        
        self.radVar = tk.IntVar()
        
        # Selecting a non-existing index value for radVar
        self.radVar.set(99)    
        
        # Creating all three Radiobutton widgets within one loop
        for col in range(3):
            curRad = 'rad' + str(col)  
            curRad = tk.Radiobutton(self.monty2, text=colors[col], variable=self.radVar, value=col, command=self.radCall)
            curRad.grid(column=col, row=6, sticky=tk.W, columnspan=3)
            # And now adding tooltips
            tt.createToolTip(curRad, 'This is a Radiobutton control.')
            
        # Create a container to hold labels
        labelsFrame = ttk.LabelFrame(self.monty2, text=' Labels in a Frame ')
        labelsFrame.grid(column=0, row=7)
         
        # Place labels into the container element - vertically
        ttk.Label(labelsFrame, text="Label1").grid(column=0, row=0)
        ttk.Label(labelsFrame, text="Label2").grid(column=0, row=1)
        
        # Add some space around each label
        for child in labelsFrame.winfo_children(): 
            child.grid_configure(padx=8)
        
        
        # Creating a Menu Bar
        menuBar = Menu(tab1)
        self.win.config(menu=menuBar)
        
        # Add menu items
        fileMenu = Menu(menuBar, tearoff=0)
        fileMenu.add_command(label="New")
        fileMenu.add_separator()
        fileMenu.add_command(label="Exit", command=self._quit)
        menuBar.add_cascade(label="File", menu=fileMenu)
        
        # Add another Menu to the Menu Bar and an item
        helpMenu = Menu(menuBar, tearoff=0)
        helpMenu.add_command(label="About")
        menuBar.add_cascade(label="Help", menu=helpMenu)
        
        # Change the main windows icon
        self.win.iconbitmap('pyc.ico')
        
        # Using tkinter Variable Classes
        strData = tk.StringVar()
        strData.set('Hello StringVar')
        print(strData.get())
        
        # Default tkinter Variable Classes
        intData = tk.IntVar()
        print(intData.get())
        print(tk.DoubleVar())
        print(tk.BooleanVar())
        
        # It is not necessary to create a tk.StringVar() 
        strData = tk.StringVar()
        strData = self.spin.get()
        print("Hello " + strData)
        
        # Printing the Global works
        print(GLOBAL_CONST)
         
        # call method
        self.usingGlobal()
        
        # Place cursor into name Entry
        nameEntered.focus()     
        
        # Add a Tooltip to the Spinbox
        tt.createToolTip(self.spin, 'This is a Spin control.')         
        
        # Add Tooltips to more widgets
        tt.createToolTip(nameEntered, 'This is an Entry control.')  
        tt.createToolTip(self.action, 'This is a Button control.')                      
        tt.createToolTip(self.scr,    'This is a ScrolledText control.')
示例#12
0
class Interface:
    """ GUI class """
    def __init__(self, master):
        # colour swatches
        self.gray1 = "#f6f6f6"
        self.gray2 = "#eaeaea"
        self.gray3 = "#d9d9d9"
        # key parameters
        self.running = False
        self.sect_width = 360
        self.rb_choice = StringVar()
        self.dob1_val = StringVar()
        self.dob2_val = StringVar()
        self.df_records = StringVar()

        master.geometry("800x600+200+200")
        master.title("Red Snapper")
        master.resizable(False, False)
        master.configure(background=self.gray1)

        # LEFT SECTION LAYER
        # --------------------------------------------------------------------
        self.sect_left = Frame(master)
        self.sect_left.place(x=15, y=15, width=self.sect_width, height=570)
        self.sect_left.config(relief=RIDGE)
        self.sect_left.config(background=self.gray2)

        # RIGHT SECTION LAYER
        # --------------------------------------------------------------------
        self.sect_right = Frame(master)
        self.sect_right.place(x=-15, y=200, width=self.sect_width, height=385)
        self.sect_right.place(relx=1.0, anchor="ne")
        self.sect_right.config(relief=RIDGE)
        self.sect_right.config(background=self.gray2)

        # Sliders layer
        self.layer_sliders = Frame(self.sect_left)
        self.layer_sliders.place(y=0, width=self.sect_width, height=320)
        self.layer_sliders.config(**self.layer_props(self.gray2))
        self.lab_sliders = Label(self.layer_sliders)
        self.lab_sliders.config(**self.title_props("Parameters"))
        self.lab_sliders.pack()

        # DOB layer
        self.layer_dob = Frame(self.sect_left)
        self.layer_dob.place(y=320, width=self.sect_width, height=80)
        self.layer_dob.config(**self.layer_props(self.gray2))
        self.lab_dob = Label(self.layer_dob)
        self.lab_dob.config(**self.title_props("Birthdays range"))
        self.lab_dob.pack()

        # Export layer
        self.layer_export = Frame(self.sect_left)
        self.layer_export.place(y=400, width=self.sect_width, height=80)
        self.layer_export.config(**self.layer_props(self.gray2))
        self.lab_export = Label(self.layer_export)
        self.lab_export.config(**self.title_props("Export format"))
        self.lab_export.pack()

        # Run layer
        self.layer_run = Frame(self.sect_left)
        self.layer_run.place(y=480, width=self.sect_width, height=100)
        self.layer_run.config(**self.layer_props(self.gray2))
        self.lab_run = Label(self.layer_run)
        self.lab_run.config(**self.title_props("Run"))
        self.lab_run.pack()

        # About layer
        self.layer_about = Frame(self.sect_right)
        self.layer_about.place(width=self.sect_width, height=385)
        self.layer_about.config(**self.layer_props(self.gray2))
        self.lab_about = Label(self.layer_about)
        self.lab_about.config(**self.title_props("About Red Snapper"))
        self.lab_about.pack()

        # sliders
        self.sli_wom = Scale(self.layer_sliders, from_=0, to=100)
        self.sli_wom.config(**self.sli_props())
        self.sli_wom.config(label="Percentage of women in dataset.")
        self.sli_wom.pack(padx=20, pady=10)
        self.sli_wom.set(50)

        self.sli_nam = Scale(self.layer_sliders, from_=0, to=100)
        self.sli_nam.config(**self.sli_props())
        self.sli_nam.config(label="Percentage of people with double name")
        self.sli_nam.pack(padx=20, pady=0)
        self.sli_nam.set(25)

        self.sli_sur = Scale(self.layer_sliders, from_=0, to=100)
        self.sli_sur.config(**self.sli_props())
        self.sli_sur.config(label="Percentage of people with double surname")
        self.sli_sur.pack(padx=20, pady=10)
        self.sli_sur.set(15)

        # DOB Layer - From Date
        self.dob1_val.set("1945")
        self.lab_dob1 = Label(self.layer_dob, text="From date")
        self.lab_dob1.config(**self.label_props())
        self.lab_dob1.pack(side=LEFT, padx=5)
        self.box_dob1 = Spinbox(self.layer_dob)
        self.box_dob1.config(from_=1945, to=1996, textvariable=self.dob1_val)
        self.box_dob1.config(**self.date_props())
        self.box_dob1.pack(side=LEFT)

        # DOB Layer - To Date
        self.dob2_val.set("1997")
        self.lab_dob2 = Label(self.layer_dob, text="To date")
        self.lab_dob2.config(**self.label_props())
        self.lab_dob2.pack(side=LEFT, padx=17)
        self.box_dob2 = Spinbox(self.layer_dob)
        self.box_dob2.config(from_=1946, to=1997, textvariable=self.dob2_val)
        self.box_dob2.config(**self.date_props())
        self.box_dob2.pack(side=LEFT)

        # Export layer - JSON / CSV radio buttons
        self.rb_choice.set("CSV")
        self.rb1 = Radiobutton(self.layer_export,
                               text="Save as CSV",
                               variable=self.rb_choice,
                               value="CSV")
        self.rb1.config(**self.radio_props())
        self.rb1.place(y=35, x=50)
        self.rb2 = Radiobutton(self.layer_export,
                               text="Save as JSON",
                               variable=self.rb_choice,
                               value="JSON")
        self.rb2.config(**self.radio_props())
        self.rb2.place(y=35, x=200)

        # Run layer - no of records spinbox
        self.df_records.set("100")
        self.box_gen = Spinbox(self.layer_run)
        self.box_gen.config(from_=1, to=999999, textvariable=self.df_records)
        self.box_gen.config(increment=1000, width=19)
        self.box_gen.place(x=70, y=53)
        self.lab_gen = Label(self.layer_run, text="Number of records")
        self.lab_gen.config(**self.label_props())
        self.lab_gen.place(x=70, y=30)

        # Run layer - generate button
        self.btn_run = ttk.Button(self.layer_run)
        self.btn_run.place(x=225, y=35, height=40)
        self.btn_run_reset()

        # header & logo section
        self.sect_logo = Frame(master)
        self.sect_logo.place(x=-15, y=30, width=350, height=120)
        self.sect_logo.place(relx=1.0, anchor="ne")
        self.logo = PhotoImage(file="./redsnapper/interface/logo.png")
        self.lab_logo = Label(self.sect_logo, image=self.logo)
        self.lab_logo.config(background=self.gray1)
        self.lab_logo.pack()

        # About
        box_about = Text(self.layer_about)
        box_about.config(**self.text_props())
        box_about.pack(pady=10, padx=10)
        txt = """This program allows generating thousands of rows filled with pseudo-random data. """ \
              + """\nThe generated records (like name,  """ \
              + """ surname, date of birth, e-mail address) can be used to provide sample data to:
        - test query performance of your database 
        - practice data operations with BI tools.""" \
              + """ \nThe application uses 4 processes to generate data simultaneously. """ \
              + """ It takes about 25 seconds to create 1 million rows of data.\n"""

        box_about.insert(END, txt)

    # styling wrapped into functions for reusability
    def sli_props(self):
        """
        bundle popular attributes of TK control so they can be reused
        :return: dict of bundled props
        """
        return {
            "length": 300,
            "orient": HORIZONTAL,
            "sliderrelief": FLAT,
            "showvalue": 1,
            "resolution": 1,
            "sliderlength": 25,
            "tickinterval": 100,
            "font": ("Arial", 8),
            "activebackground": "#333333",
            "background": "#666666",
            "troughcolor": "#d0d4d2",
            "foreground": "#eeeeee",
            "highlightthickness": 8,
            "highlightcolor": "#ffffff",
            "highlightbackground": self.gray3,
            "borderwidth": 1
        }

    @staticmethod
    def layer_props(bgcolor):
        """
        bundle popular attributes of TK control so they can be reused
        :return: dict of bundled props
        """
        return {"relief": RIDGE, "background": bgcolor}

    def title_props(self, title):
        """
        bundle popular attributes of TK control so they can be reused
        :return: dict of bundled props
        """
        return {
            "text": title,
            "background": self.gray3,
            "width": self.sect_width,
            "borderwidth": 1,
            "relief": RIDGE
        }

    def radio_props(self):
        """
        bundle popular attributes of TK control so they can be reused
        :return: dict of bundled props
        """
        return {
            "background": self.gray2,
            "activebackground": self.gray2,
        }

    def date_props(self):
        """
        bundle popular attributes of TK control so they can be reused
        :return: dict of bundled props
        """
        return {
            "width": 8,
            "increment": 1,
            "font": ("Arial", 8),
            "background": "#666666",
            "buttonbackground": "#666666",
            "foreground": "#eeeeee",
            "highlightthickness": 8,
            "highlightcolor": "#ffffff",
            "highlightbackground": self.gray2,
            "borderwidth": 1
        }

    def label_props(self):
        """
        bundle popular attributes of TK control so they can be reused
        :return: dict of bundled props
        """
        return {
            "background": self.gray2,
            "highlightcolor": "#ffffff",
            "highlightbackground": self.gray2,
            "borderwidth": 1
        }

    def text_props(self):
        """
        bundle popular attributes of TK control so they can be reused
        :return: dict of bundled props
        """
        return {
            "font": ("Arial", 11),
            "background": self.gray1,
            "foreground": "#212121",
            "highlightthickness": 8,
            "highlightbackground": self.gray1,
            "highlightcolor": self.gray1,
            "borderwidth": 0,
            "wrap": "word",
            "spacing1": 11,
            "spacing2": 7,
        }

    def produce_props(self):
        """
        produce dict of key GUI parameters selected by user
        :return: no return parameters
        """
        rows = int(self.box_gen.get())
        props = {
            "pgender": self.sli_wom.get(),
            "pdname": self.sli_nam.get(),
            "pdsurname": self.sli_sur.get(),
            "dob1": self.box_dob1.get(),
            "dob2": self.box_dob2.get(),
        }
        dataset = Dataset().run_workload(rows, **props)
        exp_format = self.rb_choice.get()
        if exp_format == "CSV":
            Export().to_csv(dataset)
        else:
            Export().to_json(dataset)
        self.btn_run_reset()
        return

    def btn_run_reset(self):
        """
        abort button (when generating)
        :return: no return parameters
        """
        self.running = False
        self.btn_run.config(text="Generate", command=self.btn_run_start)
        return

    def btn_run_start(self):
        """
        handle the run button
        :return: no return parameters
        """
        self.running = True
        newthread = threading.Thread(target=self.produce_props)
        newthread.start()
        self.btn_run.config(text="Abort", command=self.btn_run_reset)
        return
示例#13
0
class OOP():
    def __init__(self, language='en'):
        # Create instance
        self.win = tk.Tk()

        self.i18n = I18N(language)
        #         self.i18n = I18N(language)

        # Add a title
        self.win.title(self.i18n.title)

        # Callback methods now in different module
        self.callBacks = Callbacks(self)

        # Disable resizing the window
        self.win.resizable(0, 0)

        # Create a Queue
        self.guiQueue = Queue()

        self.createWidgets()

        # populate Tab 2 Entries
        self.callBacks.defaultFileEntries()

        # create MySQL instance
        self.mySQL = MySQL()

        # create Logger instance
        fullPath = path.realpath(__file__)
        self.log = Logger(fullPath)

        # create Log Level instance
        self.level = LogLevel()

    #####################################################################################
    def createWidgets(self):
        # Tab Control introduced here --------------------------------------
        tabControl = ttk.Notebook(self.win)  # Create Tab Control

        tab1 = ttk.Frame(tabControl)  # Create a tab
        #         tabControl.add(tab1, text='MySQL')    # Add the tab -- COMMENTED OUT FOR CH08

        tab2 = ttk.Frame(tabControl)  # Add a second tab
        tabControl.add(tab2, text='Widgets')  # Make second tab visible

        tabControl.pack(expand=1, fill="both")  # Pack to make visible
        # ~ Tab Control introduced here -----------------------------------------

        # We are creating a container frame to hold all other widgets
        self.mySQL = ttk.LabelFrame(tab1, text=' Python Database ')
        self.mySQL.grid(column=0, row=0, padx=8, pady=4)

        # Creating a Label
        ttk.Label(self.mySQL, text="Book Title:").grid(column=0,
                                                       row=0,
                                                       sticky='W')

        # Adding a Textbox Entry widget
        book = tk.StringVar()
        self.bookTitle = ttk.Entry(self.mySQL, width=34, textvariable=book)
        self.bookTitle.grid(column=0, row=1, sticky='W')

        # Adding a Textbox Entry widget
        book1 = tk.StringVar()
        self.bookTitle1 = ttk.Entry(self.mySQL, width=34, textvariable=book1)
        self.bookTitle1.grid(column=0, row=2, sticky='W')

        # Adding a Textbox Entry widget
        book2 = tk.StringVar()
        self.bookTitle2 = ttk.Entry(self.mySQL, width=34, textvariable=book2)
        self.bookTitle2.grid(column=0, row=3, sticky='W')

        # Creating a Label
        ttk.Label(self.mySQL, text="Page:").grid(column=1, row=0, sticky='W')

        # Adding a Textbox Entry widget
        page = tk.StringVar()
        self.pageNumber = ttk.Entry(self.mySQL, width=6, textvariable=page)
        self.pageNumber.grid(column=1, row=1, sticky='W')

        # Adding a Textbox Entry widget
        page = tk.StringVar()
        self.pageNumber1 = ttk.Entry(self.mySQL, width=6, textvariable=page)
        self.pageNumber1.grid(column=1, row=2, sticky='W')

        # Adding a Textbox Entry widget
        page = tk.StringVar()
        self.pageNumber2 = ttk.Entry(self.mySQL, width=6, textvariable=page)
        self.pageNumber2.grid(column=1, row=3, sticky='W')

        # Adding a Button
        self.action = ttk.Button(self.mySQL,
                                 text="Insert Quote",
                                 command=self.callBacks.insertQuote)
        self.action.grid(column=2, row=1)

        # Adding a Button
        self.action1 = ttk.Button(self.mySQL,
                                  text="Get Quotes",
                                  command=self.callBacks.getQuote)
        self.action1.grid(column=2, row=2)

        # Adding a Button
        self.action2 = ttk.Button(self.mySQL,
                                  text="Mody Quote",
                                  command=self.callBacks.modifyQuote)
        self.action2.grid(column=2, row=3)

        # Add some space around each widget
        for child in self.mySQL.winfo_children():
            child.grid_configure(padx=2, pady=4)

        quoteFrame = ttk.LabelFrame(tab1, text=' Book Quotation ')
        quoteFrame.grid(column=0, row=1, padx=8, pady=4)

        # Using a scrolled Text control
        quoteW = 40
        quoteH = 6
        self.quote = scrolledtext.ScrolledText(quoteFrame,
                                               width=quoteW,
                                               height=quoteH,
                                               wrap=tk.WORD)
        self.quote.grid(column=0, row=8, sticky='WE', columnspan=3)

        # Add some space around each widget
        for child in quoteFrame.winfo_children():
            child.grid_configure(padx=2, pady=4)

        #======================================================================================================
        # Tab Control 2
        #======================================================================================================
        # We are creating a container frame to hold all other widgets -- Tab2
        self.widgetFrame = ttk.LabelFrame(tab2, text=self.i18n.WIDGET_LABEL)
        self.widgetFrame.grid(column=0, row=0, padx=8, pady=4)

        # Creating three checkbuttons
        self.chVarDis = tk.IntVar()
        self.check1 = tk.Checkbutton(self.widgetFrame,
                                     text=self.i18n.disabled,
                                     variable=self.chVarDis,
                                     state='disabled')
        self.check1.select()
        self.check1.grid(column=0, row=0, sticky=tk.W)

        self.chVarUn = tk.IntVar()
        self.check2 = tk.Checkbutton(self.widgetFrame,
                                     text=self.i18n.unChecked,
                                     variable=self.chVarUn)
        self.check2.deselect()
        self.check2.grid(column=1, row=0, sticky=tk.W)

        self.chVarEn = tk.IntVar()
        self.check3 = tk.Checkbutton(self.widgetFrame,
                                     text=self.i18n.toggle,
                                     variable=self.chVarEn)
        self.check3.deselect()
        self.check3.grid(column=2, row=0, sticky=tk.W)

        # trace the state of the two checkbuttons
        self.chVarUn.trace(
            'w', lambda unused0, unused1, unused2: self.checkCallback())
        self.chVarEn.trace(
            'w', lambda unused0, unused1, unused2: self.checkCallback())

        # Radiobutton list
        colors = self.i18n.colors

        self.radVar = tk.IntVar()

        # Selecting a non-existing index value for radVar
        self.radVar.set(99)

        # Creating all three Radiobutton widgets within one loop
        for col in range(3):
            self.curRad = 'rad' + str(col)
            self.curRad = tk.Radiobutton(self.widgetFrame,
                                         text=colors[col],
                                         variable=self.radVar,
                                         value=col,
                                         command=self.callBacks.radCall)
            self.curRad.grid(column=col, row=6, sticky=tk.W, columnspan=3)
            # And now adding tooltips
            tt.createToolTip(self.curRad, 'This is a Radiobutton control.')

        # Create a container to hold labels
        labelsFrame = ttk.LabelFrame(self.widgetFrame,
                                     text=self.i18n.labelsFrame)
        labelsFrame.grid(column=0, row=7, pady=6)

        # Place labels into the container element - vertically
        ttk.Label(labelsFrame, text=self.i18n.chooseNumber).grid(column=0,
                                                                 row=0)
        self.lbl2 = tk.StringVar()
        self.lbl2.set(self.i18n.label2)
        ttk.Label(labelsFrame, textvariable=self.lbl2).grid(column=0, row=1)

        # Add some space around each label
        for child in labelsFrame.winfo_children():
            child.grid_configure(padx=6, pady=1)

        number = tk.StringVar()
        self.combo = ttk.Combobox(self.widgetFrame,
                                  width=12,
                                  textvariable=number)
        self.combo['values'] = (1, 2, 4, 42, 100)
        self.combo.grid(column=1, row=7, sticky=tk.W)
        self.combo.current(0)
        self.combo.bind('<<ComboboxSelected>>', self.callBacks._combo)

        # Adding a Spinbox widget using a set of values
        self.spin = Spinbox(self.widgetFrame,
                            values=(1, 2, 4, 42, 100),
                            width=5,
                            bd=8,
                            command=self.callBacks._spin)
        self.spin.grid(column=2, row=7, sticky='W,', padx=6, pady=1)

        # Using a scrolled Text control
        scrolW = 40
        scrolH = 1
        self.scr = scrolledtext.ScrolledText(self.widgetFrame,
                                             width=scrolW,
                                             height=scrolH,
                                             wrap=tk.WORD)
        self.scr.grid(column=0, row=8, sticky='WE', columnspan=3)

        # Adding a TZ Button
        self.allTZs = ttk.Button(self.widgetFrame,
                                 text=self.i18n.timeZones,
                                 command=self.callBacks.allTimeZones)
        self.allTZs.grid(column=0, row=9, sticky='WE')

        # Adding local TZ Button
        self.localTZ = ttk.Button(self.widgetFrame,
                                  text=self.i18n.localZone,
                                  command=self.callBacks.localZone)
        self.localTZ.grid(column=1, row=9, sticky='WE')

        # Adding getTime TZ Button
        self.dt = ttk.Button(self.widgetFrame,
                             text=self.i18n.getTime,
                             command=self.callBacks.getDateTime)
        self.dt.grid(column=2, row=9, sticky='WE')

        # Create Manage Files Frame ------------------------------------------------
        mngFilesFrame = ttk.LabelFrame(tab2, text=self.i18n.mgrFiles)
        mngFilesFrame.grid(column=0, row=1, sticky='WE', padx=10, pady=5)

        # Button Callback
        def getFileName():
            print('hello from getFileName')
            fDir = path.dirname(__file__)
            fName = fd.askopenfilename(parent=self.win, initialdir=fDir)
            print(fName)
            self.fileEntry.config(state='enabled')
            self.fileEntry.delete(0, tk.END)
            self.fileEntry.insert(0, fName)

            if len(fName) > self.entryLen:
                self.fileEntry.config(width=len(fName) + 3)

        # Add Widgets to Manage Files Frame
        lb = ttk.Button(mngFilesFrame,
                        text=self.i18n.browseTo,
                        command=getFileName)
        lb.grid(column=0, row=0, sticky=tk.W)

        #-----------------------------------------------------
        file = tk.StringVar()
        self.entryLen = scrolW - 4
        self.fileEntry = ttk.Entry(mngFilesFrame,
                                   width=self.entryLen,
                                   textvariable=file)
        self.fileEntry.grid(column=1, row=0, sticky=tk.W)

        #-----------------------------------------------------
        logDir = tk.StringVar()
        self.netwEntry = ttk.Entry(mngFilesFrame,
                                   width=self.entryLen,
                                   textvariable=logDir)
        self.netwEntry.grid(column=1, row=1, sticky=tk.W)

        def copyFile():
            import shutil
            src = self.fileEntry.get()
            file = src.split('/')[-1]
            dst = self.netwEntry.get() + '\\' + file
            try:
                shutil.copy(src, dst)
                mBox.showinfo('Copy File to Network', 'Succes: File copied.')
            except FileNotFoundError as err:
                mBox.showerror('Copy File to Network',
                               '*** Failed to copy file! ***\n\n' + str(err))
            except Exception as ex:
                mBox.showerror('Copy File to Network',
                               '*** Failed to copy file! ***\n\n' + str(ex))

        cb = ttk.Button(mngFilesFrame, text=self.i18n.copyTo, command=copyFile)
        cb.grid(column=0, row=1, sticky=tk.E)

        # Add some space around each label
        for child in mngFilesFrame.winfo_children():
            child.grid_configure(padx=6, pady=6)

        # Creating a Menu Bar ==========================================================
        menuBar = Menu(tab1)
        self.win.config(menu=menuBar)

        # Add menu items
        fileMenu = Menu(menuBar, tearoff=0)
        fileMenu.add_command(label=self.i18n.new)
        fileMenu.add_separator()
        fileMenu.add_command(label=self.i18n.exit,
                             command=self.callBacks._quit)
        menuBar.add_cascade(label=self.i18n.file, menu=fileMenu)

        # Add another Menu to the Menu Bar and an item
        helpMenu = Menu(menuBar, tearoff=0)
        helpMenu.add_command(label=self.i18n.about)
        menuBar.add_cascade(label=self.i18n.help, menu=helpMenu)

        # Change the main windows icon
        self.win.iconbitmap(r'C:\Python34\DLLs\pyc.ico')

        # Using tkinter Variable Classes
        strData = tk.StringVar()
        strData.set('Hello StringVar')

        # It is not necessary to create a tk.StringVar()
        strData = tk.StringVar()
        strData = self.spin.get()

        # Place cursor into name Entry
        self.bookTitle.focus()

        # Add a Tooltip to the Spinbox
        tt.createToolTip(self.spin, 'This is a Spin control.')

        # Add Tooltips to more widgets
        tt.createToolTip(self.bookTitle, 'This is an Entry control.')
        tt.createToolTip(self.action, 'This is a Button control.')
        tt.createToolTip(self.scr, 'This is a ScrolledText control.')
示例#14
0
class OOP():
    def __init__(self):         # Initializer method
        # Create instance
        self.win = tk.Tk()   
        
        tt.create_ToolTip(self.win, 'Hello GUI')
        
        # Add a title       
        self.win.title("Python GUI")      
        self.create_widgets()
        self.defaultFileEntries()
        self.guiQueue = Queue()

    def defaultFileEntries(self):
        self.fileEntry.delete(0, tk.END)
        self.fileEntry.insert(0, fDir)
        if len(fDir) > self.entryLen:
            self.fileEntry.config(width=len(fDir) + 3)
            # Readonly would make it impossible to change to the actual file we
            # want to copy
 #           self.fileEntry.config(state='readonly')

        self.netwEntry.delete(0, tk.END)
        self.netwEntry.insert(0, netDir)
        if len(netDir) > self.entryLen:
            self.netwEntry.config(width=len(netDir) + 3)

    def useQueues(self):
        self.guiQueue = Queue()
        for idx in range(10):
            self.guiQueue.put('Message from a queue' + str(idx))

        while True:
            print(self.guiQueue.get())

    def methodInAThread(self, numOfLoops=10):
        for idx in range(numOfLoops):
            sleep(1)
            self.scr.insert(tk.INSERT, str(idx) + '\n')
        sleep(1)
        print('methodInAThread():', self.runT.isAlive())

        # textBoxes are the Consumers of Queue data
        writeT = Thread(target=self.useQueues, daemon=True)
        writeT.start()


    # Running methods in Threads
    def createThread(self, num):
        self.runT = Thread(target=self.methodInAThread, args=[num])
        self.runT.setDaemon(True)
        self.runT.start()
        print(self.runT)
        print('createThread():', self.runT.isAlive())

        # textBoxes are the consumers of queue data
        writeT = Thread(target=self.useQueues, daemon=True)
        writeT.start()

    # Create Queue instance
    def useQueues(self):
        print(self.guiQueue)
        while True:
            print(self.guiQueue.get())

    # Modified Button Click Function
    def click_me(self): 
        # Passing in the current class instance (self)
        print(self)
        bq.writeToScrol(self)

    # Spinbox callback 
    def _spin(self):
        value = self.spin.get()
        print(value)
        self.scr.insert(tk.INSERT, value + '\n')
        
    # GUI Callback  
    def checkCallback(self, *ignored_args):
        # only enable one checkbutton
        if self.chVarUn.get(): self.check3.configure(state='disabled')
        else:                  self.check3.configure(state='normal')
        if self.chVarEn.get(): self.check2.configure(state='disabled')
        else:                  self.check2.configure(state='normal') 
        
    # Radiobutton Callback
    def radCall(self):
        radSel = self.radVar.get()
        if   radSel == 0: self.mighty2.configure(text='Blue')
        elif radSel == 1: self.mighty2.configure(text='Gold')
        elif radSel == 2: self.mighty2.configure(text='Red')          
        
    # update progressbar in callback loop
    def run_progressbar(self):
        self.progress_bar["maximum"] = 100
        for i in range(101):
            sleep(0.05)
            self.progress_bar["value"] = i   # increment progressbar
            self.progress_bar.update()       # have to call update() in loop
        self.progress_bar["value"] = 0       # reset/clear progressbar  
    
    def start_progressbar(self):
        self.progress_bar.start()
        
    def stop_progressbar(self):
        self.progress_bar.stop()
     
    def progressbar_stop_after(self, wait_ms=1000):    
        self.win.after(wait_ms, self.progress_bar.stop)        

    def usingGlobal(self):
        global GLOBAL_CONST
        print(GLOBAL_CONST)
        GLOBAL_CONST = 777
        print(GLOBAL_CONST)
                    
    # Exit GUI cleanly
    def _quit(self):
        self.win.quit()
        self.win.destroy()
        exit() 
                  
    #####################################################################################       
    def create_widgets(self):    
        tabControl = ttk.Notebook(self.win)          # Create Tab Control
        
        tab1 = ttk.Frame(tabControl)            # Create a tab 
        tabControl.add(tab1, text='Tab 1')      # Add the tab
        tab2 = ttk.Frame(tabControl)            # Add a second tab
        tabControl.add(tab2, text='Tab 2')      # Make second tab visible
        
        tabControl.pack(expand=1, fill="both")  # Pack to make visible
        
        # LabelFrame using tab1 as the parent
        mighty = ttk.LabelFrame(tab1, text=' Mighty Python ')
        mighty.grid(column=0, row=0, padx=8, pady=4)

        
        # Modify adding a Label using mighty as the parent instead of win
        a_label = ttk.Label(mighty, text="Enter a name:")
        a_label.grid(column=0, row=0, sticky='W')
    
    
        # Adding a Textbox Entry widget
        self.name = tk.StringVar()
        name_entered = ttk.Entry(mighty, width=24, textvariable=self.name)
        name_entered.grid(column=0, row=1, sticky='W')               
        
        # Adding a Button
        self.action = ttk.Button(mighty, text="Click Me!", command=self.click_me)   
        self.action.grid(column=2, row=1)                                
        
        ttk.Label(mighty, text="Choose a number:").grid(column=1, row=0)
        number = tk.StringVar()
        self.number_chosen = ttk.Combobox(mighty, width=14, textvariable=number, state='readonly')
        self.number_chosen['values'] = (1, 2, 4, 42, 100)
        self.number_chosen.grid(column=1, row=1)
        self.number_chosen.current(0)
        
             
        # Adding a Spinbox widget
        self.spin = Spinbox(mighty, values=(1, 2, 4, 42, 100), width=5, bd=8, command=self._spin) # using range
        self.spin.grid(column=0, row=2, sticky='W')
        
        # Using a scrolled Text control    
        scrol_w  = 40
        scrol_h  = 10 
        self.scr = scrolledtext.ScrolledText(mighty, width=scrol_w, height=scrol_h, wrap=tk.WORD)
        self.scr.grid(column=0, row=3, sticky='WE', columnspan=3)                    
        
        
        # Tab Control 2 ----------------------------------------------------------------------
        # We are creating a container frame to hold all other widgets -- Tab2
        self.mighty2 = ttk.LabelFrame(tab2, text=' The Snake ')
        self.mighty2.grid(column=0, row=0, padx=8, pady=4)
        
        # Creating three checkbuttons
        chVarDis = tk.IntVar()
        check1 = tk.Checkbutton(self.mighty2, text="Disabled", variable=chVarDis, state='disabled')
        check1.select()
        check1.grid(column=0, row=0, sticky=tk.W)                   
        
        chVarUn = tk.IntVar()
        check2 = tk.Checkbutton(self.mighty2, text="UnChecked", variable=chVarUn)
        check2.deselect()
        check2.grid(column=1, row=0, sticky=tk.W)                   
        
        chVarEn = tk.IntVar()
        check3 = tk.Checkbutton(self.mighty2, text="Enabled", variable=chVarEn)
        check3.deselect()
        check3.grid(column=2, row=0, sticky=tk.W)                     
        
        # trace the state of the two checkbuttons
        chVarUn.trace('w', lambda unused0, unused1, unused2 : self.checkCallback())    
        chVarEn.trace('w', lambda unused0, unused1, unused2 : self.checkCallback())   
        
        
        # First, we change our Radiobutton global variables into a list
        colors = ["Blue", "Gold", "Red"]   
        
        # create three Radiobuttons using one variable
        self.radVar = tk.IntVar()
        
        # Next we are selecting a non-existing index value for radVar
        self.radVar.set(99)                                 
         
        # Now we are creating all three Radiobutton widgets within one loop
        for col in range(3):                             
            curRad = tk.Radiobutton(self.mighty2, text=colors[col], variable=self.radVar, 
                                    value=col, command=self.radCall)          
            curRad.grid(column=col, row=1, sticky=tk.W)             # row=6
                
        # Add a Progressbar to Tab 2
        self.progress_bar = ttk.Progressbar(tab2, orient='horizontal', length=286, mode='determinate')
        self.progress_bar.grid(column=0, row=3, pady=2)         
             
        # Create a container to hold buttons
        buttons_frame = ttk.LabelFrame(self.mighty2, text=' ProgressBar ')
        buttons_frame.grid(column=0, row=2, sticky='W', columnspan=2)        
        
        # Add Buttons for Progressbar commands
        ttk.Button(buttons_frame, text=" Run Progressbar   ", command=self.run_progressbar).grid(column=0, row=0, sticky='W')  
        ttk.Button(buttons_frame, text=" Start Progressbar  ", command=self.start_progressbar).grid(column=0, row=1, sticky='W')  
        ttk.Button(buttons_frame, text=" Stop immediately ", command=self.stop_progressbar).grid(column=0, row=2, sticky='W')  
        ttk.Button(buttons_frame, text=" Stop after second ", command=self.progressbar_stop_after).grid(column=0, row=3, sticky='W')  
         
        for child in buttons_frame.winfo_children():  
            child.grid_configure(padx=2, pady=2) 
         
        for child in self.mighty2.winfo_children():  
            child.grid_configure(padx=8, pady=2) 
            
        # Creating a Menu Bar
        menu_bar = Menu(self.win)
        self.win.config(menu=menu_bar)
        
        # Add menu items
        file_menu = Menu(menu_bar, tearoff=0)
        file_menu.add_command(label="New")
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=self._quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

############################################################################
        # Create Manage Files Frame
        mngFilesFrame = ttk.LabelFrame(tab2, text=' Manage Files: ')
        mngFilesFrame.grid(column=0, row=1, sticky='WE', padx=10, pady=5)

        # Button Callback
        def getFileName():
            print('hello from getFileName')
#            fDir = path.dirname(__file__)
            fName = fd.askopenfilename(parent=self.win, initialdir=fDir)
            print("fName: " + fName)
            self.fileEntry.delete(0, tk.END)
            self.fileEntry.insert(0, fName)
            self.fileEntry.config(width=len(fName) + 3)
#            self.fileEntry.config(state='readonly')

        # Add Widgets to Manage Files Frame
        lb = ttk.Button(mngFilesFrame, text="Browse to File...",
                command=getFileName)
        lb.grid(column=0, row=0, sticky=tk.W)

        file = tk.StringVar()
        self.entryLen = scrol_w
        self.fileEntry = ttk.Entry(mngFilesFrame, width=self.entryLen,
                textvariable=file)
        self.fileEntry.bind("<Return>", (lambda event: copyFile()))
        self.fileEntry.grid(column=1, row=0, sticky=tk.W)

        logDir = tk.StringVar()
        self.netwEntry = ttk.Entry(mngFilesFrame, width=self.entryLen,
                textvariable=logDir)
        self.netwEntry.grid(column=1, row=1, sticky=tk.W)

        def copyFile():
            import shutil
            src = self.fileEntry.get()
            if len(src.split('/')) > 2:
                file = src.split('/')[-1]
            else:
                file = src.split("\\")[-1]

            dst = self.netwEntry.get() + '\\' + file
            try:
                shutil.copy(src, dst)
                mBox.showinfo('Copy File to Network', 
                        'Success: File copied')
            except FileNotFoundError as err:
                mBox.showerror('Copy File to Network',
                        '*** Failed to copy file! ***\n\n' + str(err))
            except Exception as err:
                mBox.showerror('Copy File to Network',
                        '*** Failed to copy file! ***\n\n' + str(err))

        cb = ttk.Button(mngFilesFrame, text="Copy File To :  ",
                command=copyFile)
        cb.grid(column=0, row=1, sticky=tk.E)

        # Add some space around each label
        for child in mngFilesFrame.winfo_children():
            child.grid_configure(padx=6, pady=6)

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

        # Display a Message Box
        def _msgBox():
            msg.showinfo('Python Message Info Box', 'A Python GUI created using tkinter:\nThe year is 2017.')  
            
        # Add another Menu to the Menu Bar and an item
        help_menu = Menu(menu_bar, tearoff=0)
        help_menu.add_command(label="About", command=_msgBox)   # display messagebox when clicked
        menu_bar.add_cascade(label="Help", menu=help_menu)
        
        # Change the main windows icon
#       self.win.iconbitmap('pyc.ico')
        
        # It is not necessary to create a tk.StringVar() 
        # strData = tk.StringVar()
        strData = self.spin.get()
        print("Spinbox value: " + strData)
        
        # call function
        self.usingGlobal()
        
#name_entered.focus()     
        tabControl.select(1)
win.iconbitmap(r'C:\Python34\DLLs\pyc.ico')

# Using tkinter Variable Classes
# strData = tk.StringVar()
# strData.set('Hello StringVar')
# print(strData.get())

# Default tkinter Variable Classes
# intData = tk.IntVar()
# print(intData.get())
# print(tk.DoubleVar())
# print(tk.BooleanVar())

# It is not necessary to create a tk.StringVar() 
# strData = tk.StringVar()
strData = spin.get()
# print("Hello " + strData)

# Printing the Global works
# print(GLOBAL_CONST)

def usingGlobal():
    GLOBAL_CONST = 777
#     print(GLOBAL_CONST)
    global GLOBAL_CONST
    print(GLOBAL_CONST)

# call function
usingGlobal()

# Place cursor into name Entry
class OOP():
    def __init__(self):
        # Create instance
        self.win = tk.Tk()

        # Add a title
        self.win.title("Python GUI")

        # Disable resizing the window
        self.win.resizable(0, 0)

        # Create a Queue
        self.guiQueue = Queue()

        self.createWidgets()

        # populate Tab 2 Entries
        self.defaultFileEntries()

        # Start TCP/IP server in its own thread
        svrT = Thread(target=startServer, daemon=True)
        svrT.start()

    def defaultFileEntries(self):
        # populate Entry before making it read-only
        #self.fileEntry.config(state='readonly')
        self.fileEntry.delete(0, tk.END)
        #self.fileEntry.insert(0, fDir)
        self.fileEntry.insert(0, 'Z:\\')  # bogus path
        #         if len(fDir) > self.entryLen:
        #             self.fileEntry.config(width=len(fDir) + 3)
        self.fileEntry.config(state='readonly')

        self.netwEntry.delete(0, tk.END)
        #self.netwEntry.insert(0, netDir)
        self.netwEntry.insert(0, 'Z:\\Backup')  # bogus path
#         if len(netDir) > self.entryLen:
#             self.netwEntry.config(width=len(netDir) + 3)

# Button callback

    def clickMe(self):
        self.action.configure(text='Hello ' + self.name.get())
        #         # Non-threaded code with sleep freezes the GUI
        #         for idx in range(10):
        #             sleep(5)
        #             self.scr.insert(tk.INSERT, str(idx) + '\n')

        #         # Threaded method does not freeze our GUI
        #         self.createThread()

        # Passing in the current class instance (self)
        print(self)
        bq.writeToScrol(self)
        sleep(2)
        htmlData = url.getHtml()
        print(htmlData)
        self.scr.insert(tk.INSERT, htmlData)

    # Spinbox callback
    def _spin(self):
        value = self.spin.get()
        #print(value)
        self.scr.insert(tk.INSERT, value + '\n')

    # Checkbox callback
    def checkCallback(self, *ignoredArgs):
        # only enable one checkbutton
        if self.chVarUn.get(): self.check3.configure(state='disabled')
        else: self.check3.configure(state='normal')
        if self.chVarEn.get(): self.check2.configure(state='disabled')
        else: self.check2.configure(state='normal')

    # Radiobutton callback function
    def radCall(self):
        radSel = self.radVar.get()
        if radSel == 0: self.monty2.configure(text='Blue')
        elif radSel == 1: self.monty2.configure(text='Gold')
        elif radSel == 2: self.monty2.configure(text='Red')

    # Exit GUI cleanly
    def _quit(self):
        self.win.quit()
        self.win.destroy()
        exit()

    def methodInAThread(self):
        print('Hi, how are you?')
#         for idx in range(10):
#             sleep(5)
#             self.scr.insert(tk.INSERT, str(idx) + '\n')

#     def methodInAThread(self, numOfLoops=10):
#         for idx in range(numOfLoops):
#             sleep(1)
#             self.scr.insert(tk.INSERT, str(idx) + '\n')
#         sleep(1)
#         print('methodInAThread():', self.runT.isAlive())

# Running methods in Threads

    def createThread(self, num):
        self.runT = Thread(target=self.methodInAThread, args=[num])
        self.runT.setDaemon(True)
        self.runT.start()
        print(self.runT)
        print('createThread():', self.runT.isAlive())

        # textBoxes are the Consumers of Queue data
        writeT = Thread(target=self.useQueues, daemon=True)
        writeT.start()

    # Create Queue instance
    def useQueues(self):
        #         guiQueue = Queue()
        #         print(guiQueue)
        #         for idx in range(10):
        #             guiQueue.put('Message from a queue: ' + str(idx))
        #         while True:
        #             print(guiQueue.get())

        # Now using a class member Queue
        while True:
            qItem = self.guiQueue.get()
            print(qItem)
            self.scr.insert(tk.INSERT, qItem + '\n')

    #####################################################################################
    def createWidgets(self):
        # Tab Control introduced here --------------------------------------
        tabControl = ttk.Notebook(self.win)  # Create Tab Control

        tab1 = ttk.Frame(tabControl)  # Create a tab
        tabControl.add(tab1, text='Tab 1')  # Add the tab

        tab2 = ttk.Frame(tabControl)  # Add a second tab
        tabControl.add(tab2, text='Tab 2')  # Make second tab visible

        tabControl.pack(expand=1, fill="both")  # Pack to make visible
        # ~ Tab Control introduced here -----------------------------------------

        # We are creating a container frame to hold all other widgets
        self.monty = ttk.LabelFrame(tab1, text=' Monty Python ')
        self.monty.grid(column=0, row=0, padx=8, pady=4)

        # Changing our Label
        ttk.Label(self.monty, text="Enter a name:").grid(column=0,
                                                         row=0,
                                                         sticky='W')

        # Adding a Textbox Entry widget
        self.name = tk.StringVar()
        nameEntered = ttk.Entry(self.monty, width=24, textvariable=self.name)
        nameEntered.grid(column=0, row=1, sticky='W')
        nameEntered.delete(0, tk.END)
        nameEntered.insert(0, '< default name >')

        # Adding a Button
        self.action = ttk.Button(self.monty,
                                 text="Click Me!",
                                 command=self.clickMe)
        self.action.grid(column=2, row=1)

        ttk.Label(self.monty, text="Choose a number:").grid(column=1, row=0)
        number = tk.StringVar()
        numberChosen = ttk.Combobox(self.monty, width=14, textvariable=number)
        numberChosen['values'] = (1, 2, 4, 42, 100)
        numberChosen.grid(column=1, row=1)
        numberChosen.current(0)

        # Adding a Spinbox widget using a set of values
        self.spin = Spinbox(self.monty,
                            values=(1, 2, 4, 42, 100),
                            width=5,
                            bd=8,
                            command=self._spin)
        self.spin.grid(column=0, row=2, sticky='W')

        # Using a scrolled Text control
        scrolW = 40
        scrolH = 10
        self.scr = scrolledtext.ScrolledText(self.monty,
                                             width=scrolW,
                                             height=scrolH,
                                             wrap=tk.WORD)
        self.scr.grid(column=0, row=3, sticky='WE', columnspan=3)

        # Tab Control 2 refactoring  ---------------------------------------------------
        # We are creating a container frame to hold all other widgets -- Tab2
        self.monty2 = ttk.LabelFrame(tab2, text=' The Snake ')
        self.monty2.grid(column=0, row=0, padx=8, pady=4)

        # Creating three checkbuttons
        chVarDis = tk.IntVar()
        check1 = tk.Checkbutton(self.monty2,
                                text="Disabled",
                                variable=chVarDis,
                                state='disabled')
        check1.select()
        check1.grid(column=0, row=0, sticky=tk.W)

        self.chVarUn = tk.IntVar()
        self.check2 = tk.Checkbutton(self.monty2,
                                     text="UnChecked",
                                     variable=self.chVarUn)
        self.check2.deselect()
        self.check2.grid(column=1, row=0, sticky=tk.W)

        self.chVarEn = tk.IntVar()
        self.check3 = tk.Checkbutton(self.monty2,
                                     text="Toggle",
                                     variable=self.chVarEn)
        self.check3.deselect()
        self.check3.grid(column=2, row=0, sticky=tk.W)

        # trace the state of the two checkbuttons
        self.chVarUn.trace(
            'w', lambda unused0, unused1, unused2: self.checkCallback())
        self.chVarEn.trace(
            'w', lambda unused0, unused1, unused2: self.checkCallback())
        # ~ Tab Control 2 refactoring  -----------------------------------------

        # Radiobutton list
        colors = ["Blue", "Gold", "Red"]

        self.radVar = tk.IntVar()

        # Selecting a non-existing index value for radVar
        self.radVar.set(99)

        # Creating all three Radiobutton widgets within one loop
        for col in range(3):
            curRad = 'rad' + str(col)
            curRad = tk.Radiobutton(self.monty2,
                                    text=colors[col],
                                    variable=self.radVar,
                                    value=col,
                                    command=self.radCall)
            curRad.grid(column=col, row=6, sticky=tk.W, columnspan=3)
            # And now adding tooltips
            tt.createToolTip(curRad, 'This is a Radiobutton control.')

        # Create a container to hold labels
        labelsFrame = ttk.LabelFrame(self.monty2, text=' Labels in a Frame ')
        labelsFrame.grid(column=0, row=7)

        # Place labels into the container element - vertically
        ttk.Label(labelsFrame, text="Label1").grid(column=0, row=0)
        ttk.Label(labelsFrame, text="Label2").grid(column=0, row=1)

        # Add some space around each label
        for child in labelsFrame.winfo_children():
            child.grid_configure(padx=8)

        # Create Manage Files Frame ------------------------------------------------
        mngFilesFrame = ttk.LabelFrame(tab2, text=' Manage Files: ')
        mngFilesFrame.grid(column=0, row=1, sticky='WE', padx=10, pady=5)

        # Button Callback
        def getFileName():
            print('hello from getFileName')
            fDir = path.dirname(__file__)
            fName = fd.askopenfilename(parent=self.win, initialdir=fDir)
            print(fName)
            self.fileEntry.config(state='enabled')
            self.fileEntry.delete(0, tk.END)
            self.fileEntry.insert(0, fName)

            if len(fName) > self.entryLen:
                self.fileEntry.config(width=len(fName) + 3)

        # Add Widgets to Manage Files Frame
        lb = ttk.Button(mngFilesFrame,
                        text="Browse to File...",
                        command=getFileName)
        lb.grid(column=0, row=0, sticky=tk.W)

        #-----------------------------------------------------
        file = tk.StringVar()
        self.entryLen = scrolW - 4
        self.fileEntry = ttk.Entry(mngFilesFrame,
                                   width=self.entryLen,
                                   textvariable=file)
        self.fileEntry.grid(column=1, row=0, sticky=tk.W)

        #-----------------------------------------------------
        logDir = tk.StringVar()
        self.netwEntry = ttk.Entry(mngFilesFrame,
                                   width=self.entryLen,
                                   textvariable=logDir)
        self.netwEntry.grid(column=1, row=1, sticky=tk.W)

        def copyFile():
            import shutil
            src = self.fileEntry.get()
            file = src.split('/')[-1]
            dst = self.netwEntry.get() + '\\' + file
            try:
                shutil.copy(src, dst)
                mBox.showinfo('Copy File to Network', 'Succes: File copied.')
            except FileNotFoundError as err:
                mBox.showerror('Copy File to Network',
                               '*** Failed to copy file! ***\n\n' + str(err))
            except Exception as ex:
                mBox.showerror('Copy File to Network',
                               '*** Failed to copy file! ***\n\n' + str(ex))

        cb = ttk.Button(mngFilesFrame,
                        text="Copy File To :   ",
                        command=copyFile)
        cb.grid(column=0, row=1, sticky=tk.E)

        # Add some space around each label
        for child in mngFilesFrame.winfo_children():
            child.grid_configure(padx=6, pady=6)

        # Creating a Menu Bar ==========================================================
        menuBar = Menu(tab1)
        self.win.config(menu=menuBar)

        # Add menu items
        fileMenu = Menu(menuBar, tearoff=0)
        fileMenu.add_command(label="New")
        fileMenu.add_separator()
        fileMenu.add_command(label="Exit", command=self._quit)
        menuBar.add_cascade(label="File", menu=fileMenu)

        # Add another Menu to the Menu Bar and an item
        helpMenu = Menu(menuBar, tearoff=0)
        helpMenu.add_command(label="About")
        menuBar.add_cascade(label="Help", menu=helpMenu)

        # Change the main windows icon
        self.win.iconbitmap(r'C:\Python34\DLLs\pyc.ico')

        # Using tkinter Variable Classes
        strData = tk.StringVar()
        strData.set('Hello StringVar')

        # It is not necessary to create a tk.StringVar()
        strData = tk.StringVar()
        strData = self.spin.get()

        # Place cursor into name Entry
        #         nameEntered.focus()
        # Set focus to Tab 2
        tabControl.select(1)

        # Add a Tooltip to the Spinbox
        tt.createToolTip(self.spin, 'This is a Spin control.')

        # Add Tooltips to more widgets
        tt.createToolTip(nameEntered, 'This is an Entry control.')
        tt.createToolTip(self.action, 'This is a Button control.')
        tt.createToolTip(self.scr, 'This is a ScrolledText control.')
class OOP():
    def __init__(self): 
        # Create instance
        self.win = tk.Tk()           

        # Add a title       
        self.win.title("Python GUI")   
         
        # Disable resizing the window  
        self.win.resizable(0,0)  
        
        # Create a Queue
        self.guiQueue = Queue() 
                              
        self.createWidgets() 
        
        # populate Tab 2 Entries      
        self.defaultFileEntries()
        
        # Start TCP/IP server in its own thread
        svrT = Thread(target=startServer, daemon=True)
        svrT.start()
    

    def defaultFileEntries(self):
        # populate Entry before making it read-only
        #self.fileEntry.config(state='readonly') 
        self.fileEntry.delete(0, tk.END)
        #self.fileEntry.insert(0, fDir) 
        self.fileEntry.insert(0, 'Z:\\')        # bogus path
#         if len(fDir) > self.entryLen:
#             self.fileEntry.config(width=len(fDir) + 3)
        self.fileEntry.config(state='readonly')         

        self.netwEntry.delete(0, tk.END)
        #self.netwEntry.insert(0, netDir) 
        self.netwEntry.insert(0, 'Z:\\Backup')  # bogus path
#         if len(netDir) > self.entryLen:
#             self.netwEntry.config(width=len(netDir) + 3)  
                  
            
    # Button callback
    def clickMe(self):
        self.action.configure(text='Hello ' + self.name.get())        
#         # Non-threaded code with sleep freezes the GUI
#         for idx in range(10):
#             sleep(5)
#             self.scr.insert(tk.INSERT, str(idx) + '\n')

#         # Threaded method does not freeze our GUI
#         self.createThread()
        
        # Passing in the current class instance (self)
        print(self)
        bq.writeToScrol(self)       
        sleep(2)
        htmlData = url.getHtml()
        print(htmlData)
        self.scr.insert(tk.INSERT, htmlData)

    
    # Spinbox callback 
    def _spin(self):
        value = self.spin.get()
        #print(value)
        self.scr.insert(tk.INSERT, value + '\n')
        
    # Checkbox callback  
    def checkCallback(self, *ignoredArgs):
        # only enable one checkbutton
        if self.chVarUn.get(): self.check3.configure(state='disabled')
        else:             self.check3.configure(state='normal')
        if self.chVarEn.get(): self.check2.configure(state='disabled')
        else:             self.check2.configure(state='normal') 
        
    # Radiobutton callback function
    def radCall(self):
        radSel=self.radVar.get()
        if   radSel == 0: self.monty2.configure(text='Blue')
        elif radSel == 1: self.monty2.configure(text='Gold')
        elif radSel == 2: self.monty2.configure(text='Red')        

    # Exit GUI cleanly
    def _quit(self):
        self.win.quit()
        self.win.destroy()
        exit() 
        
    def methodInAThread(self):
        print('Hi, how are you?')
#         for idx in range(10):
#             sleep(5)
#             self.scr.insert(tk.INSERT, str(idx) + '\n')        

#     def methodInAThread(self, numOfLoops=10):
#         for idx in range(numOfLoops):
#             sleep(1)
#             self.scr.insert(tk.INSERT, str(idx) + '\n') 
#         sleep(1)
#         print('methodInAThread():', self.runT.isAlive())
            
    # Running methods in Threads
    def createThread(self, num):
        self.runT = Thread(target=self.methodInAThread, args=[num])
        self.runT.setDaemon(True)    
        self.runT.start()
        print(self.runT)
        print('createThread():', self.runT.isAlive())

        # textBoxes are the Consumers of Queue data
        writeT = Thread(target=self.useQueues, daemon=True)
        writeT.start()
    
    # Create Queue instance  
    def useQueues(self):
#         guiQueue = Queue()     
#         print(guiQueue)
#         for idx in range(10):
#             guiQueue.put('Message from a queue: ' + str(idx))          
#         while True: 
#             print(guiQueue.get())
    
        # Now using a class member Queue        
        while True: 
            qItem = self.guiQueue.get()
            print(qItem)
            self.scr.insert(tk.INSERT, qItem + '\n') 
        
          
    #####################################################################################    
    def createWidgets(self):    
        # Tab Control introduced here --------------------------------------
        tabControl = ttk.Notebook(self.win)     # Create Tab Control
        
        tab1 = ttk.Frame(tabControl)            # Create a tab 
        tabControl.add(tab1, text='Tab 1')      # Add the tab
        
        tab2 = ttk.Frame(tabControl)            # Add a second tab
        tabControl.add(tab2, text='Tab 2')      # Make second tab visible
        
        tabControl.pack(expand=1, fill="both")  # Pack to make visible
        # ~ Tab Control introduced here -----------------------------------------
        
        # We are creating a container frame to hold all other widgets
        self.monty = ttk.LabelFrame(tab1, text=' Monty Python ')
        self.monty.grid(column=0, row=0, padx=8, pady=4)        
        
        # Changing our Label
        ttk.Label(self.monty, text="Enter a name:").grid(column=0, row=0, sticky='W')
   
        # Adding a Textbox Entry widget
        self.name = tk.StringVar()
        nameEntered = ttk.Entry(self.monty, width=24, textvariable=self.name)
        nameEntered.grid(column=0, row=1, sticky='W')     
        nameEntered.delete(0, tk.END)
        nameEntered.insert(0, '< default name >') 
        
        # Adding a Button
        self.action = ttk.Button(self.monty, text="Click Me!", command=self.clickMe)   
        self.action.grid(column=2, row=1)
        
        ttk.Label(self.monty, text="Choose a number:").grid(column=1, row=0)
        number = tk.StringVar()
        numberChosen = ttk.Combobox(self.monty, width=14, textvariable=number)
        numberChosen['values'] = (1, 2, 4, 42, 100)
        numberChosen.grid(column=1, row=1)
        numberChosen.current(0)
             
        # Adding a Spinbox widget using a set of values
        self.spin = Spinbox(self.monty, values=(1, 2, 4, 42, 100), width=5, bd=8, command=self._spin) 
        self.spin.grid(column=0, row=2, sticky='W')
                  
        # Using a scrolled Text control    
        scrolW  = 40; scrolH  =  10
        self.scr = scrolledtext.ScrolledText(self.monty, width=scrolW, height=scrolH, wrap=tk.WORD)
        self.scr.grid(column=0, row=3, sticky='WE', columnspan=3)
               
        # Tab Control 2 refactoring  ---------------------------------------------------
        # We are creating a container frame to hold all other widgets -- Tab2
        self.monty2 = ttk.LabelFrame(tab2, text=' The Snake ')
        self.monty2.grid(column=0, row=0, padx=8, pady=4)
        
        # Creating three checkbuttons
        chVarDis = tk.IntVar()
        check1 = tk.Checkbutton(self.monty2, text="Disabled", variable=chVarDis, state='disabled')
        check1.select()
        check1.grid(column=0, row=0, sticky=tk.W)                 
        
        self.chVarUn = tk.IntVar()
        self.check2 = tk.Checkbutton(self.monty2, text="UnChecked", variable=self.chVarUn)
        self.check2.deselect()
        self.check2.grid(column=1, row=0, sticky=tk.W )                  
         
        self.chVarEn = tk.IntVar()
        self.check3 = tk.Checkbutton(self.monty2, text="Toggle", variable=self.chVarEn)
        self.check3.deselect()
        self.check3.grid(column=2, row=0, sticky=tk.W)                 
     
        # trace the state of the two checkbuttons
        self.chVarUn.trace('w', lambda unused0, unused1, unused2 : self.checkCallback())    
        self.chVarEn.trace('w', lambda unused0, unused1, unused2 : self.checkCallback())   
        # ~ Tab Control 2 refactoring  -----------------------------------------
        
        # Radiobutton list
        colors = ["Blue", "Gold", "Red"]
        
        self.radVar = tk.IntVar()
        
        # Selecting a non-existing index value for radVar
        self.radVar.set(99)    
        
        # Creating all three Radiobutton widgets within one loop
        for col in range(3):
            curRad = 'rad' + str(col)  
            curRad = tk.Radiobutton(self.monty2, text=colors[col], variable=self.radVar, value=col, command=self.radCall)
            curRad.grid(column=col, row=6, sticky=tk.W, columnspan=3)
            # And now adding tooltips
            tt.createToolTip(curRad, 'This is a Radiobutton control.')
            
        # Create a container to hold labels
        labelsFrame = ttk.LabelFrame(self.monty2, text=' Labels in a Frame ')
        labelsFrame.grid(column=0, row=7)
         
        # Place labels into the container element - vertically
        ttk.Label(labelsFrame, text="Label1").grid(column=0, row=0)
        ttk.Label(labelsFrame, text="Label2").grid(column=0, row=1)
        
        # Add some space around each label
        for child in labelsFrame.winfo_children(): 
            child.grid_configure(padx=8)
        
        # Create Manage Files Frame ------------------------------------------------
        mngFilesFrame = ttk.LabelFrame(tab2, text=' Manage Files: ')
        mngFilesFrame.grid(column=0, row=1, sticky='WE', padx=10, pady=5)
        
        # Button Callback
        def getFileName():
            print('hello from getFileName')
            fDir  = path.dirname(__file__)
            fName = fd.askopenfilename(parent=self.win, initialdir=fDir)
            print(fName)
            self.fileEntry.config(state='enabled')
            self.fileEntry.delete(0, tk.END)
            self.fileEntry.insert(0, fName)
            
            if len(fName) > self.entryLen:
                self.fileEntry.config(width=len(fName) + 3)
                        
        # Add Widgets to Manage Files Frame
        lb = ttk.Button(mngFilesFrame, text="Browse to File...", command=getFileName)     
        lb.grid(column=0, row=0, sticky=tk.W) 
        
        #-----------------------------------------------------        
        file = tk.StringVar()
        self.entryLen = scrolW - 4
        self.fileEntry = ttk.Entry(mngFilesFrame, width=self.entryLen, textvariable=file)
        self.fileEntry.grid(column=1, row=0, sticky=tk.W)
              
        #-----------------------------------------------------
        logDir = tk.StringVar()
        self.netwEntry = ttk.Entry(mngFilesFrame, width=self.entryLen, textvariable=logDir)
        self.netwEntry.grid(column=1, row=1, sticky=tk.W) 

        
        def copyFile():
            import shutil   
            src = self.fileEntry.get()
            file = src.split('/')[-1]  
            dst = self.netwEntry.get() + '\\'+ file
            try:
                shutil.copy(src, dst)   
                mBox.showinfo('Copy File to Network', 'Succes: File copied.')     
            except FileNotFoundError as err:
                mBox.showerror('Copy File to Network', '*** Failed to copy file! ***\n\n' + str(err))
            except Exception as ex:
                mBox.showerror('Copy File to Network', '*** Failed to copy file! ***\n\n' + str(ex))   
        
        cb = ttk.Button(mngFilesFrame, text="Copy File To :   ", command=copyFile)     
        cb.grid(column=0, row=1, sticky=tk.E) 
                
        # Add some space around each label
        for child in mngFilesFrame.winfo_children(): 
            child.grid_configure(padx=6, pady=6)
                    

        # Creating a Menu Bar ==========================================================
        menuBar = Menu(tab1)
        self.win.config(menu=menuBar)
        
        # Add menu items
        fileMenu = Menu(menuBar, tearoff=0)
        fileMenu.add_command(label="New")
        fileMenu.add_separator()
        fileMenu.add_command(label="Exit", command=self._quit)
        menuBar.add_cascade(label="File", menu=fileMenu)
        
        # Add another Menu to the Menu Bar and an item
        helpMenu = Menu(menuBar, tearoff=0)
        helpMenu.add_command(label="About")
        menuBar.add_cascade(label="Help", menu=helpMenu)
        
        # Change the main windows icon
        self.win.iconbitmap(r'C:\Python34\DLLs\pyc.ico')
        
        # Using tkinter Variable Classes
        strData = tk.StringVar()
        strData.set('Hello StringVar')
        
        # It is not necessary to create a tk.StringVar() 
        strData = tk.StringVar()
        strData = self.spin.get()
        
        # Place cursor into name Entry
#         nameEntered.focus()  
        # Set focus to Tab 2           
        tabControl.select(1)      
      
        # Add a Tooltip to the Spinbox
        tt.createToolTip(self.spin, 'This is a Spin control.')         
        
        # Add Tooltips to more widgets
        tt.createToolTip(nameEntered, 'This is an Entry control.')  
        tt.createToolTip(self.action, 'This is a Button control.')                      
        tt.createToolTip(self.scr,    'This is a ScrolledText control.')   
示例#18
0
# Add menu items
file_menu = Menu(menu_bar, tearoff=0)
file_menu.add_command(label="New")
file_menu.add_separator()
file_menu.add_command(label="Exit", command=_quit)
menu_bar.add_cascade(label="File", menu=file_menu)

# Display a Message Box
def _msgBox():
    msg.showinfo('Python Message Info Box', 'A Python GUI created using tkinter:\nThe year is 2017.')  
    
# Add another Menu to the Menu Bar and an item
help_menu = Menu(menu_bar, tearoff=0)
help_menu.add_command(label="About", command=_msgBox)   # display messagebox when clicked
menu_bar.add_cascade(label="Help", menu=help_menu)

# Change the main windows icon
win.iconbitmap('pyc.ico')

# It is not necessary to create a tk.StringVar() 
# strData = tk.StringVar()

strData = spin.get()
print("Spinbox value: " + strData)

name_entered.focus()      # Place cursor into name Entry
#======================
# Start GUI
#======================
win.mainloop()
class OOP():
    def __init__(self): 
        # Create instance
        self.win = tk.Tk()           

        # Add a title       
        self.win.title("Python GUI")   
         
        # Disable resizing the window  
        self.win.resizable(0,0)  
        
        # Create a Queue
        self.guiQueue = Queue() 
                              
        self.createWidgets() 
        
        # populate Tab 2 Entries      
        self.defaultFileEntries()
        
        # create MySQL instance
        self.mySQL = MySQL()
                
    def defaultFileEntries(self): 
        self.fileEntry.delete(0, tk.END)
        self.fileEntry.insert(0, 'Z:\\')        # bogus path
        self.fileEntry.config(state='readonly')         

        self.netwEntry.delete(0, tk.END)
        self.netwEntry.insert(0, 'Z:\\Backup')  # bogus path                      
    
    # Combobox callback 
    def _combo(self, val=0):
        value = self.combo.get()
        self.scr.insert(tk.INSERT, value + '\n')
    
    # Spinbox callback 
    def _spin(self):
        value = self.spin.get()
        self.scr.insert(tk.INSERT, value + '\n')
                
    # Checkbox callback  
    def checkCallback(self, *ignoredArgs):
        # only enable one checkbutton
        if self.chVarUn.get(): self.check3.configure(state='disabled')
        else:             self.check3.configure(state='normal')
        if self.chVarEn.get(): self.check2.configure(state='disabled')
        else:             self.check2.configure(state='normal') 
        
    # Radiobutton callback function
    def radCall(self):
        radSel=self.radVar.get()
        if   radSel == 0: self.mySQL2.configure(text=WIDGET_LABEL + 'in Blue')
        elif radSel == 1: self.mySQL2.configure(text=WIDGET_LABEL + 'in Gold')
        elif radSel == 2: self.mySQL2.configure(text=WIDGET_LABEL + 'in Red')        

    # Exit GUI cleanly
    def _quit(self):
        self.win.quit()
        self.win.destroy()
        exit() 
       
    def methodInAThread(self, numOfLoops=10):
        for idx in range(numOfLoops):
            sleep(1)
            self.scr.insert(tk.INSERT, str(idx) + '\n') 
        sleep(1)
        print('methodInAThread():', self.runT.isAlive())
            
    # Running methods in Threads
    def createThread(self, num):
        self.runT = Thread(target=self.methodInAThread, args=[num])
        self.runT.setDaemon(True)    
        self.runT.start()
        print(self.runT)
        print('createThread():', self.runT.isAlive())

        # textBoxes are the Consumers of Queue data
        writeT = Thread(target=self.useQueues, daemon=True)
        writeT.start()
    
    # Create Queue instance  
    def useQueues(self):
        # Now using a class member Queue        
        while True: 
            qItem = self.guiQueue.get()
            print(qItem)
            self.scr.insert(tk.INSERT, qItem + '\n') 

    # Button callback
    def insertQuote(self):
        title = self.bookTitle.get()
        page = self.pageNumber.get()
        quote = self.quote.get(1.0, tk.END)
        print(title)
        print(quote)
        self.mySQL.insertBooks(title, page, quote)     

    # Button callback
    def getQuote(self):
        allBooks = self.mySQL.showBooks()  
        print(allBooks)
        self.quote.insert(tk.INSERT, allBooks)

    # Button callback
    def modifyQuote(self):
        raise NotImplementedError("This still needs to be implemented for the SQL command.")
          
    #####################################################################################    
    def createWidgets(self):    
        # Tab Control introduced here --------------------------------------
        tabControl = ttk.Notebook(self.win)     # Create Tab Control
        
        tab1 = ttk.Frame(tabControl)            # Create a tab 
        tabControl.add(tab1, text='MySQL')      # Add the tab 
        
        tab2 = ttk.Frame(tabControl)            # Add a second tab
        tabControl.add(tab2, text='Widgets')      # Make second tab visible
        
        tabControl.pack(expand=1, fill="both")  # Pack to make visible
        # ~ Tab Control introduced here -----------------------------------------
        
        # We are creating a container frame to hold all other widgets
        self.mySQL = ttk.LabelFrame(tab1, text=' Python Database ')
        self.mySQL.grid(column=0, row=0, padx=8, pady=4)        
        
        # Creating a Label
        ttk.Label(self.mySQL, text="Book Title:").grid(column=0, row=0, sticky='W')
   
        # Adding a Textbox Entry widget
        book = tk.StringVar()
        self.bookTitle = ttk.Entry(self.mySQL, width=34, textvariable=book)
        self.bookTitle.grid(column=0, row=1, sticky='W')     

        # Adding a Textbox Entry widget
        book1 = tk.StringVar()
        self.bookTitle1 = ttk.Entry(self.mySQL, width=34, textvariable=book1)
        self.bookTitle1.grid(column=0, row=2, sticky='W')  
        
        # Adding a Textbox Entry widget
        book2 = tk.StringVar()
        self.bookTitle2 = ttk.Entry(self.mySQL, width=34, textvariable=book2)
        self.bookTitle2.grid(column=0, row=3, sticky='W')  
        
        # Creating a Label
        ttk.Label(self.mySQL, text="Page:").grid(column=1, row=0, sticky='W')
        
        # Adding a Textbox Entry widget
        page = tk.StringVar()
        self.pageNumber = ttk.Entry(self.mySQL, width=6, textvariable=page)
        self.pageNumber.grid(column=1, row=1, sticky='W')     
 
        # Adding a Textbox Entry widget
        page = tk.StringVar()
        self.pageNumber1 = ttk.Entry(self.mySQL, width=6, textvariable=page)
        self.pageNumber1.grid(column=1, row=2, sticky='W')    
        
        # Adding a Textbox Entry widget
        page = tk.StringVar()
        self.pageNumber2 = ttk.Entry(self.mySQL, width=6, textvariable=page)
        self.pageNumber2.grid(column=1, row=3, sticky='W')           
       
        # Adding a Button
        self.action = ttk.Button(self.mySQL, text="Insert Quote", command=self.insertQuote)   
        self.action.grid(column=2, row=1)

        # Adding a Button
        self.action1 = ttk.Button(self.mySQL, text="Get Quotes", command=self.getQuote)   
        self.action1.grid(column=2, row=2)
        
        # Adding a Button
        self.action2 = ttk.Button(self.mySQL, text="Mody Quote", command=self.modifyQuote)   
        self.action2.grid(column=2, row=3)
                
        # Add some space around each widget
        for child in self.mySQL.winfo_children(): 
            child.grid_configure(padx=2, pady=4)
            

        quoteFrame = ttk.LabelFrame(tab1, text=' Book Quotation ')
        quoteFrame.grid(column=0, row=1, padx=8, pady=4)    

        # Using a scrolled Text control    
        quoteW  = 40; quoteH = 6
        self.quote = scrolledtext.ScrolledText(quoteFrame, width=quoteW, height=quoteH, wrap=tk.WORD)
        self.quote.grid(column=0, row=8, sticky='WE', columnspan=3)   

        # Add some space around each widget
        for child in quoteFrame.winfo_children(): 
            child.grid_configure(padx=2, pady=4)
                            
        #======================================================================================================               
        # Tab Control 2 
        #======================================================================================================
        # We are creating a container frame to hold all other widgets -- Tab2
        self.mySQL2 = ttk.LabelFrame(tab2, text=WIDGET_LABEL)
        self.mySQL2.grid(column=0, row=0, padx=8, pady=4)
        
        # Creating three checkbuttons
        self.chVarDis = tk.IntVar()
        self.check1 = tk.Checkbutton(self.mySQL2, text="Disabled", variable=self.chVarDis, state='disabled')
        self.check1.select()
        self.check1.grid(column=0, row=0, sticky=tk.W)               
        
        self.chVarUn = tk.IntVar()
        self.check2 = tk.Checkbutton(self.mySQL2, text="UnChecked", variable=self.chVarUn)
        self.check2.deselect()
        self.check2.grid(column=1, row=0, sticky=tk.W )                  
         
        self.chVarEn = tk.IntVar()
        self.check3 = tk.Checkbutton(self.mySQL2, text="Toggle", variable=self.chVarEn)
        self.check3.deselect()
        self.check3.grid(column=2, row=0, sticky=tk.W)                 
     
        # trace the state of the two checkbuttons
        self.chVarUn.trace('w', lambda unused0, unused1, unused2 : self.checkCallback())    
        self.chVarEn.trace('w', lambda unused0, unused1, unused2 : self.checkCallback())   
        
        # Radiobutton list
        colors = ["Blue", "Gold", "Red"]
        
        self.radVar = tk.IntVar()
        
        # Selecting a non-existing index value for radVar
        self.radVar.set(99)    
        
        # Creating all three Radiobutton widgets within one loop
        for col in range(3):
            curRad = 'rad' + str(col)  
            curRad = tk.Radiobutton(self.mySQL2, text=colors[col], variable=self.radVar, value=col, command=self.radCall)
            curRad.grid(column=col, row=6, sticky=tk.W, columnspan=3)
            # And now adding tooltips
            tt.createToolTip(curRad, 'This is a Radiobutton control.')
            
        # Create a container to hold labels
        labelsFrame = ttk.LabelFrame(self.mySQL2, text=' Labels within a Frame ')
        labelsFrame.grid(column=0, row=7, pady=6)
         
        # Place labels into the container element - vertically
        ttk.Label(labelsFrame, text="Choose a number:").grid(column=0, row=0)
        ttk.Label(labelsFrame, text="Label 2").grid(column=0, row=1)
        
        # Add some space around each label
        for child in labelsFrame.winfo_children(): 
            child.grid_configure(padx=6, pady=1)
            
        number = tk.StringVar()
        self.combo = ttk.Combobox(self.mySQL2, width=12, textvariable=number)
        self.combo['values'] = (1, 2, 4, 42, 100)
        self.combo.grid(column=1, row=7, sticky=tk.W)
        self.combo.current(0)       
        self.combo.bind('<<ComboboxSelected>>', self._combo) 
             
        # Adding a Spinbox widget using a set of values
        self.spin = Spinbox(self.mySQL2, values=(1, 2, 4, 42, 100), width=5, bd=8, command=self._spin) 
        self.spin.grid(column=2, row=7, sticky='W,', padx=6, pady=1)
        
        # Using a scrolled Text control    
        scrolW  = 40; scrolH = 1
        self.scr = scrolledtext.ScrolledText(self.mySQL2, width=scrolW, height=scrolH, wrap=tk.WORD)
        self.scr.grid(column=0, row=8, sticky='WE', columnspan=3)      
                
        # Create Manage Files Frame ------------------------------------------------
        mngFilesFrame = ttk.LabelFrame(tab2, text=' Manage Files: ')
        mngFilesFrame.grid(column=0, row=1, sticky='WE', padx=10, pady=5)
        
        # Button Callback
        def getFileName():
            print('hello from getFileName')
            fDir  = path.dirname(__file__)
            fName = fd.askopenfilename(parent=self.win, initialdir=fDir)
            print(fName)
            self.fileEntry.config(state='enabled')
            self.fileEntry.delete(0, tk.END)
            self.fileEntry.insert(0, fName)
            
            if len(fName) > self.entryLen:
                self.fileEntry.config(width=len(fName) + 3)
                        
        # Add Widgets to Manage Files Frame
        lb = ttk.Button(mngFilesFrame, text="Browse to File...", command=getFileName)     
        lb.grid(column=0, row=0, sticky=tk.W) 
        
        #-----------------------------------------------------        
        file = tk.StringVar()
        self.entryLen = scrolW - 4
        self.fileEntry = ttk.Entry(mngFilesFrame, width=self.entryLen, textvariable=file)
        self.fileEntry.grid(column=1, row=0, sticky=tk.W)
              
        #-----------------------------------------------------
        logDir = tk.StringVar()
        self.netwEntry = ttk.Entry(mngFilesFrame, width=self.entryLen, textvariable=logDir)
        self.netwEntry.grid(column=1, row=1, sticky=tk.W) 

        
        def copyFile():
            import shutil   
            src = self.fileEntry.get()
            file = src.split('/')[-1]  
            dst = self.netwEntry.get() + '\\'+ file
            try:
                shutil.copy(src, dst)   
                mBox.showinfo('Copy File to Network', 'Succes: File copied.')     
            except FileNotFoundError as err:
                mBox.showerror('Copy File to Network', '*** Failed to copy file! ***\n\n' + str(err))
            except Exception as ex:
                mBox.showerror('Copy File to Network', '*** Failed to copy file! ***\n\n' + str(ex))   
        
        cb = ttk.Button(mngFilesFrame, text="Copy File To :   ", command=copyFile)     
        cb.grid(column=0, row=1, sticky=tk.E) 
                
        # Add some space around each label
        for child in mngFilesFrame.winfo_children(): 
            child.grid_configure(padx=6, pady=6)            
            
        # Creating a Menu Bar ==========================================================
        menuBar = Menu(tab1)
        self.win.config(menu=menuBar)
        
        # Add menu items
        fileMenu = Menu(menuBar, tearoff=0)
        fileMenu.add_command(label="New")
        fileMenu.add_separator()
        fileMenu.add_command(label="Exit", command=self._quit)
        menuBar.add_cascade(label="File", menu=fileMenu)
        
        # Add another Menu to the Menu Bar and an item
        helpMenu = Menu(menuBar, tearoff=0)
        helpMenu.add_command(label="About")
        menuBar.add_cascade(label="Help", menu=helpMenu)
        
        # Change the main windows icon
        self.win.iconbitmap(r'C:\Python34\DLLs\pyc.ico')
        
        # Using tkinter Variable Classes
        strData = tk.StringVar()
        strData.set('Hello StringVar')
        
        # It is not necessary to create a tk.StringVar() 
        strData = tk.StringVar()
        strData = self.spin.get()
        
        # Place cursor into name Entry
        self.bookTitle.focus()        
      
        # Add a Tooltip to the Spinbox
        tt.createToolTip(self.spin, 'This is a Spin control.')         
        
        # Add Tooltips to more widgets
        tt.createToolTip(self.bookTitle, 'This is an Entry control.')  
        tt.createToolTip(self.action, 'This is a Button control.')                      
        tt.createToolTip(self.scr,    'This is a ScrolledText control.')   
示例#20
0
class OOP():
    def __init__(self):         # Initializer method
        # Create instance
        self.win = tk.Tk()   
        
        # Add a title       
        self.win.title("Python GUI")      
        self.create_widgets()


    # Create Queue instance  
    def use_queues(self, loops=5):
        gui_queue = Queue() 
        print(gui_queue)
        for idx in range(loops):
            gui_queue.put('Message from a queue: ' + str(idx))
        while True:
            print(gui_queue.get())
                
    def method_in_a_thread(self, num_of_loops=10):
        for idx in range(num_of_loops):
            sleep(1)
            self.scrol.insert(tk.INSERT, str(idx) + '\n')  

    # Running methods in Threads
    def create_thread(self, num=1):
        self.run_thread = Thread(target=self.method_in_a_thread, args=[num]) 
        self.run_thread.setDaemon(True) 
        self.run_thread.start()

        # start queue in its own thread
        write_thread = Thread(target=self.use_queues, args=[num], daemon=True)
        write_thread.start()   
                        
    # Button callback
    def click_me(self): 
        self.action.configure(text='Hello ' + self.name.get())
        print(self)
        # self.create_thread()                # now called from imported module
        bq.write_to_scrol(self)    
            
            
    # Spinbox callback 
    def _spin(self):
        value = self.spin.get()
        self.scrol.insert(tk.INSERT, value + '\n')
        
    # GUI Callback  
    def checkCallback(self, *ignored_args):
        # only enable one checkbutton
        if self.chVarUn.get(): self.check3.configure(state='disabled')
        else:                  self.check3.configure(state='normal')
        if self.chVarEn.get(): self.check2.configure(state='disabled')
        else:                  self.check2.configure(state='normal') 
        
    # Radiobutton Callback
    def radCall(self):
        radSel = self.radVar.get()
        if   radSel == 0: self.mighty2.configure(text='Blue')
        elif radSel == 1: self.mighty2.configure(text='Gold')
        elif radSel == 2: self.mighty2.configure(text='Red')          
        
    # update progressbar in callback loop
    def run_progressbar(self):
        self.progress_bar["maximum"] = 100
        for i in range(101):
            sleep(0.05)
            self.progress_bar["value"] = i   # increment progressbar
            self.progress_bar.update()       # have to call update() in loop
        self.progress_bar["value"] = 0       # reset/clear progressbar  
    
    def start_progressbar(self):
        self.progress_bar.start()
        
    def stop_progressbar(self):
        self.progress_bar.stop()
     
    def progressbar_stop_after(self, wait_ms=1000):    
        self.win.after(wait_ms, self.progress_bar.stop)        

    def usingGlobal(self):
        global GLOBAL_CONST
        GLOBAL_CONST = 777
        
                            
    # Exit GUI cleanly
    def _quit(self):
        self.win.quit()
        self.win.destroy()
        exit() 
                  
    #####################################################################################       
    def create_widgets(self):    
        tabControl = ttk.Notebook(self.win)          # Create Tab Control
        
        tab1 = ttk.Frame(tabControl)            # Create a tab 
        tabControl.add(tab1, text='Tab 1')      # Add the tab
        tab2 = ttk.Frame(tabControl)            # Add a second tab
        tabControl.add(tab2, text='Tab 2')      # Make second tab visible
        
        tabControl.pack(expand=1, fill="both")  # Pack to make visible
        
        # LabelFrame using tab1 as the parent
        mighty = ttk.LabelFrame(tab1, text=' Mighty Python ')
        mighty.grid(column=0, row=0, padx=8, pady=4)
        
        # Modify adding a Label using mighty as the parent instead of win
        a_label = ttk.Label(mighty, text="Enter a name:")
        a_label.grid(column=0, row=0, sticky='W')
     
        # Adding a Textbox Entry widget
        self.name = tk.StringVar()
        self.name_entered = ttk.Entry(mighty, width=24, textvariable=self.name)
        self.name_entered.grid(column=0, row=1, sticky='W')               
        
        # Adding a Button
        self.action = ttk.Button(mighty, text="Click Me!", command=self.click_me)   
        self.action.grid(column=2, row=1)                                
        
        ttk.Label(mighty, text="Choose a number:").grid(column=1, row=0)
        number = tk.StringVar()
        self.number_chosen = ttk.Combobox(mighty, width=14, textvariable=number, state='readonly')
        self.number_chosen['values'] = (1, 2, 4, 42, 100)
        self.number_chosen.grid(column=1, row=1)
        self.number_chosen.current(0)
        
        # Adding a Spinbox widget
        self.spin = Spinbox(mighty, values=(1, 2, 4, 42, 100), width=5, bd=9, command=self._spin) # using range
        self.spin.grid(column=0, row=2, sticky='W') # align left
        
        # Using a scrolled Text control    
        scrol_w = 40; scrol_h = 10                  # increase sizes
        self.scrol = scrolledtext.ScrolledText(mighty, width=scrol_w, height=scrol_h, wrap=tk.WORD)
        self.scrol.grid(column=0, row=3, sticky='WE', columnspan=3)                    
        
        for child in mighty.winfo_children():       # add spacing to align widgets within tabs
            child.grid_configure(padx=4, pady=2) 
         
        #=====================================================================================
        # Tab Control 2 ----------------------------------------------------------------------
        self.mighty2 = ttk.LabelFrame(tab2, text=' The Snake ')
        self.mighty2.grid(column=0, row=0, padx=8, pady=4)
        
        # Creating three checkbuttons
        chVarDis = tk.IntVar()
        check1 = tk.Checkbutton(self.mighty2, text="Disabled", variable=chVarDis, state='disabled')
        check1.select()
        check1.grid(column=0, row=0, sticky=tk.W)                   
        
        chVarUn = tk.IntVar()
        check2 = tk.Checkbutton(self.mighty2, text="UnChecked", variable=chVarUn)
        check2.deselect()
        check2.grid(column=1, row=0, sticky=tk.W)                   
        
        chVarEn = tk.IntVar()
        check3 = tk.Checkbutton(self.mighty2, text="Enabled", variable=chVarEn)
        check3.deselect()
        check3.grid(column=2, row=0, sticky=tk.W)                     
        
        # trace the state of the two checkbuttons
        chVarUn.trace('w', lambda unused0, unused1, unused2 : self.checkCallback())    
        chVarEn.trace('w', lambda unused0, unused1, unused2 : self.checkCallback())   
        
        
        # First, we change our Radiobutton global variables into a list
        colors = ["Blue", "Gold", "Red"]   
        
        # create three Radiobuttons using one variable
        self.radVar = tk.IntVar()
        
        # Next we are selecting a non-existing index value for radVar
        self.radVar.set(99)                                 
         
        # Now we are creating all three Radiobutton widgets within one loop
        for col in range(3):                             
            curRad = tk.Radiobutton(self.mighty2, text=colors[col], variable=self.radVar, 
                                    value=col, command=self.radCall)          
            curRad.grid(column=col, row=1, sticky=tk.W)             # row=6
            # And now adding tooltips
            ToolTip(curRad, 'This is a Radiobutton control')
                
        # Add a Progressbar to Tab 2
        self.progress_bar = ttk.Progressbar(tab2, orient='horizontal', length=286, mode='determinate')
        self.progress_bar.grid(column=0, row=3, pady=2)         
             
        # Create a container to hold buttons
        buttons_frame = ttk.LabelFrame(self.mighty2, text=' ProgressBar ')
        buttons_frame.grid(column=0, row=2, sticky='W', columnspan=2)        
        
        # Add Buttons for Progressbar commands
        ttk.Button(buttons_frame, text=" Run Progressbar   ", command=self.run_progressbar).grid(column=0, row=0, sticky='W')  
        ttk.Button(buttons_frame, text=" Start Progressbar  ", command=self.start_progressbar).grid(column=0, row=1, sticky='W')  
        ttk.Button(buttons_frame, text=" Stop immediately ", command=self.stop_progressbar).grid(column=0, row=2, sticky='W')  
        ttk.Button(buttons_frame, text=" Stop after second ", command=self.progressbar_stop_after).grid(column=0, row=3, sticky='W')  
         
        for child in buttons_frame.winfo_children():  
            child.grid_configure(padx=2, pady=2) 
         
        for child in self.mighty2.winfo_children():  
            child.grid_configure(padx=8, pady=2) 
            
        # Creating a Menu Bar
        menu_bar = Menu(self.win)
        self.win.config(menu=menu_bar)
        
        # Add menu items
        file_menu = Menu(menu_bar, tearoff=0)
        file_menu.add_command(label="New")
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=self._quit)
        menu_bar.add_cascade(label="File", menu=file_menu)
        
        # Display a Message Box
        def _msgBox():
            msg.showinfo('Python Message Info Box', 'A Python GUI created using tkinter:\nThe year is 2019.')  
            
        # Add another Menu to the Menu Bar and an item
        help_menu = Menu(menu_bar, tearoff=0)
        help_menu.add_command(label="About", command=_msgBox)   # display messagebox when clicked
        menu_bar.add_cascade(label="Help", menu=help_menu)
        
        # Change the main windows icon
        self.win.iconbitmap('pyc.ico')
        
        # It is not necessary to create a tk.StringVar() 
        # strData = tk.StringVar()
        strData = self.spin.get()

        # call function
        self.usingGlobal()
        
        self.name_entered.focus()     

        # Add Tooltips -----------------------------------------------------
        # Add a Tooltip to the Spinbox
        ToolTip(self.spin, 'This is a Spinbox control')   
                
        # Add Tooltips to more widgets
        ToolTip(self.name_entered, 'This is an Entry control')  
        ToolTip(self.action, 'This is a Button control')                      
        ToolTip(self.scrol, 'This is a ScrolledText control')
示例#21
0
class Example(Frame):
    def __init__(self, parent):
        Frame.__init__(self, parent)

        self.parent = parent
        self.initUI()

    def initUI(self):
        self.parent.title("")
        #self.style = Style()
        #self.style.theme_use("clam")
        #self.pack(fill=BOTH, expand = 1)

        self.labelU = Label(self, text="U:")
        self.labelP = Label(self, text="P:")

        self.mailrecipient = 'GoldenSights'
        
        self.entryUsername = Entry(self)
        self.entryUsername.focus_set()
        self.entryUsername.bind('<Return>', lambda event: self.entryPassword.focus_set())

        self.entryPassword = Entry(self)
        self.entryPassword.config(show='•')
        self.entryPassword.bind('<Return>', lambda event: self.login(self.entryUsername.get(), self.entryPassword.get()))

        self.newbutton = Button(self, text="Login", command= lambda: self.login(self.entryUsername.get(), self.entryPassword.get()))
        self.newbutton.bind('<Return>', lambda event: self.login(self.entryUsername.get(), self.entryPassword.get()))
        self.newbutton.config(width=6)
        self.quitbutton = Button(self, text="Quit", command= lambda: self.quit())
        self.quitbutton.config(width=6)
    
        self.labelU.grid(row=0, column=0,padx=0)
        self.entryUsername.grid(row=0, column=1)
        self.labelP.grid(row=1, column=0)
        self.entryPassword.grid(row=1, column=1, pady=4)
        self.newbutton.grid(row=2, column=1)
        self.quitbutton.grid(row=3, column=1, pady=4)

        self.labelErrorPointer = Label(self, text="◀")

        self.indicatorGreen = PhotoImage(file="indicatorGreen.gif")
        self.indicatorRed = PhotoImage(file="indicatorRed.gif")
        self.indicatorBlue = PhotoImage(file="indicatorBlue.gif")
        self.indicatorBlack = PhotoImage(file="indicatorBlack.gif")
        

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


        w=400
        h=480
        x = (sw - w) / 2
        y = (sh - h) / 2

        self.parent.geometry('%dx%d+%d+%d' % (w, h, x, y-50))
        

    def login(self, username, password):
        print('U: ' + username)
        self.username = username
        if username == '' or not all(char in string.ascii_letters+string.digits+'_-' for char in username):
            print('Please enter a username')
            self.entryUsername.focus_set()
            self.labelErrorPointer.grid(row=0, column=2)
        elif password == '':
            print('Please enter a password')
            self.entryPassword.focus_set()
            self.labelErrorPointer.grid(row=1, column=2)
            
        else:
            self.labelErrorPointer.grid_forget()
            print('Attempting login for ' + username)
            try:
                self.USERAGENT = username + ' practices Tkinter+PRAW mixing with utility by /u/GoldenSights.'
                self.r = praw.Reddit(self.USERAGENT)
                #self.r.login(username, password)
                print('Success')
                self.labelU.grid_forget()
                self.labelP.grid_forget()
                self.entryUsername.grid_forget()
                self.entryPassword.grid_forget()
                self.newbutton.grid_forget()
                self.quitbutton.grid_forget()
                self.usernamelabel = Label(self, text=username + ', Sending to /u/' + self.mailrecipient)
                self.usernamelabel.grid(row=0, column=0, columnspan=8)
                self.quitbutton.grid(row=900, column=0)


                self.labellist = []
                self.entrylist = []
                self.verifylist = []
                self.misclist = []
                
                self.optionDiscuss = "Discussion Flair + Crossposting"
                self.optionRegister = "Register a new Candidate"

                self.prevmode = self.optionDiscuss
                self.curmode = self.optionDiscuss
                self.optionvar = tkinter.StringVar(self)
                self.optionvar.trace("w",self.permaloop)
                self.optionvar.set(self.optionDiscuss)
                self.option = OptionMenu(self, self.optionvar, self.optionDiscuss, self.optionRegister, "three", "four")
                self.newbutton.unbind("<Return>")
                self.entryUsername.unbind("<Return>")
                self.entryPassword.unbind("<Return>")
                self.option.grid(row=1,column=0,columnspan=8,pady=8)
                self.updategui(True)
            except praw.errors.InvalidUserPass:
                pass
                print('Invalid username or password')
                self.entryPassword.delete(0,200)
                self.labelErrorPointer.grid(row=1, column=2)

    def permaloop(self, *args):
        self.curmode = self.optionvar.get()
        print('Was: ' + self.prevmode + ' | Now: ' + self.curmode)
        if self.curmode != self.prevmode:
            self.prevmode = self.curmode
            self.updategui(True)

    def updategui(self, *args):
        if args[0] == True:
            print('Cleaning GUI')
            for item in self.labellist:
                item.grid_forget()
            for item in self.entrylist:
                item.grid_forget()
            for item in self.verifylist:
                item.grid_forget()
            for item in self.misclist:
                item.grid_forget()
            self.labellist = []
            self.entrylist = []
            self.verifylist = []
            self.misclist = []


            if self.curmode == self.optionDiscuss:
                self.newrowindex = 4
                self.labelPermalink = Label(self, text="Thread Permalink:")
                self.entryPermalink = Entry(self)
                self.rowconfigure(2,weight=2)
                self.labelPermalink.grid(row=2,column=0)
                self.entryPermalink.grid(row=2,column=1)
                self.labelcrossposting = Label(self,text="Crosspost to:")
                self.labelcrossposting.grid(row=3,column=0,columnspan=2,sticky="w")

                for m in range(5):
                    self.redditlabel = Label(self,text="/r/")
                    self.redditlabel.grid(row=self.newrowindex,column=0, sticky="e")
                    self.labellist.append(self.redditlabel)

                    self.redditentry = Entry(self)
                    self.redditentry.grid(row=self.newrowindex,column=1)
                    self.entrylist.append(self.redditentry)

                    self.newrowindex +=1

                self.morerowbutton = Button(self,text="+row",command=lambda: self.morerows('/r/', 0, 1, 20))
                self.morerowbutton.grid(row=898,column=0,columnspan=2)

                self.verifybutton = Button(self,text="Verify",command= lambda: self.updategui(False))
                self.verifybutton.grid(row=899,column=0,columnspan=2)

                self.newrowindex += 2

                self.misclist.append(self.labelPermalink)
                self.misclist.append(self.labelcrossposting)
                self.misclist.append(self.entryPermalink)
                self.misclist.append(self.morerowbutton)
                self.misclist.append(self.verifybutton)

            if self.curmode == self.optionRegister:
                self.newrowindex = 6
                self.labelCanUsername = Label(self, text="Candidate's Username:  /u/")
                self.entryCanUsername = Entry(self)
                self.labelCanRealname = Label(self, text="Candidate's Realname:")
                self.entryCanRealname = Entry(self)
                self.labelCanFlair = Label(self, text="Candidate's Flair:")
                self.entryCanFlair = Entry(self)
                self.entryMo = Spinbox(self, width=9, values=('January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'))
                self.entryDa = Spinbox(self, width=2, from_=1, to=31)
                self.entryYr = Spinbox(self, width=4, from_=2014, to=2500)
                self.labelHH = Label(self, text="Schedule time UTC:")
                self.entryHH = Spinbox(self, from_=0, to=23, width=2)
                self.entryMM = Spinbox(self, from_=0, to=59, width=2)
                self.entryYr.delete(0,'end')
                self.entryYr.insert(0,2014)

                self.morerowbutton = Button(self,text="+question",command=lambda: self.morerows('Q:', 0, 1, 25))
                self.morerowbutton.grid(row=898,column=0,columnspan=8)

                self.verifybutton = Button(self,text="Verify",command= lambda: self.updategui(False))
                self.verifybutton.grid(row=899,column=0,columnspan=8)

                self.misclist.append(self.labelCanUsername)
                self.misclist.append(self.labelCanRealname)
                self.misclist.append(self.entryCanUsername)
                self.misclist.append(self.entryCanRealname)
                self.misclist.append(self.labelHH)
                self.misclist.append(self.entryHH)
                self.misclist.append(self.entryMM)
                self.misclist.append(self.entryMo)
                self.misclist.append(self.entryDa)
                self.misclist.append(self.entryYr)

                self.labelCanUsername.grid(row=2, column=0, sticky="e")
                self.labelCanRealname.grid(row=3, column=0, sticky="e")
                self.entryCanUsername.grid(row=2, column=1, columnspan=3)
                self.entryCanRealname.grid(row=3, column=1, columnspan=3)
                self.entryMo.grid(row=4, column=1,sticky="e")
                self.entryDa.grid(row=4, column=2)
                self.entryYr.grid(row=4, column=3)
                self.labelHH.grid(row=4, column=0, sticky="se", pady=5)
                self.entryHH.grid(row=5, column=1, sticky="e")
                self.entryMM.grid(row=5, column=2, sticky="w")
        else:
            if self.curmode == self.optionDiscuss:

                verifies = []

                i = self.entryPermalink.get()
                if len(i) == 6:
                    pid = i
                else:
                    if 'www.reddit.com/r/' in i and '/comments/' in i:
                        pid = i.split('/comments/')[1].split('/')[0]
                    if 'http://redd.it/' in i:
                        pid = i.split('redd.it/')[1]

                for flag in self.verifylist:
                    flag.grid_forget()
                    self.verifylist.remove(flag)

                try:
                    print('Fetching Submission ' + pid)
                    self.r.get_info(thing_id="t3_" + pid).title + 'Check'
                    self.redditlabel = Label(self, image=self.indicatorGreen)
                    self.redditlabel.grid(row=2,column=2)
                    self.verifylist.append(self.redditlabel)
                    verifies.append(True)
                    print('\tSuccess')
                except:
                    print('Failed. Make sure to include the http://. Copy and paste straight from your browser for best result')
                    self.redditlabel = Label(self, image=self.indicatorRed)
                    self.redditlabel.grid(row=2,column=2)
                    self.verifylist.append(self.redditlabel)
                    verifies.append(False)

                for entry in self.entrylist:
                    i = entry.get()
                    if i != '':
                        print('Fetching /r/' + i)
                        if all(char in string.ascii_letters+string.digits+'_-' for char in i):
                            try:
                                sub = self.r.get_subreddit(i,fetch=True)
                                self.redditlabel = Label(self, image=self.indicatorGreen)
                                self.redditlabel.grid(row=entry.grid_info()['row'],column=2)
                                self.verifylist.append(self.redditlabel)
                                verifies.append(True)
                                print('\tSuccess')
                            except:
                                self.redditlabel = Label(self, image=self.indicatorRed)
                                self.redditlabel.grid(row=entry.grid_info()['row'],column=2)
                                self.verifylist.append(self.redditlabel)
                                verifies.append(False)
                                print('\tFailed')
                            time.sleep(2)
                        else:
                            self.redditlabel = Label(self, image=self.indicatorRed)
                            self.redditlabel.grid(row=entry.grid_info()['row'],column=2)
                            self.verifylist.append(self.redditlabel)
                            verifies.append(False)
                            print('\tFailed')

                print(verifies)


            if self.curmode == self.optionRegister:

                verifies = []
                u=self.entryCanUsername.get()
                print('Fetching /u/' + u)
                if not all(char in string.ascii_letters+string.digits+'_-' for char in u):
                    self.redditlabel = Label(self, image=self.indicatorRed)
                    self.redditlabel.grid(row=2, column=4)
                    self.verifylist.append(self.redditlabel)
                    verifies.append(False)
                    print('\tBad characterage')
                else:
                    try:
                        u = self.r.get_redditor(u)
                        print(u)
                        self.redditlabel = Label(self, image=self.indicatorGreen)
                        self.redditlabel.grid(row=2,column=4)
                        self.verifylist.append(self.redditlabel)
                        verifies.append(True)
                        print('\tSuccess')
                    except:
                        self.redditlabel = Label(self, image=self.indicatorRed)
                        self.redditlabel.grid(row=2,column=4)
                        self.verifylist.append(self.redditlabel)
                        verifies.append(False)
                        print('\tFailed')

                try:
                    print('Checking Time')
                    t = self.entryMo.get() + ' ' + self.entryDa.get() + ' ' + self.entryYr.get() + ' ' + self.entryHH.get() + ':' + self.entryMM.get()
                    plandate = datetime.datetime.strptime(t, "%B %d %Y %H:%M")
                    plandate = datetime.datetime.utcfromtimestamp(plandate.timestamp())
                    print('\t' + str(plandate.timestamp()))

                    self.redditlabel = Label(self, image=self.indicatorGreen)
                    self.redditlabel.grid(row=5,column=3)
                    self.verifylist.append(self.redditlabel)
                    verifies.append(True)
                except:
                    print('\tFailed')
                    self.redditlabel = Label(self, image=self.indicatorRed)
                    self.redditlabel.grid(row=5,column=3)
                    self.verifylist.append(self.redditlabel)
                    verifies.append(False)

                print(verifies)


    def morerows(self, label, columnm, columnn, limit, *args):
        self.redditlabel = Label(self,text=label)
        self.redditlabel.grid(row=self.newrowindex,column=columnm, sticky="e")
        self.labellist.append(self.redditlabel)

        self.redditentry = Entry(self)
        self.redditentry.grid(row=self.newrowindex,column=columnn, columnspan=8)
        self.entrylist.append(self.redditentry)

        self.newrowindex += 1
        if self.newrowindex >= limit:
            self.morerowbutton.grid_forget()
        print(self.newrowindex)
示例#22
0
class GUI():
    def __init__(self):
        self.root = Tk(
            className='Программа для удаление подписей из электронных писем')
        self.root.geometry("1000x600")
        self.root.wm_resizable(False, False)

        self.panelFrame = LabelFrame(self.root, height=100, text="")
        self.panelFrame.pack(side='top', fill='x')

        self.labelLogin = Label(self.panelFrame, text="Адрес почты: ")
        self.labelLogin.place(x=10, y=40)

        self.loginField = Entry(self.panelFrame, width=20)
        self.loginField.place(x=100, y=40)

        self.labelPassword = Label(self.panelFrame, text="Пароль: ")
        self.labelPassword.place(x=280, y=40)

        self.passwordField = Entry(self.panelFrame, show="*", width=15)
        self.passwordField.place(x=340, y=40)

        self.labelLogin = Label(
            self.panelFrame,
            text="Порядковый номер письма \nв папке 'входящие': ")
        self.labelLogin.place(x=490, y=30)

        self.sb = Spinbox(self.panelFrame, from_=1, to=10000)
        self.sb.place(x=690, y=40, width=50)

        self.buttonDeleteSing = Button(self.panelFrame,
                                       text="Удалить подпись",
                                       command=self._delete_signature)
        self.buttonDeleteSing.place(x=770, y=15, width=200)

        self.buttonInfo = Button(self.panelFrame, text="Помощь")
        self.buttonInfo.place(x=770, y=45, width=200)

        self.buttonInfo.bind('<ButtonRelease-1>', GUI._show_info)

        self.textFrame1 = LabelFrame(self.root,
                                     width=500,
                                     text='Исходный текст письма')
        self.textFrame1.pack(fill='y', side='left')

        self.textbox1 = Text(self.textFrame1, font='Arial 12', wrap='word')
        self.textbox1.pack(side='left', fill='both')
        self.textbox1.place(width=490)

        self.textFrame2 = LabelFrame(self.root,
                                     width=500,
                                     text='Текст без подписи')
        self.textFrame2.pack(fill='y', side='right')

        self.textbox2 = Text(self.textFrame2, font='Arial 12', wrap='word')
        self.textbox2.pack(side='left', fill='both')
        self.textbox2.place(width=490)

    def _show_messagebox(self, messageType, message):
        if messageType == 'error':
            messagebox.showerror('Ошибка', message)
        elif messageType == 'warning':
            messagebox.showwarning('Предупреждение', message)
        else:
            messagebox.showinfo('Info', message)

    def _delete_signature(self):

        address = self.loginField.get()
        password = self.passwordField.get()
        index = int(self.sb.get())

        try:
            original, without_sign = SignatureRemover.delete_signature(
                address, password, index)
        except EmailException as e:
            self._show_messagebox('error', str(e))
            return
        except EmailWarning as e:
            self._show_messagebox('warning', str(e))
            return
        except ClassifierException as e:
            self._show_messagebox(
                'error', "Ошибка при загрузке классификатора:\n" + str(e))
            return

        self._show_email_lines(original, self.textbox1)
        self._show_email_lines(without_sign, self.textbox2)

        del_lines_count = len(original) - len(without_sign)

        self._show_messagebox('info', "Удалено строк: " + str(del_lines_count))

    def _show_info(self):
        messagebox.showinfo(
            'Информация', 'Программа позволяет удалять подпись '
            'из текстов электронных писем папки "Входящие" почтового ящика gmail.\nУдаление '
            'подписи возможно в письмах, содержащих только текст.'
            '\nДля удаления подписи из письма введите адрес электронной почты, пароль и порядковый номер'
            ' письма в папке "Входящие", затем нажмите кнопку "Удалить подпись"'
        )

    def _show_email_lines(self, lines, textbox):
        textbox.delete('1.0', END)
        all_lines = "\n".join(lines)
        textbox.insert('1.0', all_lines)

    def show(self):
        self.root.mainloop()