Python Forum
[Tkinter] How to do this with Tkinter?
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[Tkinter] How to do this with Tkinter?
#1
Hello,

I have a window created with Tkinter (see screenshot attached), but I am having issues after this one is created, specially with window.mainloop() because it does not execute my python code; the idea is to do this:

1. Show Folder processing image on the window and run the script I have for this, which is a loop that goes through arrays.
2. Once completed (1), it will do a process with Selenium and download files from the web.
3. Completed (2), it will do the data moving to specific folders
4. Show the process complete once is done.

But as mentioned before, the window.mainloop() is preventing from executing the rest of my code.
I know that exists the Thread, but if I understood properly, it would run my array function, but because of the window.mainloop() appears below, it will not show the progress as explained on items from 1 to 4.

import threading
import tkinter as tk

def my_function_arrays():
   #execute the code

def show_window():
   windows = tk.Tk()
   thread = theading.Thread(target = my_function_arrays)
   thread.start()

   window.mainloop()

show_window()
How to do this?

Attached Files

Thumbnail(s)
   
Reply
#2
As is, your program does nothing. Can you post some code that does something and then describe how the program behavior differs from what you want? You should avoid using threads until you have a program that does what you want. If the program is laggy, you can then think about using threads or maybe something else.
Reply
#3
(Dec-12-2023, 09:04 PM)deanhystad Wrote: As is, your program does nothing. Can you post some code that does something and then describe how the program behavior differs from what you want? You should avoid using threads until you have a program that does what you want. If the program is laggy, you can then think about using threads or maybe something else.

Thank you for your reply.

This is all my code:

import tkinter as tk
import selenium 
import os
import shutil
import getpass
import requests



from tkinter import filedialog
from time import sleep
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import Select
from selenium.webdriver.edge.service import Service as EdgeService
from bs4 import BeautifulSoup
from requests.adapters import HTTPAdapter
import tqdm
from urllib3.util.retry import Retry
from icecream import ic

#para borrar despues
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import tkinter as tk
from tkinter import ttk
from PIL import Image, ImageTk


def open_path():
    """
    This part of the code reads the location of the folder where the PDFs files are 
    located at
    """
    root = tk.Tk()
    root.withdraw()

    file_path = filedialog.askdirectory()
    files_in_folder = os.listdir(file_path) #List all the files from the folder
    pdf_files = [archivo for archivo in files_in_folder if archivo.lower().endswith(".pdf")] #look for all the pdf files inside the folder

    array_pdf_files = []
    if pdf_files:
        #remove_extension = [nombre.replace("_INV.pdf", "") for nombre in archivo]
        for archivo in pdf_files:
            #portion_name = archivo[2:]
            #final_portion_name = os.path.splitext(portion_name)[0]
            final_portion_name = archivo.replace("_INV.pdf", "")
            print(final_portion_name)
            array_pdf_files.append(final_portion_name)
             
    
    return array_pdf_files, file_path

def move_files(tf, fp, df):
    for index_row, row in enumerate(tf):
        destiny = fp + "/" + tf[index_row][0]
        for index_col, col in enumerate(row[1:],start=1):
            source = df + "/" + tf[index_row][index_col]
            if not os.path.exists(destiny + "/" + tf[index_row][index_col]):                               
                    shutil.move(source , destiny)


