#python #tkinter #multiprocessing
Вопрос:
Я использую следующий код, но я получаю «Ошибка имени: имя» логарифмическая область «не определено»
from tkinter import *
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
import time
import multiprocessing
from multiprocessing import Queue
import os
from tkinter import ttk
import logging
import datetime
curr_dir = os.getcwd()
def browserRun():
global curr_dir
timenow = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
logname = rf'{curr_dir}LogsLog-{timenow}.txt'
logging.basicConfig(filename=logname,
filemode='a',
format='%(asctime)s: %(message)s',
datefmt='%d-%m-%Y %I:%M:%S %p',
level=logging.INFO,
force=True)
while True:
global driver
options = Options()
options.binary_location = r'D:DownloadsChromedriverbrowserchrome.exe'
driver = webdriver.Chrome(executable_path=r'D:DownloadsChromedriverchromedriver.exe', options=options)
driver.get('http://google.com')
logging.info(f"Logging to gmail")
loggingtoUI(logname)
time.sleep(5)
driver.find_element(By.XPATH, '//input[@name="q"]').send_keys("Hello World")
time.sleep(5)
driver.close()
driver.quit()
def start():
global executor
pqueue = Queue()
executor = [multiprocessing.Process(target=browserRun) for _ in range(1)]
for p in executor:
p.daemon = True
p.start()
def loggingtoUI(logname):
global myfile
global logarea
with open(logname, "r") as myfile:
try:
MyText2 = myfile.read()
logarea.config(state='normal')
logarea.delete('1.0', END)
logarea.insert(INSERT, MyText2)
logarea.see("end")
logarea.config(state='disabled')
finally:
myfile.close()
def stop():
global executor
for p in executor:
p.terminate()
# os.system("taskkill /F /IM chromedriver.exe /T")
os.system("taskkill /F /IM CHROME.exe /T")
if __name__ == '__main__':
global logarea
root = Tk()
notebook = ttk.Notebook(root, style='lefttab.TNotebook')
tab1 = ttk.Frame(notebook)
tab2 = ttk.Frame(notebook)
notebook.add(tab1, text="Home")
notebook.add(tab2, text="Settings")
notebook.pack(fill=BOTH, expand=True)
button = Button(tab1, text="start", command=start)
button.place(x=20, y=20)
button1 = Button(tab1, text="stop", command=stop)
button1.place(x=70, y=20)
logarea = Text(tab1, height=25, width=40, wrap='word', state='disabled')
logarea.place(x=120, y=40)
root.geometry("500x500")
root.mainloop()
Я установил логарифмическую область в глобальную, но все равно получаю ошибку имени, я попытался установить логарифмическую область как глобальную при запуске и загрузке кода, но ничего не работает.
Проблема возникает, когда я вызываю loggingtoUI в другой функции. Любая помощь будет признательна.
Комментарии:
1. во — первых , вам не нужно использовать
global logarea
, во-вторых, вам не нужно использоватьtry/finally
with
контекстный менеджер, потому что это именно то, что он делает неявно. иlogarea
определяется2. Матисс, Спасибо за помощь, но это не сработало, я снимаю
try/finally global logarea
, но все равно это видноNameError: name 'logarea' is not defined
, это происходит наlogarea.config(state='normal')
3. Данные не передаются между процессами.
4. acw1668, Спасибо за помощь, когда я добавляю
MyText2 = myfile.read()
того, как смогу увидеть прочитанные данные5.
logarea
не разделяется между процессами, и вы даже не можете поделиться им, потому что он не поддается маринованию (ничегоtkinter
такого нет), вам, вероятно, нужно использоватьmultiprocessing.Queue
илиmultiprocessing.Manager
обмениваться данными с основным процессом и использовать.after
«цикл» для обновления текстового виджета
Ответ №1:
Наконец-то нашел ответ, спасибо за помощь, ребята
from queue import Empty, Full
import tkinter as Tk
import multiprocessing
from tkinter import ttk
from tkinter import *
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
import logging
import datetime
import time
import os
import undetected_chromedriver.v2 as uc
import random
import tempfile
logname = ''
curr_dir = os.getcwd()
class GuiApp(object):
def __init__(self, q):
self.root = Tk()
self.notebook = ttk.Notebook(self.root, style='lefttab.TNotebook')
self.tab1 = ttk.Frame(self.notebook)
self.tab2 = ttk.Frame(self.notebook)
self.notebook.add(self.tab1, text="Home")
self.notebook.add(self.tab2, text="Settings")
self.notebook.pack(fill=BOTH, expand=True)
self.button = Button(self.tab1, text="start", command=self.start)
self.button.place(x=20, y=20)
self.button1 = Button(self.tab1, text="stop", command=self.stop)
self.button1.place(x=70, y=20)
self.logarea = Text(self.tab1, height=25, width=40, wrap='word', state='disabled')
self.logarea.place(x=120, y=40)
self.root.geometry("500x500")
self.root.after(100, self.CheckQueuePoll, q)
def CheckQueuePoll(self, c_queue):
global logname
try:
MyText2 = c_queue.get(0)
self.logarea.config(state='normal')
self.logarea.delete('1.0', END)
self.logarea.insert('end', MyText2)
self.logarea.config(state='disabled')
except Empty:
pass
finally:
self.root.after(100, self.CheckQueuePoll, c_queue)
def start(self):
global executor
executor = [multiprocessing.Process(target=GenerateData,args=(q,)) for _ in range(2)]
for p in executor:
p.start()
# t1 = multiprocessing.Process(target=GenerateData,args=(q,))
# t1.start()
def stop(self):
# t1.terminate()
for p in executor:
p.terminate()
os.system("taskkill /F /IM chromedriver.exe /T")
# os.system("taskkill /F /IM CHROME.exe /T")
def GenerateData(q):
global logname
global curr_dir
timenow = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
logname = rf'{curr_dir}LogsLog-{timenow}.txt'
logging.basicConfig(filename=logname,
filemode='a',
format='%(asctime)s: %(message)s',
datefmt='%d-%m-%Y %I:%M:%S %p',
level=logging.INFO,
force=True)
while True:
options = uc.ChromeOptions()
rand_num = random.randint(0000, 9999)
temp = tempfile.gettempdir()
temp_dir = rf'{temp}/temp{rand_num}'
options.add_argument(f'--user-data-dir={temp_dir}')
options.add_argument('--no-first-run --no-service-autorun --password-store=basic --disable-notifications')
options.binary_location = rf'{curr_dir}driversBrowserchrome.exe'
driver = uc.Chrome(executable_path=rf'{curr_dir}driverschromedriver.exe', options=options)
driver.get('http://google.com')
logging.info(f"Logging to gmail")
f = open(logname, "r")
q.put(f.read())
time.sleep(5)
driver.find_element(By.XPATH, '//input[@name="q"]').send_keys("Hello World")
time.sleep(5)
driver.close()
driver.quit()
if __name__ == '__main__':
q = multiprocessing.Queue()
q.cancel_join_thread() # or else thread that puts data will not term
gui = GuiApp(q)
gui.root.mainloop()