文章目录
1.形式一
- 该方法使用多线程进行搜索,主线程不会等待所有子线程返回结果后再继续执行,而是在获取队列中第一个结果后立即继续执行。
- 优势在于一旦有子线程找到结果,主线程就能立即继续执行;
- 劣势在于未找到结果的子线程会持续搜索,直到达到设定的最大搜索时间(maxSearchSeconds)后才结束。
import queue
import threading
import time
from enum import Enum
from uiautomation import uiautomation, UninitializeUIAutomationInCurrentThread, InitializeUIAutomationInCurrentThread
class ControlName(Enum):
Intel_Graphics_Command_Center = ['AMD显卡', "Intel® Graphics Command Center"]
def find_window_by_uiautomation(names: list, control=uiautomation.WindowControl):
def find_thread(_name: str):
nonlocal control
# Uninitialize UIAutomation in a new thread after calling InitializeUIAutomationInCurrentThread.
# You must call this function when the new thread exits if you have called InitializeUIAutomationInCurrentThread in the same thread.
UninitializeUIAutomationInCurrentThread()
# Initialize UIAutomation in a new thread.
# If you want to use functionalities related to Controls and Patterns in a new thread.
# You must call this function first in the new thread.
# But you can't use a Control or a Pattern created in a different thread.
# So you can't create a Control or a Pattern in main thread and then pass it to a new thread and use it.
InitializeUIAutomationInCurrentThread()
item_control = control(Name=_name)
if item_control.Exists(maxSearchSeconds=5): # 搜索时间
q.put(item_control)
else:
q.put(False)
q = queue.Queue()
_list = []
for name in names:
t = threading.Thread(target=find_thread, args=(name,))
t.setDaemon(True)
t.start()
_list.append(t)
for _ in names:
try:
res = q.get(timeout=5)
if res:
return res
except queue.Empty:
return False
if __name__ == '__main__':
start = time.time()
res = find_window_by_uiautomation(names=ControlName.Intel_Graphics_Command_Center.value,
control=uiautomation.WindowControl)
print("USE:", time.time() - start, res)
2.形式二
- 该方法利用多线程线程池进行搜索,主线程在等待所有子线程返回结果后才会继续执行。
- 优势:主线程继续执行时不会产生额外的子线程开销。
- 劣势:至少要等到maxSearchSeconds后,主线程才会继续执行。
import concurrent.futures
import time
from enum import Enum
from uiautomation import uiautomation, UninitializeUIAutomationInCurrentThread, InitializeUIAutomationInCurrentThread
class ControlName(Enum):
Intel_Graphics_Command_Center = ['1121', '1121', "Intel® Graphics Command Center"]
def find_window_by_uiautomation(control, names=None):
# 定义一个准备作为线程任务的函数
def find_thread(_name):
nonlocal control
# Uninitialize UIAutomation in a new thread after calling InitializeUIAutomationInCurrentThread.
# You must call this function when the new thread exits if you have called InitializeUIAutomationInCurrentThread in the same thread.
UninitializeUIAutomationInCurrentThread()
# Initialize UIAutomation in a new thread.
# If you want to use functionalities related to Controls and Patterns in a new thread.
# You must call this function first in the new thread.
# But you can't use a Control or a Pattern created in a different thread.
# So you can't create a Control or a Pattern in main thread and then pass it to a new thread and use it.
InitializeUIAutomationInCurrentThread()
item_control = control(Name=_name)
if item_control.Exists(maxSearchSeconds=3):
return item_control
else:
return False
if names is None:
return False
if not isinstance(names, list):
names = [names]
# 创建一个包含n条线程的线程池
with concurrent.futures.ThreadPoolExecutor(max_workers=len(names)) as pool:
futures = [pool.submit(find_thread, _) for _ in names]
# 通过as_completed函数获取第一个完成的任务
for future in concurrent.futures.as_completed(futures):
result = future.result()
pool.shutdown()
return result
if __name__ == '__main__':
start = time.time()
a = find_window_by_uiautomation(names=ControlName.Intel_Graphics_Command_Center.value,
control=uiautomation.WindowControl)
print("USE:", time.time() - start, a)
标签:control,控件,uiautomation,thread,names,time,new,多线程
From: https://blog.csdn.net/qq_29371275/article/details/139127988