无法使用UIA后端访问子菜单元素

时间:2019-07-05 08:57:53

标签: pywinauto

我正在使用截至2019/07/04的来自github的最新pywinauto代码。

我正在尝试访问基于Eclipse的应用程序菜单/子菜单项。我用于执行此操作的代码是:

public class ScreenCapture : MonoBehaviour
{
    //here you can set the folder you want to use, 
    //IMPORTANT - use "@" before the string, because this is a verbatim string
    //IMPORTANT - the folder must exists
    string pathToYourFile = @"C:\Screenshots\";
    //this is the name of the file
    string fileName = "filename";
    //this is the file type
    string fileType = ".png";

    private int CurrentScreenshot { get => PlayerPrefs.GetInt("ScreenShot"); set => PlayerPrefs.SetInt("ScreenShot", value); }

    private void Update()
    {

        if (Input.GetKeyDown(KeyCode.Space))
        {
            UnityEngine.ScreenCapture.CaptureScreenshot(pathToYourFile + fileName + CurrentScreenshot + fileType);
            CurrentScreenshot++;
        }
    }
}

不幸的是,这引发了一个异常:

mainwinobj.menu_select("Project->My first menu->my second menu(specific)")

尽管如此,我可以看到它正确地单击了Traceback (most recent call last): File <MYPATH>\pywinauto\controls\uia_controls.py", line 1073, in item_by_path menu = next_level_menu(menu, menu_items[i], items_cnt == i + 1) File "<MYPATH>\pywinauto\controls\uia_controls.py", line 1053, in next_level_menu return self._sub_item_by_text(parent_menu, item_name, exact, is_last) File "<MYPATH>\pywinauto\controls\uia_controls.py", line 1017, in _sub_item_by_text self._activate(sub_item, is_last) File "<MYPATH>\pywinauto\controls\uia_controls.py", line 984, in _activate if not item.is_active(): AttributeError: 'NoneType' object has no attribute 'is_active' ,但没有正确地单击第二个。

我的行为也不一致,有时我会看到它在正确点击My first menu后错误地点击了My first menu图形上的子菜单,导致正确的子菜单从屏幕上消失。不会发生异常静止图像,但这不会改变,但会影响我如下所述尝试的解决方法。

引起问题的根源

我很快就能了解问题的根本原因:在My first menu中,一行

_sub_item_by_text

返回一个空列表,因此items = menu.items() 保持为无。

尝试过的解决方案

我围绕一个核心解决方案尝试了许多不同的方法,这些方法有时会导致正确的行为,但是它从来都不是一致的。基本上,我强迫搜索窗口以尝试找到菜单:

sub_item

或其他解决方案,例如:

        if not menu.items():
            print("waiting for menu " + menu.window_text())
            time.sleep(1)
            menus = menu.top_level_parent().children(control_type="Menu", title=menu.window_text())
            print(menus)
            menu = menus[0]

或者我删除了激活:

        if not menu.items():
            print("waiting for menu " + menu.window_text())
            self._activate(menu, False)
            timings.wait_until(
                timings.Timings.window_find_timeout,
                timings.Timings.window_find_retry,
                lambda: len(self.top_level_parent().descendants(control_type="Menu", title=menu.window_text())) > 0)
            menus = menu.top_level_parent().children(control_type="Menu", title=menu.window_text())
            print(menus)
            menu = menus[0]

但是最后,这些操作始终无法正常工作,有时还是可以,但是当我在我期望的子菜单条目上方单击此子菜单项时,它总是失败,因为它会使正确的菜单消失。

1 个答案:

答案 0 :(得分:0)

我找到了解决问题的方法,该问题是由于以下事实:在调用menu_select之前,鼠标指针位于与子菜单图形扩展冲突的位置。

由于某种原因,在选择最后一个子菜单项之前,系统会“单击”鼠标所处的位置,最终出现在另一个菜单项中。

因此,为了避免发生此问题,在调用menu_select之前,我将指针强制指向了无法执行任何操作的位置。

第二步,我将win32用作自动化了我必须操纵的大多数元素(更安全,得到更好的支持)的后端,而我仅将UIA用于复杂的元素。