首页 > 编程语言 >使用python uiautomation模块,结合多线程快速寻找控件

使用python uiautomation模块,结合多线程快速寻找控件

时间:2024-05-24 16:25:47浏览次数:24  
标签:control 控件 uiautomation thread names time new 多线程

文章目录

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

相关文章

  • Java JUC&多线程 基础完整版
    JavaJUC&多线程基础完整版目录JavaJUC&多线程基础完整版1、多线程的第一种启动方式之继承Thread类2、多线程的第二种启动方式之实现Runnable接口3、多线程的第三种实现方式之实现Callable接口4、多线的常用成员方法5、线程的优先级6、守护线程7、线程的让出8、线程插队9、同......
  • Python多线程案例分析
    接下来,我们将在之前的基础上进一步扩展多线程爬虫案例,增加以下功能:1.动态URL发现与添加:爬虫在解析页面时,能够发现并添加新的URL到队列中。2.设置请求头:模拟浏览器行为,设置请求头中的`User-Agent`。3.使用会话:使用`requests.Session()`对象来保持连接,提高效率。4.避免重......
  • 【WPF】WPF中调用winform的控件,winform始终置顶处理
    在WPF中调用windowFormsHost的控件时,由于渲染机制的问题总会出现各种问题,比如Winform的控件始终会出现在最顶层。在WPF项目中添加Microsoft.DwayneNeed.dll可以避免置顶问题<xmlns:interop=clr-namespace:Microsoft.DwayneNeed.Interop;assembly=Microsoft.DwayneNeed></xmln......
  • .net 直接在DataGridView控件中修改单元格数据,并保存到数据库
    1.获取datagridview单元格修改的内容//单元格的值发生改变时触发事件privatevoiddataGridView1_CellValueChanged(objectsender,DataGridViewCellEventArgse){//获取当前行绑定的内容AppraisalBasesitem=(AppraisalBases)dataGridView1.Rows[e.RowIndex].Da......
  • 推荐一个WPF仪表盘开源控件
    前段时间,做服务器端监控系统,为了界面好看,采用WPF。硬件相关监控,比如CPU、内存等,想用仪表盘控件。网上找了很多这种控件,基本上都是第三方商业控件(虽然很漂亮,不过得money...)。最后在CodeProject上找到了一款还不错的开源的仪表盘控件CircularGauge。用了下该控件,感觉还不错......
  • DataGridView 控件入门
    常用属性和方法ContextMenuStrip属性:当用户点击鼠标右键时(设置和contextMenuStrip挂钩)MultiSelect属性是否可以多行选择SelectionMode属性:设置选中方式,比如是否选中一整行(设置为FullRowSelect)Dock属性:设置显示位置AllowUserToAddRows属性:取......
  • 进程间通信(管道),多线程
    Ⅰ进程间通信(管道)【一】引入借助于消息队列,进程可以将消息放入队列中,然后由另一个进程从队列中取出。这种通信方式是非阻塞的,即发送进程不需要等待接收进程的响应即可继续执行。multiprocessing模块支持两种形式:队列和管道,这两种方式都是使用消息传递的进程间通信(IPC)方式二......
  • DataGridView treeview控件入门
    隐藏treeview相关联的线连接ShowLines设置为false设置行高:itemHeight设置在窗体的位置:Dock设置是否随窗体大小改变而改变:Anchor设置被选中后,是否占满整行:FullRowSelect被点击后的事件:AfterSelectprivatevoidtreeView_AfterSelec......
  • duilib 自定义控件
    1.主窗口自定义FramWnd继承WindowImplBase,重写CreateControl,HandleMessage.组合CPaintManagerUI.2.自定义控件自定义mycontrol继承CControlUI重写DoEvent,DoPaint,SetPos.main.cpp#include"FramWnd.h"intAPIENTRYWinMain(HINSTANCEhInstance,HINSTANCE/*hPrev......
  • Java实验五: Java多线程程序设计(头歌)
    一、线程接力编写一个应用程序,除了主线程外,还有三个线程:first、second和third。first负责模拟一个红色的按钮从坐标(10,60)运动到(100,60);second负责模拟一个绿色的按钮从坐标(100,60)运动到(200,60)。third线程负责模拟一个蓝色的按钮从坐标(200,60)运动到(300,60)。第一步以下是ideajdk1.8的教......