Hengen Asdwdrasd
Hengen Asdwdrasd

Reputation: 55

Using tkinder and selenium in python (not responding)

I have a project. I want to use tkinter and selenium. I'm telling a button to enter "https://stackoverflow.com" When I click it it opens but tkinter freezes. How do I get around this?

I am using the code on this site

import tkinter as tk
from selenium import webdriver

# --- functions ---

def on_open():
    global driver

    if not driver:
        driver = webdriver.Chrome()
        url = e.get()
        driver.get(url)

def on_close():
    global driver

    if driver:
        driver.close()
        driver = None

# --- main ---

driver = None

root  = tk.Tk()

e = tk.Entry(root)
e.pack()
e.insert('end', 'https://stackoverflow.com')

b = tk.Button(root, text='Selenium Open', command=on_open)
b.pack()

b = tk.Button(root, text='Selenium Close', command=on_close)
b.pack()

root.mainloop()

Upvotes: 1

Views: 393

Answers (2)

PDHide
PDHide

Reputation: 19979

import threading
from selenium import webdriver
import tkinter as tk

def on_open():
    global thread_lock
    global driver
    global thread
    
    #we use thread_lock to ensure clicking the start button too many times doesn't open many chromedriver instance
    #as soon as the code reaches inside this for loop , the thread_lock flag will be set preventing more chromedriver instance creation
    #Next chrome driver can be created only after clicking close
    if not driver and not thread_lock:
        thread_lock = True
        options = webdriver.ChromeOptions()
        options.page_load_strategy = 'none'
        options.add_argument("--window-position=500,500")
        driver = webdriver.Chrome(options=options)
        url = e.get()
        driver.get(url)
        


def on_close():
    global driver
    global thread
    global thread_lock

    #A this flag allows next driver to be created
    thread_lock = False
    thread.__stop = True
    if driver:
        driver.quit()
        driver = None


# --- main ---

driver = None

root = tk.Tk()

thread_lock = False

e = tk.Entry(root)
e.pack()
e.insert('end', 'https://stackoverflow.com')

thread = None

# you have to create new thread for each click , so wrapping it with a function
def start():
    global thread
    thread = threading.Thread(
    target=on_open, daemon=True)
    thread.start()


def kill():
    global thread
    thread = threading.Thread(
        target=on_close, daemon=True)
    thread.start()

b = tk.Button(root, text='Selenium Open', command=start)
b.pack()
    
b = tk.Button(root, text='Selenium Close', command=kill)
b.pack()

root.mainloop()

see the code comments

Upvotes: 2

Tim Roberts
Tim Roberts

Reputation: 54743

The UI will be frozen until driver.get(url) returns. If the fetch takes a long time, your UI will be frozen for a long time. The way around this is to spin that fetch off into a thread, which allows the on_open function to get back to the event loop.

import threading

def on_open():
    global driver
    if not driver:
        driver = webdriver.Chrome()
        url = e.get()
        threading.Thread(target=driver.get, args=(url,), daemon=True)

EDIT -- Another one to try.

import threading

def open_chrome( url ):
    global driver
    driver = webdriver.Chrome()
    driver.get( url )

def on_open():
    if not driver:
        threading.Thread(target=open_chrome, args=(e.get(),), daemon=True)

This might not be the complete answer, either. If "webdriver.Chrome" is actually Python code, then there's nothing you can do. Python only allows one thread at a time to be running Python code. Until that function either waits for something or goes into a C module, the interpreter is tied up.

Upvotes: 3

Related Questions