def goCheck(rpf, fp):

    transfiles = []
    options = webdriver.EdgeOptions()
    #options.add_experimental_option("detach", True)

    
    
    prefs = {
            "download.default_directory": "C:\\FO\\FO\\",  # Replace with your desired download directory
            "download.prompt_for_download": False,
            "download.directory_upgrade": True,
            "safebrowsing.enabled": False,
            "plugins.always_open_pdf_externally": True  # This option is specific to PDFs
            }
    driver = webdriver.Edge(service=EdgeService(), options=options)
    #edge_options.add_experimental_option("prefs", prefs)
    options.add_experimental_option("prefs", prefs)
    driver.get('https://eview.com/')
    driver.switch_to.window(driver.window_handles[-1])
    driver.maximize_window()
    sleep(20)
    driver.switch_to.frame('topFrame')
    
    
    for j in range(0, len(rpf)):
        driver.switch_to.parent_frame()
        driver.switch_to.parent_frame()
        driver.switch_to.frame(0)
        driver.find_element(By.XPATH, "//input[@name='DocNumber']").click()
        driver.find_element(By.XPATH, "//input[@name='DocNumber']").clear()
        driver.find_element(By.XPATH, "//input[@name='DocNumber']").send_keys(rpf[j])
        driver.find_element(By.XPATH, "//input[@name='Search']").click()
        sleep(10)
        #driver.find_element(By.XPATH, "//input[@name='Search']").click()
        driver.switch_to.parent_frame()
        driver.switch_to.frame(1)
        driver.switch_to.frame(1)
        if driver.find_element(By.XPATH, "/html[1]/body[1]/div[1]/div[1]/div[1]/div[1]/form[1]/table[1]/tbody[1]/tr[2]/td[1]/table[1]").text == "  No Records Found. Click the 'Load Archive Data' button below to search older documents.  ":
            continue
        else:
            print(driver.find_element(By.XPATH, "/html[1]/body[1]/div[1]/div[1]/div[1]/div[1]/form[1]/table[1]/tbody[1]/tr[2]/td[1]/table[1]").text)
            ic(driver.find_element(By.XPATH, "/html[1]/body[1]/div[1]/div[1]/div[1]/div[1]/form[1]/table[1]/tbody[1]/tr[2]/td[1]/table[1]").text)
        
            driver.find_element(By.XPATH, "/html[1]/body[1]/div[1]/div[1]/div[1]/div[1]/form[1]/table[1]/tbody[1]/tr[3]/td[3]/a[1]").click()
            
            driver.switch_to.parent_frame()
            driver.switch_to.frame(0)
            
            #Clicks on Attachment tab
            driver.find_element(By.XPATH, "/html[1]/body[1]/table[1]/tbody[1]/tr[2]/td[2]/table[1]/tbody[1]/tr[1]/td[3]").click()
            driver.switch_to.parent_frame()
            driver.switch_to.frame(1)
            
            #Go through the table and download all the files
            #original_window_handle = driver.current_window_handle
            table_id = '/html[1]/body[1]/div[1]/div[1]/div[1]/table[1]' #"//body/div[@id='contents']/div[@id='main']/div/table[1]"
            table = driver.find_element(By.XPATH, table_id)
            body = table.find_element(By.TAG_NAME, 'tbody')
            rows = table.find_elements(By.TAG_NAME, "tr")

            k = 0
            i = 0
            

            main_window = driver.window_handles[0]

            #EXTRACT THE INFORMATION OF THE TABLE TO LATER BE TRANSFERRED TO A FOLDER
            column_index = 2
            column_values = []
            row_data = []
            folder_2_create = fp + "/" + rpf[j]
            column_values.append(rpf[j])
            os.makedirs(folder_2_create, exist_ok=True)
            
            
            input_elements = driver.find_elements(By.CSS_SELECTOR, 'input[name="FileName"]')
            for input_element in input_elements:
                input_value = input_element.get_attribute('value')
                if ".xml" in input_value:
                    continue
                else:
                    column_values.append(input_value)
                    ic(input_value)
            transfiles.append(column_values)
            ic(transfiles)        

            #DOWNLOAD ALL THE FILES FROM THE LINKS AT ONCE
            driver.execute_script('''
                var buttons = document.querySelectorAll(".download");
                for (var i = 0; i < buttons.length; i++){
                    buttons[i].click();
                }
                                    ''')
            
            #EXTRACT THE INFORMATION OF THE TABLE TO LATER BE TRANSFERRED TO A FOLDER
            #LOOK FOR INVOICEBULKERV4.PY FOR THIS PART
            
            #================================================================
            sleep(17)
            driver.quit()
            options = webdriver.EdgeOptions()
        #options.add_experimental_option("detach", True)

        
        
            prefs = {
                    "download.default_directory": "C:\\FO\\FO\\",  # Replace with your desired download directory
                    "download.prompt_for_download": False,
                    "download.directory_upgrade": True,
                    "safebrowsing.enabled": False,
                    "plugins.always_open_pdf_externally": True  # This option is specific to PDFs
                    }
            driver = webdriver.Edge(service=EdgeService(), options=options)
            options.add_experimental_option("prefs", prefs)
            driver.get('https://eview.com/')
            driver.switch_to.window(driver.window_handles[-1])
            driver.maximize_window()
            sleep(20)
            driver.switch_to.frame('topFrame')
    print(transfiles)
    ic(transfiles)
    move_files(transfiles, fp, downloads_folder)

