Пример #1
0
 def add_entry(self, text):
     entry = Entry(self)
     entry.insert(0, ",".join(text))
     entry.pack(fill="both", expand=True)
     entry.config(state="readonly")
     self.bindings(entry)
     self.entries.append(entry)
Пример #2
0
class BookManagerUi(Frame):

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

        self.parent = parent

        self.initUI()

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


    def initUI(self):

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

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


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

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

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

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

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


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

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


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

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

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

        self.lb = Listbox(self)

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


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

        self.delete = value

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

        self.lb.delete(0,END)


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

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


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


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

        self.lb.delete(0,END)

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

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

    #삭제 버튼
    def clicked_delete(self):
        self.lb.delete(0,END)
        q = self.db.excute_delete(self.delete)
        self.lb.insert(END,q+' is delete from database')
Пример #3
0
 def add_entry(self, text):
     entry = Entry(self)
     entry.insert(0, "".join(text))
     entry.pack(fill="both", expand=True)
     entry.config(state="disable")
     self.entries.append(entry)
Пример #4
0
class App(Tk):  #the main class for the main window
    def __init__(self):
        Tk.__init__(self)

        # window properties
        self.title(string="Screen Recorder by Darsh Sharma")
        self.iconbitmap("icon.ico")
        self.resizable(width=False, height=False)

        ffmpegAvailable = False
        for item in os.listdir():
            if item == "ffmpeg.exe":
                ffmpegAvailable = True
                break
        if not ffmpegAvailable:
            self.withdraw()
            if messagebox.askyesno(
                    "FFmpeg Not Found",
                    "ffmpeg.exe could not be found in screen recorder's directory. Do you want to be redirected to the ffmpeg download website? to pehele mera channel subscribe karo"
            ):
                webbrowser.open_new_tab(
                    "https://www.youtube.com/channel/UCznpesyijPSg4fK082eDEow/videos"
                )
            exit()
        self.cmdGen = cmdGen(
        )  # create a command generator object to store settings

        # file name
        label1 = Label(self, text="File Name:")
        label1.grid(row=0, column=0, sticky="")
        self.entry1 = Entry(self)
        self.entry1.grid(row=0, column=1, sticky="ew")

        # ensure the existance of the "ScreenCaptures" directory
        try:
            os.mkdir("ScreenCaptures by Darsh Sharma")
        except FileExistsError:
            pass
        os.chdir("ScreenCaptures by Darsh Sharma")

        # find a default file name that is currently available.
        defaultFile = "DarshPro.mp4"
        available = False
        fileNum = 0
        while available == False:
            hasMatch = False
            for item in os.listdir():
                if item == defaultFile:
                    hasMatch = True
                    break
            if not hasMatch:
                available = True
            else:
                fileNum += 1
                defaultFile = "DarshPro" + str(fileNum) + ".mp4"
        os.chdir("..")
        self.entry1.insert(END, defaultFile)

        # radio buttons determine what to record
        self.what = StringVar()
        self.what.set("desktop")
        self.radio2 = Radiobutton(self,
                                  text="record the window with the title of: ",
                                  variable=self.what,
                                  value="title",
                                  command=self.enDis1)
        self.radio1 = Radiobutton(self,
                                  text="record the entire desktop",
                                  variable=self.what,
                                  value="desktop",
                                  command=self.enDis)
        self.radio1.grid(row=1, column=0, sticky="w")
        self.radio2.grid(row=2, column=0, sticky="w")
        self.entry2 = Entry(self, state=DISABLED)
        self.entry2.grid(row=2, column=1, sticky="ew")

        # initialize webcam
        self.webcamdevices = Webcam.listCam()
        self.webcamrecorder = Webcam.capturer("")

        # "record from webcam" checkbox
        self.rcchecked = IntVar()
        self.recordcam = Checkbutton(self,
                                     text="Record from webcam",
                                     command=self.checkboxChanged,
                                     variable=self.rcchecked)
        self.recordcam.grid(row=3, column=0)

        # a drop-down allowing you to select the webcam device from the available directshow capture devices
        self.devicename = StringVar(self)
        if self.webcamdevices:
            self.devicename.set(self.webcamdevices[0])
            self.deviceselector = OptionMenu(self, self.devicename,
                                             *self.webcamdevices)
            self.deviceselector.config(state=DISABLED)
            self.deviceselector.grid(row=3, column=1)
        else:
            self.devicename.set("NO DEVICES AVAILABLE")
            self.recordcam.config(state=DISABLED)
            self.deviceselector = OptionMenu(self, self.devicename,
                                             "NO DEVICES AVAILABLE")
            self.deviceselector.config(state=DISABLED)
            self.deviceselector.grid(row=3, column=1)

        self.opButton = Button(self,
                               text="⚙ Additional Options...",
                               command=self.openSettings)
        self.opButton.grid(row=4, column=1, sticky='e')

        # the "start recording" button
        self.startButton = Button(self,
                                  text="⏺ Start Recording",
                                  command=self.startRecord)
        self.startButton.grid(row=5, column=0, columnspan=2)

        # some variables
        self.recording = False  # are we recording?
        self.proc = None  # the popen object for ffmpeg (during screenrecord)
        self.recorder = recordFile.recorder(
        )  # the "recorder" object for audio (see recordFile.py)
        self.mergeProcess = None  # the popen object for ffmpeg (while merging video and audio files)

        # start the ffmpeg monitoring callback
        self.pollClosed()

    def openSettings(self):
        self.settings = settingsWin(self, self.cmdGen, self.recorder)

    def pollClosed(self):
        """callback that repeats itself every 100ms. Automatically determines if ffmpeg is still running."""
        if self.recording:
            if self.proc.poll() != None:
                self.startRecord()
                messagebox.showerror(
                    "ffmpeg error", "ffmpeg has stopped working. ERROR: \n" +
                    str(self.proc.stderr.read()).replace('\\r\\n', '\n'))
            if self.recorder.error:
                self.startRecord()
        if self.mergeProcess and self.recording == False:
            if self.mergeProcess.poll() != None:
                self.startButton.config(text="⏺ Start Recording", state=NORMAL)
                self.title(string="Screen Recorder by Darsh Sharma")
        self.after(100, self.pollClosed)

    def enDis(self):
        """Called when the "desktop" radio button is pressed"""
        self.entry2.config(state=DISABLED)
        # self.what.set("desktop")

    def enDis1(self):
        """Called when the "window title" radio button is pressed"""
        self.entry2.config(state=NORMAL)
        # self.what.set("title")

    def checkboxChanged(self):
        """Called when the "record webcam" checkbox is checked or unchecked."""
        #self.rcchecked = not self.rcchecked
        if self.rcchecked.get():
            self.deviceselector.config(state=NORMAL)
        else:
            self.deviceselector.config(state=DISABLED)

    def startRecord(self):
        """toggles recording. Will start conversion subprocess on recording completion"""
        if self.recording == False:
            # change the window
            self.title(string="Screen Recorder by Darsh Sharma (Recording...)")
            self.startButton.config(text="⏹️ Stop Recording")
            self.filename = self.entry1.get()

            # disable interface
            self.entry1.config(state=DISABLED)
            self.radio1.config(state=DISABLED)
            self.radio2.config(state=DISABLED)
            self.deviceselector.config(state=DISABLED)
            self.opButton.config(state=DISABLED)
            if self.what.get() == "title":
                self.entry2.config(state=DISABLED)

            # ensure the existence of the "tmp" directory
            try:
                os.mkdir("tmp")
            except FileExistsError:
                pass

            # start screen recording process
            self.recording = True
            startupinfo = subprocess.STARTUPINFO()
            startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
            startupinfo.wShowWindow = subprocess.SW_HIDE

            # self.cmdGen.setFps(60)
            # self.cmdGen.setEncode('nvenc_h264') # CPU: mpeg4 // NVIDIA: h264_nvenc // AMD: no.
            self.cmdGen.setSource(self.what.get() == "title",
                                  self.entry2.get())
            command = self.cmdGen.getCmd("tmp/tmp.mkv")
            self.proc = subprocess.Popen(
                args=command,
                startupinfo=startupinfo)  #,stderr=subprocess.PIPE)

            # start audio recording
            self.recorder.record("tmp/tmp.wav")

            # start webcam recording, if checked
            self.recordcam.config(state=DISABLED)
            if self.rcchecked.get() and self.webcamdevices:
                self.webcamrecorder.setDevice(str(self.devicename.get()))
                self.webcamrecorder.startCapture("tmp/webcamtmp.mkv")

            # minimize the window to get it out of the way of the recording
            self.iconify()
        elif self.recording == True:
            self.deiconify()
            defaultFile = self.filename

            # re-enable interface
            self.entry1.config(state=NORMAL)
            self.radio1.config(state=NORMAL)
            self.radio2.config(state=NORMAL)
            self.opButton.config(state=NORMAL)
            if self.webcamdevices:
                self.recordcam.config(state=NORMAL)
                if self.rcchecked.get():
                    self.deviceselector.config(state=NORMAL)
            if self.what.get() == "title":
                self.entry2.config(state=NORMAL)

            available = False
            fileNum = 0

            # stop all recording processes
            self.recording = False
            self.proc.terminate()
            if self.rcchecked.get() and self.webcamdevices:
                self.webcamrecorder.stopCapture()
            try:
                os.mkdir("ScreenCaptures by Darsh Sharma")
            except FileExistsError:
                pass

            # change the window title and button text to reflect the current process
            self.title(
                string="Screen Recorder by Darsh Sharma (converting...)")
            self.startButton.config(
                text="converting your previous recording, please wait...",
                state=DISABLED)

            # start the video conversion process
            startupinfo = subprocess.STARTUPINFO()
            startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
            startupinfo.wShowWindow = subprocess.SW_HIDE
            self.cmdGen.config(audList=self.recorder.devices)
            command = self.cmdGen.getCvtCmd("ScreenCaptures by Darsh Sharma/" +
                                            self.filename)
            if not self.recorder.error:
                self.mergeProcess = subprocess.Popen(
                    args=command)  #,startupinfo=startupinfo)

            # if self.rcchecked.get():
            #     self.mergeProcess = subprocess.Popen(args= ["ffmpeg","-i",'tmp/tmp.mkv','-i','tmp/tmp.wav','-i','tmp/webcamtmp.mkv','-filter_complex','[2:v] scale=640:-1 [inner]; [0:0][inner] overlay=0:0 [out]',"-shortest",'-map','[out]','-y',"ScreenCaptures/"+self.filename])
            # else:
            #     self.mergeProcess = subprocess.Popen(args= ["ffmpeg","-i",'tmp/tmp.mkv','-i','tmp/tmp.wav',"-shortest",'-y',"ScreenCaptures/"+self.filename], startupinfo=startupinfo)

            # change the screen capture name to something that is not taken
            os.chdir("ScreenCaptures by Darsh Sharma")
            while True:
                matches = 0
                for item in os.listdir():
                    if item == defaultFile:
                        matches += 1
                if matches == 0:
                    self.entry1.delete(0, END)
                    self.entry1.insert(END, defaultFile)
                    break
                else:
                    fileNum += 1
                    file = self.filename.split(".")
                    defaultFile = file[0].rstrip("1234567890") + str(
                        fileNum) + "." + file[1]

            os.chdir("../")
