For applications using Tkinter and Selenium, press Start to launch Chrome, press Start to launch
input('>If you type something, you'll see the text of the p element on the console')
Wait for to get the p element until works and presses Enter on the console.
Next
input('>Enter something to display text for h2 elements on the console')
will also wait for the h2 element to be retrieved.
"I would like to make ""Press Enter key on console"" correspond to ""Press Next Button"" and wait for the next action until the next button is pressed." How should I implement it?
The reason I want to stop processing is to visually check the output one by one and then proceed to the next.
At present, next() does not do anything, but when I press the next button, next() works and I want to proceed to the next process.
処理 I don't want to prevent the window from closing after processing.
Please let me know.
import ctypes
import tkinter as tk
import tkinter.ttk as ttk
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.chrome.options import Options
try:
ctypes.windll.shcore.SetProcessDpiAwareness (True)
exceptBaseException:
pass
def next():
pass
def start():
global driver
chrome_options=Options()
chrome_options.add_experimental_option("detach", True)
driver = webdriver.Chrome(
service=Service(ChromeDriverManager().install()) ,
options=chrome_options
)
driver.get('https://scrape-b276b.web.app/')
input ('> type something and the p element text will be displayed on the console')
print(driver.find_element(by.CSS_SELECTOR, '#app>div>main>div>div>div>div>section>div.text>p')
input('> type something and the h2 element text will be displayed on the console')
print(driver.find_element(By.CSS_SELECTOR, 'h2').text)
input('>Enter something and exit')
defmain():
frame = tk.Tk()
frame.title('title')
frame.geometry("230x60+400+440")
button1=ttk.Button(frame, text='Next', command=next)
button1.place(x=10,y=10,width=100)
button2=ttk.Button(frame, text='start', command=start)
button2.place (x=120, y=10, width=100)
frame.mainloop()
if__name__=='__main__':
main()
"How to wait for the next action until the Tkinter button is pressed" is a basic feature of Tkinter and is not something to be added later on the user-created program.
The question program starts with the execution of the line frame.mainloop()
and waits for an event such as a button or other widget mouse keyboard while it is running, and invokes the action if the corresponding event exists by default or is registered from the user program.
There is an explanation in this article.
[Python] Explanation of mainloop on tkinter
Therefore, "def start():
in the function def start():
and wait for the button to click to proceed" in a program similar to the question is bad behavior from a GUI point of view, and there is no point in using Tkinter.
From a GUI perspective, as shown in the answers to the previous question and the comments on this question, you should do the following:
def start():
The function only displays sitesIf you still want to do just one button, you can prepare a variable to indicate how far you have done the processing, and then change the processing by determining the variable as follows.
Show only the parts you want to change and omit the front and back.
import traceback
phase=-1#### Variable to save processing stage: -1 is browser not started
def next():
global phase####Declaration using global variables
#### Each of the following processes is performed according to the value of the variable that stores the processing stage, and the variable is moved to the next stage.
try:
if phase == 0:
print('The first 'Next' was clicked, so the p element text is displayed on the console')
print(driver.find_element(by.CSS_SELECTOR, '#app>div>main>div>div>div>div>section>div.text>p')
phase+=1#### variable to the next level
elif phase==1:
print('The second 'Next' was clicked, so the h2 element text is displayed on the console')
print(driver.find_element(By.CSS_SELECTOR, 'h2').text)
phase+=1#### variable to the next level
elif phase==2:
print('Close browser as 3rd 'Next' was clicked')
phase=-1#### variable to pre-browser startup stage
driver.quit()
except Exception as:
print({e.__class__.__name_}Exception Occurs in f'{phase} Step Process')
print(traceback.format_exc())
phase+=1#### variable to the next level
if phase>2:
phase=-1#### The range is over, so move the variable to the pre-browser startup stage
pass
def start():
global driver
global phase####Declaration using global variables
chrome_options=Options()
chrome_options.add_experimental_option("detach", True)
driver = webdriver.Chrome(
service=Service(ChromeDriverManager().install()) ,
options=chrome_options
)
driver.get('https://scrape-b276b.web.app/')
print('Browser launched, site displayed, ready')
phase=0#### Set the variable to the first step
The request to "wait until the button is pressed before proceeding to the next step" indicates the difficulty of an event-driven program.
That's right.
wait_variable
Cubick's comment explains how to use the wait
series of tkinter
features in links to.I don't know much about it, but there may be many situations where there is no problem.However, when this feature is invoked, it appears to be a bit complicated (such as "local event loop" being created or something), and there are problems such as not being able to exit the program while wait
.I have the impression that it is a kind of hack to the event loop, and that it cannot be used without understanding it at the Tcl/Tk level.
If you exclude the Tck/Tk specific features above, there are two possible solutions.
This answer deals with the former.
Kunif's answer is to calculate what to do with each callback function.I think this is simple and easy to understand.
There is another way to explicitly treat "next action" as a function.This is a bit complicated, but I think it's a way to think about future and promote, so I'll explain it to you.
That's the flow.
If you write this honestly, the code will look like the one below.
def start(root, next_button):
# ...
defproc_01():
print('--Process 1--')
# Change to a callback function (command) that:
next_button.configure(command=proc_02)
defproc_02():
print('--Process 2--')
# Change to a callback function (command) that:
next_button.configure(command=proc_03)
defproc_03():
print('--exit--')
root.quit()
# Set the first callback function (command)
next_button.configure(command=proc_01)
print('--start--')
Python provides iterator as a way to handle the following actions (values):There is also a generator that can be used instead of the complicated code above.
def start(root, next_button):
# ...
def proc_gen():
print('--Process 1--')
yield
print('--Process 2--')
yield
print('--exit--')
root.quit()
yield
# Generate iterators
# Every time `proc_itr` is `next`, proceed to the next field.
proc_itr=proc_gen()
# Callback (command) is set to invoke `next`
next_button.configure(command=lambda:next(proc_itr))
print('--start--')
The syntax sugar coating for these "next actions" is given to event-driven processes such as async/away syntax.Eventually, the GUI toolkit may be better combined.
Moving Code:
This code has been verified to work.In order to move it by hand, I have changed the content of the process from the question.next
is Python's built-in function.I avoid overwriting it with my own functions.
import tkinter ask
import tkinter.ttk as ttk
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.chrome.options import Options
url='https://google.com/'
def start (root, next_button):
chrome_options=Options()
chrome_options.add_experimental_option("detach", True)
driver = webdriver.Chrome(
service=Service(ChromeDriverManager().install()) ,
options=chrome_options
)
driver.get(url)
def proc_gen():
print('--div Element--')
print(driver.find_element(By.CSS_SELECTOR, 'div').text)
yield
print('--a element--')
print(driver.find_element(By.CSS_SELECTOR, 'a').text)
yield
print('--exit--')
root.quit()
yield
# Generate iterators
# Every time `proc_itr` is `next`, proceed to the next field.
proc_itr=proc_gen()
# Callback (command) is set to invoke `next`
next_button.configure(command=lambda:next(proc_itr))
print('--start--')
defmain():
frame = tk.Tk()
frame.title('title')
frame.geometry("230x60+400+440")
button1 = ttk.Button(frame, text='Next')
button1.place(x=10,y=10,width=100)
button2=ttk.Button(frame, text='start', command=lambda:start(frame,button1)))
button2.place (x=120, y=10, width=100)
frame.mainloop()
if__name__=='__main__':
main()
© 2024 OneMinuteCode. All rights reserved.