username = getpass.getuser()    
downloads_folder = "C:/Users/" + username + "/Downloads"

#==============================================================================================================
# Set the width and height for the iPhone 14 screen (adjust as needed)
iphone_width = 300
iphone_height = 500

# Create the main window
window = tk.Tk()
window.title("Invoice Processor")

# Set the window size
window.geometry(f"{iphone_width}x{iphone_height}")
window.config(bg='White')

image = Image.open("Images/Logo.png")
image = ImageTk.PhotoImage(image)
image_label = tk.Label(window, image=image, borderwidth=0)
image_label.place(x=20, y=440)



#========================================================================
image2 = Image.open("Images/Folder_Logo.png")
resimage = image2.resize((32,29))
image2 = ImageTk.PhotoImage(resimage)
image_folder = tk.Label(window, image=image2, borderwidth=0)
image_folder.place(x=60, y=200)

progess_text = tk.Label(window, text="Folder Processing", font=("Arial", 9, "bold"), bg="white")
progess_text.place(x=100, y=205)
progressbar = ttk.Progressbar()
progressbar.place(x=40, y=230, width=210)
progressbar.destroy()
'''
#========================================================================
image3 = Image.open("Images/Download_Logo.png")
resimage_download = image3.resize((27,30))
image3 = ImageTk.PhotoImage(resimage_download)
image_download = tk.Label(window, image=image3, borderwidth=0)
image_download.place(x=62, y=240)

download_text = tk.Label(window, text="Downloading the files", font=("Arial", 9, "bold"), bg="white")
download_text.place(x=100, y=245)
#========================================================================
image4 = Image.open("Images/Moving_Logo.png")
resimage_moving= image4.resize((28,24))
image4 = ImageTk.PhotoImage(resimage_moving)
image_moving = tk.Label(window, image=image4, borderwidth=0)
image_moving.place(x=62, y=285)

moving_text = tk.Label(window, text="Moving the files", font=("Arial", 9, "bold"), bg="white")
moving_text.place(x=100, y=290)
#========================================================================
image5 = Image.open("Images/Complete_Logo.png")
resimage_complete = image5.resize((25,31))
image5 = ImageTk.PhotoImage(resimage_complete)
image_complete = tk.Label(window, image=image5, borderwidth=0)
image_complete.place(x=62, y=330)

complete_text = tk.Label(window, text="Process completed", font=("Arial", 9, "bold"), bg="white")
complete_text.place(x=100, y=335)
#========================================================================
'''
canvas = tk.Canvas(window, width=300, height=70, bg="#0014DC")
canvas.pack()

rectangle = canvas.create_rectangle(0, 0, 300, 70, fill="#0014DC")  # Set the rectangle coordinates and fill color
welcome_text = canvas.create_text(75, 50, text="Welcome", fill="white", font=("Sans", 20))

additional_text = tk.Label(window, text="This application will help you\n"
                                    "to automatize the file download\n"
                                    "process in bulk.", font=("Arial", 11), bg="white")
additional_text.place(x=45, y=100)

# Run the Tkinter event loop
window.mainloop()
#==============================================================================================================

result_pdf_files, file_path = open_path()
goCheck(result_pdf_files, file_path)
print(result_pdf_files) 
Keep in mind that the URL: eview.com can be only accessed in our intranet. And I commented all the images and text from the window, while I figure out how to execute the rest of the code.


Thanks again for your support.
Reply
#4
This kinda a poor example but, maybe something like this with threading.
import tkinter as tk 
from os.path import dirname, realpath
import os
from PIL import Image, ImageTk
from time import sleep
from threading import Thread

path = f'{realpath(dirname(__file__))}/images'