Пример #5
0
    def update_table(self):
        '''
        Actualiza la información que se muestra en la
        tabla con lo actualizado de la base de datos.
        '''

        # Destruye todo los componentes que se encuentren en
        # marco principal (la tabla) para poder generarlos
        # nuevamente con la información actualizada.
        for c in self.root.winfo_children():
            c.destroy()

        self.viewer.hide()

        # Se obtiene la tabla completa de la base de datos
        data = self.viewer.get_all()["data"]
        names = self.viewer.get_all()["names"]

        # Se crea la primer fila que contiene los
        # nombres de las columnas
        frameNames = Frame(self.root)
        for name in names:
            # Se utiliza una operación ternaria (se utilizan varias
            # en la app, simplifican el código) para determinar si
            # es necesario aplicar un tamaño provisto de largo de columna
            e = Entry(frameNames,
                      width=self.columns_width[name] if self.columns_width
                      and name in self.columns_width else 20)
            e.insert(0, str(name).replace("_", " ").capitalize())
            e.config(state="readonly")
            e.pack(side="left")
        frameNames.pack(side="top", padx=(0, 75))

        frame = Frame(self.root)

        # Crea la tabla iterando sobre cada campo de
        # cada uno de los registros de la consulta.
        for item in data:
            row = Frame(frame)
            for field in dict(item):
                if self.btn and field == 'codigo':
                    btn_id = Button(row,
                                    text="Ver",
                                    command=lambda index=item[field]: self.
                                    viewer.show(index))
                    btn_id.pack(side="right")

                # Se utiliza un operador ternario para hacer más configurable
                # a la tabla, permitiendo modificar el tamaño de las columnas
                entry = Entry(
                    row,
                    width=self.columns_width[field] if self.columns_width
                    and field in self.columns_width else 20)
                entry.pack(side="left")
                entry.insert(0, str(item[field]))
                entry.config(state="readonly")

            if self.btn:
                row.pack(side="top")
            else:
                row.pack(side="top", padx=(0, 75))

        frame.pack()

        # Se fija el area de desplazamiento de la tabla en
        # base a la cantidad de filas que posea.
        height = (len(frame.winfo_children()) * 25) + 25
        self.canvas.config(scrollregion=(0, 0, 0, height))