def change_text(container, labels):
    row = 2
    for label in labels:
        sleep(2)
        label = tk.Label(container, text='Complete', bg='white', fg='green')
        label.grid(column=1, row=row, sticky='new', padx=8, pady=(20,8))
        row += 1
       

def timer(container, labels):
    athread = Thread(target=change_text, args=(container, labels,))
    athread.start()

class Window:
    def __init__(self, parent):
        parent.columnconfigure(0, weight=1)
        parent.rowconfigure(0, weight=1)

        container = tk.Frame(parent, bg='white')
        container.grid(column=0, row=0, sticky='news')       

        img_list = os.listdir(path)

        label = tk.Label(container, text='Welcome', fg='white', bg='blue')
        label['font'] = ("SLB Sans", 20, 'bold')
        label.grid(column=0,columnspan=2, row=0, sticky='new')

        label = tk.Label(container, anchor='w', wraplength=180, bg='white')
        label['text'] = '''This application will help you to automatize the file download process in bulk.'''
        label.grid(column=0, columnspan=2, row=1, sticky='new', padx=10, pady=20)

        index = 0
        label = []
        labels = ['Folder Processing', 'Downloading Files', 'Moving Files', 'Process']
        row = 2
        for img in ('0.png', '2.png', '3.png', '4.png'):
            with Image.open(f'{path}/{img}') as im:
                resized = im.resize((40,40))
            icon = ImageTk.PhotoImage(resized)
            icon.bak = icon

            label.append(tk.Label(container, bg='white', fg='blue', text=f' {labels[index]}', image=icon, compound='left', anchor='w'))
            label[index].grid(column=0, row=row, sticky='new', padx=8, pady=8)
            row += 1
            index += 1

        btn = tk.Button(container, text='Submit')
        btn['command'] = lambda: timer(container, labels)
        btn.grid(column=0, columnspan=2, row=len(labels)+4, sticky='new')
       


root = tk.Tk()
root['padx'] = 8
root['pady'] = 8
root['bg'] = 'white'
Window(root)
root.mainloop()
I welcome all feedback.
The only dumb question, is one that doesn't get asked.
My Github
How to post code using bbtags


Reply
#5
Why are you using a Canvas? There is nothing in your program that requires Canvas, and everything you are doing is easier to do if you don't use a canvas.

Why are you making this a GUI? There is nothing here for the user it interact with. Where are your controls? This program should be a script. You can have a really fancy CLI for a script.

https://codeburst.io/building-beautiful-...c7e1bb54df

If you want to continue with tkinter, you need to add some controls to your window. For your first pass, put this code in a function.
result_pdf_files, file_path = open_path()
goCheck(result_pdf_files, file_path)
print(result_pdf_files)
Add a button to your root window and have the button call your function when pressed.
Reply
#6
Why do you create a progressbar and then immediately call progressbar.destroy() ?

If you need to update the gui from within a thread, I created a small module to do just that, managetkeventdata
« We can solve any problem by introducing an extra level of indirection »
Reply
#7
Use of threads should be avoided until you have a software that does the required task. If the program is sluggish, you may then think about using threads or perhaps something different pico park
Reply
#8
(Dec-12-2023, 10:11 PM)deanhystad Wrote: Why are you using a Canvas? There is nothing in your program that requires Canvas, and everything you are doing is easier to do if you don't use a canvas.

Why are you making this a GUI? There is nothing here for the user it interact with. Where are your controls? This program should be a script. You can have a really fancy CLI for a script.

https://codeburst.io/building-beautiful-...c7e1bb54df

If you want to continue with tkinter, you need to add some controls to your window. For your first pass, put this code in a function.
result_pdf_files, file_path = open_path()
goCheck(result_pdf_files, file_path)
print(result_pdf_files)
Add a button to your root window and have the button call your function when pressed.


Why are you making this a GUI?
The idea is to show something and to make it nicely visible rather than a plane command window.
Reply
#9
(Dec-13-2023, 05:52 AM)Gribouillis Wrote: Why do you create a progressbar and then immediately call progressbar.destroy() ?

If you need to update the gui from within a thread, I created a small module to do just that, managetkeventdata


This was just testing.
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020