Пример #6
0
class UnsplashUI(Frame):
    def __init__(self, master=None):
        super().__init__(master=master)
        self.master = master
        self.listUnsplashImage = []
        self.setupUI()

    def setupUI(self):
        self.label_name = Label(self, text='Query:')
        self.label_name.grid(row=0, column=0, sticky='w')

        self.label_amount = Label(self, text='Per page:')
        self.label_amount.grid(row=1, column=0, sticky='w')

        self.label_page_number = Label(self, text='Page:')
        self.label_page_number.grid(row=2, column=0, sticky='w')

        self.label_save = Label(self, text='Save:')
        self.label_save.grid(row=3, column=0, sticky='w')

        self.label_quality = Label(self, text='Quality:')
        self.label_quality.grid(row=4, column=0, sticky='w')

        self.label_order_by = Label(self, text='Order by:')
        self.label_order_by.grid(row=5, column=0, sticky='w')

        self.label_random = Label(self, text='Random:')
        self.label_random.grid(row=6, column=0, sticky='w')

        self.var_name = StringVar()
        self.entry_name = Entry(self, textvariable=self.var_name)
        self.entry_name.grid(row=0, column=1, sticky='we')

        self.var_amount = IntVar()
        self.var_amount.set(10)
        self.entry_amount = Entry(self, textvariable=self.var_amount)
        self.entry_amount.grid(row=1, column=1, sticky='we')

        self.var_page_number = IntVar()
        self.var_page_number.set(1)
        self.entry_page_number = Entry(self, textvariable=self.var_page_number)
        self.entry_page_number.grid(row=2, column=1, sticky='we')

        self.var_folder_name = StringVar()
        self.entry_save = Entry(self, textvariable=self.var_folder_name)
        self.entry_save.grid(row=3, column=1, sticky='we')

        self.button_browse = Button(self,
                                    text='Browse',
                                    command=self.choice_folder)
        self.button_browse.grid(row=3, column=2, sticky='we')

        QUALITIES = {
            'Raw': 'raw',
            'Full': 'full',
            'Regular': 'regular',
            'Small': 'small',
            'Thumnail': 'thumb',
        }

        self.var_quality_rb = StringVar()
        group_quality_radiobutton = FrameGroupRadiobutton(
            self,
            side='left',
            variable=self.var_quality_rb,
            dict_option=QUALITIES,
            initialize='raw')
        group_quality_radiobutton.grid(row=4, column=1, sticky='w')

        ORDER_BY = {
            'Latest': 'latest',
            'Oldest': 'oldest',
            'Popular': 'popular',
        }

        self.var_order_by_rb = StringVar()
        self.group_order_by_radiobutton = FrameGroupRadiobutton(
            self,
            side='left',
            variable=self.var_order_by_rb,
            dict_option=ORDER_BY,
            initialize='latest')
        self.group_order_by_radiobutton.grid(row=5, column=1, sticky='w')

        self.var_random = IntVar()
        self.checkbutton_random = Checkbutton(self)
        self.checkbutton_random['variable'] = self.var_random
        self.checkbutton_random['command'] = self.disable_order_by_for_random
        self.checkbutton_random.grid(row=6, column=1, sticky='w')
        createToolTip(self.checkbutton_random, 'Max amount is 30')

        self.image_icon_download = PhotoImage(file='icon/down-arrow.png')
        self.button_download = Button(self)
        self.button_download['text'] = 'Download now!'
        self.button_download['image'] = self.image_icon_download
        self.button_download['compound'] = 'left'
        self.button_download['command'] = self.startDownload
        self.button_download.image = self.image_icon_download
        self.button_download.grid(row=7, column=1)

    def startDownload(self):
        # check folder
        if self.var_folder_name.get() == '':
            messagebox.showwarning('Thông báo', 'Bạn chưa chọn nơi lưu trữ!')
            return
        else:
            self.lock = threading.Lock()
            self.th_sendRequest = threading.Thread(
                target=self.getListUnsplashImages)
            self.th_sendRequest.start()

            logging.info('Initialize the Download UI')
            self.toplevel_info = Toplevel(self)
            self.toplevel_info.title('Downloading...')

            self.var_progress = StringVar()
            self.label_progress = Label(self.toplevel_info)
            self.label_progress['textvariable'] = self.var_progress
            self.label_progress.pack(fill='x')

            self.progress_bar = Progressbar(self.toplevel_info)
            self.progress_bar['length'] = 100
            self.progress_bar['orient'] = 'horizontal'
            self.progress_bar['mode'] = 'determinate'
            self.progress_bar['value'] = 0
            self.progress_bar.pack(fill='x')

            self.label_image = Label(self.toplevel_info)
            self.label_image.pack(fill='x')

            self.th_download = threading.Thread(target=self.download)
            self.th_download.start()

            self.toplevel_info.protocol('WM_DELETE_WINDOW',
                                        self.closeToplevelWidget)

    def download(self):
        self.lock.acquire()
        per = 0
        self.show = 1
        for image in self.listUnsplashImage:
            path = image.downloadThisImage(self.var_quality_rb.get(),
                                           self.var_folder_name.get())

            per = per + 100 / len(self.listUnsplashImage)
            self.var_progress.set('{}%'.format(int(per)))
            self.progress_bar['value'] = per

            self.image_downloaded = Image.open(path)
            self.image_complete = ImageTk.PhotoImage(self.image_downloaded)

            self.label_image['image'] = self.image_complete
            self.label_image.image = self.image_complete

            if self.show == 0:
                break

        # release data
        logging.info('show warning')
        messagebox.showinfo('Thông báo', 'Đã tải xong !')
        self.toplevel_info.destroy()
        self.listUnsplashImage = []

        self.lock.release()

    def disable_order_by_for_random(self):
        if self.var_random.get() == 1:
            self.label_order_by.config(state='disable')
            self.label_name.config(state='disable')
            self.entry_name.config(state='disable')
            self.label_page_number.config(state='disable')
            self.entry_page_number.config(state='disable')
            for child in self.group_order_by_radiobutton.winfo_children():
                child.config(state='disable')
        else:
            self.label_order_by.config(state='normal')
            self.label_name.config(state='normal')
            self.entry_name.config(state='normal')
            self.label_page_number.config(state='normal')
            self.entry_page_number.config(state='normal')
            for child in self.group_order_by_radiobutton.winfo_children():
                child.config(state='normal')

    def choice_folder(self):
        dialog_choice_folder = filedialog.askdirectory()
        self.var_folder_name.set(dialog_choice_folder)

    def getListUnsplashImages(self):
        '''Thực hiện gửi chọn và request, sau đó đưa data lấy về thành một list chứa UnsplashImage'''
        self.lock.acquire()
        if self.var_random.get() == 1:
            # call random request
            request = 'https://unsplash.com/napi/photos/random'
            params = {'count': self.var_amount.get()}
            r = requests.get(request, params=params)
            data = json.loads(r.text)
        elif self.var_name.get() == '':
            request = 'https://unsplash.com/napi/photos'
            params = params = {
                'page': self.var_page_number.get(),
                'per_page': self.var_amount.get()
            }
            r = requests.get(request, params=params)
            data = json.loads(r.text)
        else:
            # call searchPhoto request
            request = 'https://unsplash.com/napi/search/photos'
            params = {
                'query': self.var_name.get(),
                'page': self.var_page_number.get(),
                'per_page': self.var_amount.get()
            }
            r = requests.get(request, params=params)
            data = json.loads(r.text)
            data = data['results']

        for i in data:
            img = UnsplashImage(i)
            self.listUnsplashImage.append(img)

        self.lock.release()

    def closeToplevelWidget(self):
        self.show = 0
Пример #7
0
frame2 = Frame(window)
frame2.pack(fill="both")

tablayout = Notebook(frame2)

#tab1
tab1 = Frame(tablayout)
tab1.pack(fill="both")

#input box Table
for row in range(5):
    for column in range(6):
        if row == 0:
            label = Entry(tab1, text="Heading : " + str(column))
            label.config(font=('Arial', 14))
            label.grid(row=row, column=column, sticky="nsew", padx=1, pady=1)
            tab1.grid_columnconfigure(column, weight=1)
        else:
            label = Entry(tab1,
                          text="Row : " + str(row) + " , Column : " +
                          str(column))
            label.grid(row=row, column=column, sticky="nsew", padx=1, pady=1)
            tab1.grid_columnconfigure(column, weight=1)

tablayout.add(tab1, text="TAB 1")

#tab2
tab1 = Frame(tablayout)
tab1.pack(fill="both")
class Application(Frame):
    """Main class, handles GUI and starts logic"""
    def __init__(self, master=None, arguments=()):
        super().__init__(master)

        self._file_path = ""
        self._output_dir = ""
        self._same_dir = IntVar(value=1)        # By default output path is the same as file path
        self._show_password = False
        self._db_type = IntVar(value=self.DB_TYPE_MARIADB())

        self._master = master
        self.grid()
        try:
            self._create_widgets()
        except Exception as ex:
            messagebox.showerror("Error", ex.args[0])

        self._same_dir_as_file()        # Disable output button and it sets output dir at start
        self._convert_progressbar.grid_remove()        # Hide loading bar at start

        if self._is_file_path_in_arguments(arguments):
            self._set_file_path(arguments[1])

    def _is_file_path_in_arguments(self, arguments):
        """Method to check if arguments[1] (because arguments[0] is application
        path) is a file path
        """
        if arguments.__len__() > 1:
            file_path = arguments[1]
            if path.isfile(file_path):
                extension = path.splitext(file_path)[1]
                if extension == ".mdb" or extension == ".accdb":
                    return True
        return False

    def _create_widgets(self):
        """GUI building"""
        # File widgets
        self._filename_label = Label(self._master, width="22", anchor="e", text="Access File (*.mdb, *.accdb):")
        self._filename_label.grid(row=0, column=0)

        self._filename_path_label = Label(self._master, width="50", anchor="w", textvariable=self._file_path, bg="#cccccc")
        self._filename_path_label.grid(row=0, column=1)

        self._browse_file_button = Button(self._master, text="...", width="3", command=self._browse_file)
        self._browse_file_button.grid(row=0, column=2)

        # Password widget
        self._password_label = Label(self._master, width="22", anchor="e", text="Password (else leave empty):")
        self._password_label.grid(row=1, column=0)

        self._password_entry = Entry(self._master, width="58", show="*")
        self._password_entry.grid(row=1, column=1)

        self._password_show_image = PhotoImage(file=path.join(module_dir, "images\\watch_pwd.png")).subsample(8, 8)
        self._password_show_button = Button(self._master, width="3", command=self._show_hide_password, image=self._password_show_image)
        self._password_show_button.grid(row=1, column=2)

        # Checkbox widget
        self._same_dir_as_file_checkbox = Checkbutton(self._master, width="50", text="Same directory as source file", var=self._same_dir, command=self._same_dir_as_file)
        self._same_dir_as_file_checkbox.grid(row=2, column=1, pady=8)

        # Output widgets
        self._output_label = Label(self._master, width="22", anchor="e", text="Output directory:")
        self._output_label.grid(row=3, column=0)

        self._output_dir_label = Label(self._master, width="50", anchor="w", textvariable=self._file_path,
                                       bg="#cccccc")
        self._output_dir_label.grid(row=3, column=1)

        self._browse_dir_button = Button(self._master, text="...", width="3", command=self._browse_dir)
        self._browse_dir_button.grid(row=3, column=2)

        # Radio buttons for PostgreSQL or MySQL/MariaDB
        self._db_type_label = Label(self._master, width="22", anchor="e", text="Database type:")
        self._db_type_label.grid(row=4, column=0)

        self._db_type_frame = Frame(self._master)
        self._db_type_frame.grid(row=4, column=1, columnspan=2, pady=5)

        self._radio_button_postgres = Radiobutton(self._db_type_frame, text="PostgreSQL", var=self._db_type, value=self.DB_TYPE_POSTGRESQL(), width="13")
        self._radio_button_postgres.grid(row=0, column=0)

        self._radio_button_mariadb = Radiobutton(self._db_type_frame, text="MariaDB", var=self._db_type, value=self.DB_TYPE_MARIADB(), width="13")
        self._radio_button_mariadb.grid(row=0, column=1)

        self._radio_button_mysql = Radiobutton(self._db_type_frame, text="MySQL", var=self._db_type, value=self.DB_TYPE_MYSQL(), width="13")
        self._radio_button_mysql.grid(row=0, column=2)

        # Convert widget & progressbar
        self._convert_frame = Frame(self._master)
        self._convert_frame.grid(row=5, column=0, columnspan=2, pady=5)

        self._convert_button = Button(self._convert_frame, width="84", text="CREATE SQL FILE", command=self.convertSQL, state="disabled")
        self._convert_button.grid(row=0, column=0)

        self._convert_progressbar = Progressbar(self._convert_frame, length="512")
        self._convert_progressbar.grid(row=1, column=0)

    def convertSQL(self):
        """SQL file generator"""
        self._convert_progressbar.grid(row=1, column=0)        # Show progressbar
        self._convert_progressbar["value"] = 0
        self._master.config(cursor="wait")
        accessconnector = Accessconnector()
        try:
            driver = accessconnector.driver(self._file_path)
            con = accessconnector.con(driver, self._file_path, self._get_password())
            self._convert_progressbar["value"] = 33
        except (AccessConnectionError, ODBCDriverNotFoundError) as ex:
            self._master.config(cursor="")
            self._convert_progressbar["value"] = 100
            messagebox.showerror("Error", ex)
        else:
            cur = con.cursor()
            database_name = StringDialog.ask_string(title_="Database name", prompt="Name for database:")
            if database_name is not None:
                if database_name == "":
                    messagebox.showinfo("Error", "Database name field cannot be blank")
                else:
                    self._convert_progressbar["value"] = 66
                    accesshandler = Accesshandler(cur)
                    accesshandler.make_file(self._output_dir, database_name, self._db_type.get())
                    messagebox.showinfo("Completed", "SQL file generated successfully")
            cur.close()
            con.close()
            self._master.config(cursor="")
            self._convert_progressbar["value"] = 100

    def _set_file_path(self, file_path):
        """Setter for file path, updates file path label and output dir based on _same_dir"""
        self._file_path = file_path
        self._filename_path_label.config(text=self._file_path)
        if self._is_same_dir() == 1:
            self._set_output_dir(path.dirname(self._file_path))
        if self._file_path != "" and self._output_dir != "":        # Enable convert button if it´s good to go
            self._convert_button.config(state="normal")
        self._update_gui_size()

    def _set_output_dir(self, output_dir):
        """Setter for output dir"""
        self._output_dir = output_dir
        self._output_dir_label.config(text=self._output_dir)
        if self._file_path != "" and self._output_dir != "":        # Enable convert button if it´s good to go
            self._convert_button.config(state="normal")
        self._update_gui_size()

    def _update_gui_size(self):
        """Method for expanding or shrinking GUI based on the length of the paths"""
        min_size = 50        # Standard min-size on creating GUI for _filename_path_label ...
        size = max(self._file_path.__len__(), self._output_dir.__len__())
        if size > min_size:
            self._filename_path_label.config(width=size)
            self._output_dir_label.config(width=size)
            self._same_dir_as_file_checkbox.config(width=size)
            self._password_entry.config(width=int((size * 58) / min_size))
            self._convert_button.config(width=int((size * 84) / min_size))
            self._convert_progressbar.config(length=int((size * 512) / min_size))
        elif size <= min_size:
            self._filename_path_label.config(width=50)
            self._output_dir_label.config(width=50)
            self._same_dir_as_file_checkbox.config(width=50)
            self._password_entry.config(width=58)
            self._convert_button.config(width=84)
            self._convert_progressbar.config(length=512)

    def _same_dir_as_file(self):
        """Functionality for disabling or enabling browse output dir button
        and setting _output_dir based on _file_path
        """
        if self._is_same_dir() == 1:
            self._set_output_dir(path.dirname(self._file_path))
            self._browse_dir_button.config(state="disabled")
        else:
            self._browse_dir_button.config(state="normal")

    def _show_hide_password(self):
        """Show/Hide password by current _show_password value and updates it"""
        if self._show_password:
            self._password_entry.config(show="*")
            try:
                self._password_show_image = PhotoImage(file=path.join(module_dir, "images\\watch_pwd.png")).subsample(8, 8)
            except Exception as ex:
                messagebox.showerror("Error", ex)
        else:
            self._password_entry.config(show="")
            try:
                self._password_show_image = PhotoImage(file=path.join(module_dir, "images\\hide_pwd.png")).subsample(8, 8)
            except Exception as ex:
                messagebox.showerror("Error", ex)
        self._password_show_button.config(image=self._password_show_image)
        self._show_password = not self._show_password

    def _browse_file(self):
        """Browse file functionality"""
        file_path = askopenfilename(filetypes=[("Microsoft Access", ".mdb .accdb")])
        if file_path != "":        # If browse window is closed then don´t update
            self._set_file_path(file_path)

    def _browse_dir(self):
        """Browse dir functionality"""
        output_dir = askdirectory()
        if output_dir != "":        # If browse window is closed then don´t update
            self._set_output_dir(output_dir)

    def _get_password(self):
        """Getter for password"""
        return self._password_entry.get()

    def _is_same_dir(self):
        """Getter for _same_dir"""
        return self._same_dir.get()

    @staticmethod
    def DB_TYPE_POSTGRESQL():
        """POSTGRESQL constant"""
        return 1

    @staticmethod
    def DB_TYPE_MARIADB():
        """MARIADB constant"""
        return 2

    @staticmethod
    def DB_TYPE_MYSQL():
        """MYSQL constant"""
        return 3