From e32681f90a2a84305c32ceb1bbfbe802386e535c Mon Sep 17 00:00:00 2001 From: Ivan Maslov Date: Tue, 7 May 2019 10:12:10 +0300 Subject: [PATCH] #Robot_GUI_Refactoring_70% --- Robot/GUI.py | 329 ++++----------------------------------------------- 1 file changed, 26 insertions(+), 303 deletions(-) diff --git a/Robot/GUI.py b/Robot/GUI.py index 08266e9c..ef8197a8 100644 --- a/Robot/GUI.py +++ b/Robot/GUI.py @@ -460,109 +460,13 @@ def UIOSelector_Get_UIOInfo(inControlSpecificationArray): lResultList.append(ElementInfoExportObject(lTempObjectInfo)); return lResultList -############################ -#Старая версия -############################ -mFlagIsDebug=False - - - -################################## - -############################################ -###Модуль поиска объекта на экране -############################################ -#Инициализация глобальных переменных -mBitmap={} -mGUISearchElementSelected={} -def GUISearchEvent_on_move(lX, lY): - global mBitmap - global mGUISearchElementSelected - if (lX,lY) in mBitmap: - if mGUISearchElementSelected != mBitmap[lX,lY]: - mGUISearchElementSelected = mBitmap[lX,lY] - mBitmap[lX,lY].draw_outline() -def GUISearchEvent_on_click(x, y, button, pressed): - global mBitmap - global mGUISearchElementSelected - print('{0} at {1}'.format( - 'Pressed' if pressed else 'Released', - (x, y))) - print(str(len(mBitmap))) - if not pressed: - # Stop listener - del mBitmap - mBitmap={} - del mGUISearchElementSelected - mGUISearchElementSelected={} - return False -def GUISearchEvent_on_scroll(x, y, dx, dy): - print('Scrolled {0} at {1}'.format( - 'down' if dy < 0 else 'up', - (x, y))) - -#Создать bitmap карту объектов -#GUISearchBitmapCreate -#inElement - wrapper_object() -# dict: x_y_ : elementObject -def GUISearchRun(inSpecificationArray): - lBitmap={} - lGUISearchElementSelected=None - #Создать карту пикселей и элементов - lBitmap=GUISearchBitmapCreate(GetControl(inSpecificationArray),lBitmap) - #Выдать сообщение, что поиск готов к использованию - #print("GUISearch: Ready for search!") - #mBitmap=lBitmap - # Collect events until released - #Версия с Events (занимает поток, чтобы использовать общие переменные) - #with mouse.Listener( - # on_move=GUISearchEvent_on_move, - # on_click=GUISearchEvent_on_click, - # on_scroll=GUISearchEvent_on_scroll) as listener: - #listener.join() - # True == False - ##################### - ###Версия с таймером - ##################### - #mTimer = RepeatedTimer(0.5, GUISearchDraw, lBitmap) # it auto-starts, no need of rt.start() - #mTimer.start() - ########### - #Версия с задержкой - ########### - #Сбросить нажатие Ctrl, если оно было - bool(win32api.GetAsyncKeyState(17)) - lTimeSleepSeconds=0.7 - lFlagLoop = True - while lFlagLoop: - #Проверить, нажата ли клавиша Ctrl (код 17) - lFlagKeyPressedCtrl=bool(win32api.GetAsyncKeyState(17)) - #Подсветить объект, если мышка наведена над тем объектом, который не подсвечивался в прошлый раз - if not lFlagKeyPressedCtrl: - #Получить координаты мыши - (lX,lY) = win32api.GetCursorPos() - #Подсветить объект, если мышь над ним - if (lX,lY) in lBitmap: - if lGUISearchElementSelected != lBitmap[lX,lY]: - lGUISearchElementSelected = lBitmap[lX,lY] - lBitmap[lX,lY].draw_outline() - else: - lGUISearchElementSelected = None - else: - #Была нажата клавиша Ctrl - выйти из цикла - lFlagLoop=False; - #Заснуть до следующего цикла - time.sleep(lTimeSleepSeconds) - #Вернуть результат поиска - return lGUISearchElementSelected -############################################################# -#Поиск элементов -############################################################# -#inHierarchyList: [{"index":<>,"element":<>}] -# -#Вернуть словарь [{"index":<>,"element":<>}] -#Последний элемент - искомый -def GUISearchElementByRootXY(inRootElement,inX,inY,inHierarchyList=[]): +#################################################################################################### +#Search child UIO by the: Parent UIO, X, Y +#inHierarchyList: [{"index":<>,"element":<>}] - technical argument for internal purpose +#result -List of dict [{"index":<>,"element":<>}] -- list of element hierarchy specifications +#old name - GUISearchElementByRootXY +def UIOXY_SearchChild_ListDict(inRootElement,inX,inY,inHierarchyList=[]): #Инициализация результирующего значения lResultElement = None lResultElementX1 = None @@ -645,92 +549,12 @@ def GUISearchElementByRootXY(inRootElement,inX,inY,inHierarchyList=[]): except Exception as e: False == False return lResultHierarchyList -#Техническая функция -def GUISearchBitmapCreate (inElement,inBitmapDict={}): - #Добавить в карту информацию о текущем объекте - inBitmapDict=GUISearchBitmapElementFill(inElement,inBitmapDict) - #Получить список детей и добавить в карту - for lItem in inElement.children(): - inBitmapDict=GUISearchBitmapCreate(lItem,inBitmapDict) - return inBitmapDict - -#GUISearchBitmapElementFill -def GUISearchBitmapElementFill (inElement,inBitmapDict): - lElementInfo=inElement.element_info - #pdb.set_trace() - #Получить параметры прямоугольника - lElementRectX1 = 0 - lElementRectX2 = 0 - lElementRectY1 = 0 - lElementRectY2 = 0 - lFlagHasRect = True - try: - lElementRectX1=lElementInfo.rectangle.left - lElementRectX2=lElementInfo.rectangle.right - lElementRectY1=lElementInfo.rectangle.top - lElementRectY2=lElementInfo.rectangle.bottom - #Выполнить установку элемента, если прямоугольник получить удалось - if lFlagHasRect: - lX=lElementRectX1 - #Циклический обход по оси X - while lX<=lElementRectX2: - lY=lElementRectY1 - #Циклический обход по Оси Y - while lY<=lElementRectY2: - ###################### - #Если объект в карте есть - if (lX,lY) in inBitmapDict: - if inBitmapDict[lX,lY] is not None: - #Правила перезатирания карты, если имеется старый объект - #[Накладываемый объект] - НО - ElementNew - #[Имеющийся объект] - ИО - ElementOld - #3 типа вхождения объектов - #тип 1 - [имеющийся объект] полностью входит в [накладываемый объект] (ИО X1 Y1 >= НО X1 Y1; ИО X2 Y2 <= НО X2 Y2) - не вносить НО в bitmap в эти диапазоны - #тип 2 - [имеющийся объект] полностью выходит за пределы [накладываемого объекта] (ИО X1 Y1 < НО X1 Y1; ИО X2 Y2 > НО X2 Y2) - вносить НО в bitmap - #тип 3 - [имеющийся объект] частично входит в [накладываемый объект] (все остальные случаи)- вносить НО в bitmap - #Получить координаты ИО - lElementOldInfo = inBitmapDict[lX,lY].element_info - #lElementNew = inElement - lElementOldX1 = lElementOldInfo.rectangle.left - lElementOldX2 = lElementOldInfo.rectangle.right - lElementOldY1 = lElementOldInfo.rectangle.top - lElementOldY2 = lElementOldInfo.rectangle.bottom - #Проверка вхождения по типу 1 - if (lElementOldX1>=lElementRectX1) and (lElementOldY1>=lElementRectY1) and (lElementOldX2<=lElementRectX2) and (lElementOldY2<=lElementRectY2): - #Выполнить корректировку каретки по lY, чтобы не проходить по всем пикселям в рамках этой линии - lY = lElementOldY2 + 1 - #Проверка вхождения по типу 3 - elif (lElementOldX1lElementRectX2) and (lElementOldY2>lElementRectY2): - #Установка элемента по адресу [,] - inBitmapDict[lX,lY]=inElement - #Инкремент y - lY=lY+1 - #Проверка вхождения по типу 2 - else: - #Установка элемента по адресу [,] - inBitmapDict[lX,lY]=inElement - #Инкремент y - lY=lY+1 - #Если объекта в карте нет - else: - #Установка элемента по адресу [,] - inBitmapDict[lX,lY]=inElement - #Инкремент y - lY=lY+1 - else: - #Установка элемента по адресу [,] - inBitmapDict[lX,lY]=inElement - #Инкремент y - lY=lY+1 - ###################### - #Инкремент X - lX=lX+1 - except Exception as e: - lFlagHasRect = False - return inBitmapDict -#debug -def ElementGetChildElementList(inControlSpecificationArray=[]): +################################################################################################### +#Get list of child UIO's by Parent UIOSelector +#inControlSpecificationArray- UIOSelector +#old name - ElementGetChildElementList +def UIOSelector_GetChildList_UIOList(inControlSpecificationArray=[]): #Подготовка входного массива inControlSpecificationArray=ElementSpecificationArraySearchPrepare(inControlSpecificationArray) #Выполнить идентификацию объектов, если передан массив @@ -755,64 +579,13 @@ def ElementGetChildElementList(inControlSpecificationArray=[]): else: lResultList=GetRootElementList() return lResultList -#Подготовить спецификацию для поиска элемента -def ElementSpecificationListNormalize(inElementSpecification): - lResult=[] - #Циклический обход - for lSpecificationItem in inElementSpecification: - lSpecificationItemNew=lSpecificationItem.copy() - #Перебор всех элементов - for lItemKey,lItemValue in lSpecificationItem.items(): - #Флаг удаления атрибута - lFlagRemoveAttribute=False - ############################# - #Если является вложенным словарем - удалить - if type(lItemValue) is dict: - lFlagRemoveAttribute=True - #Является типом None - if lItemValue is None: - lFlagRemoveAttribute=True - #Проверка допустимого ключевого слова - if ( - lItemKey == "class_name" or - lItemKey == "class_name_re" or - lItemKey == "parent" or - lItemKey == "title" or - lItemKey == "title_re" or - lItemKey == "top_level_only" or - lItemKey == "visible_only" or - lItemKey == "enabled_only" or - lItemKey == "best_match" or - lItemKey == "handle" or - lItemKey == "ctrl_index" or - lItemKey == "found_index" or - lItemKey == "predicate_func" or - lItemKey == "active_only" or - lItemKey == "control_id" or - lItemKey == "control_type" or - lItemKey == "auto_id" or - lItemKey == "framework_id" or - lItemKey == "backend"): - True == True - else: - lFlagRemoveAttribute=True - ############################# - #Конструкция по удалению ключа из словаря - if lFlagRemoveAttribute: - lSpecificationItemNew.pop(lItemKey) - #Проверит наличие ctrl_index - если он есть, то удалить control_id и control_type из-за того, что они мешают друг другу - if 'ctrl_index' in lSpecificationItemNew: - if "control_id" in lSpecificationItemNew: - lSpecificationItemNew.pop("control_id") - if "control_type" in lSpecificationItemNew: - lSpecificationItemNew.pop("control_type") - #Добавить строку в результирующий массив - lResult.append(lSpecificationItemNew) - #Вернуть результат - return lResult +#################################################################################################### #Подготовить массив для обращшения к поиску элемементов -def ElementSpecificationArraySearchPrepare(inControlSpecificationArray): +#inControlSpecificationArray - UIOSelector (can be dirty) +#old name 1 - ElementSpecificationArraySearchPrepare +#old name 2 - ElementSpecificationListNormalize +def UIOSelector_SearchNormalize_UIOSelector (inControlSpecificationArray): lResult=[] #Циклический обход for lSpecificationItem in inControlSpecificationArray: @@ -869,66 +642,16 @@ def ElementSpecificationArraySearchPrepare(inControlSpecificationArray): lResult.append(lSpecificationItemNew) #Вернуть результат return lResult -############################### -####Нормализация под JSON (в JSON нельзя передавать классы - только null, числа, строки, словари и массивы) -############################### -#Нормализация словаря под JSON -def JSONNormalizeDictionary(inDictionary): - #Сделать копию объекта - lResult=inDictionary.copy() - #Перебор всех элементов - for lItemKey,lItemValue in inDictionary.items(): - #Флаг удаления атрибута - lFlagRemoveAttribute=False - #Если строка или число или массив или объект или None - оставить - if ( - type(lItemValue) is dict or - type(lItemValue) is int or - type(lItemValue) is str or - type(lItemValue) is list or - lItemValue is None): - True==True - else: - lFlagRemoveAttribute=True - #Рекурсивный вызов, если объект является словарем - if type(lItemValue) is dict: - lResult[lItemKey]=JSONNormalizeDictionary(lItemValue) - #Рекурсивный вызов, если объект является списком - if type(lItemValue) is list: - lResult[lItemKey]=JSONNormalizeList(lItemValue) - ############################# - #Конструкция по удалению ключа из словаря - if lFlagRemoveAttribute: - lResult.pop(lItemKey) - #Вернуть результат - return lResult -#Нормализация массива под JSON -def JSONNormalizeList(inList): - lResult=[] - #Циклический обход - for lItemValue in inList: - #Если строка или число или массив или объект или None - оставить - if ( - type(lItemValue) is int or - type(lItemValue) is str or - lItemValue is None): - lResult.append(lItemValue) - #Если является словарем - вызвать функцию нормализации словаря - if type(lItemValue) is dict: - lResult.append(JSONNormalizeDictionary(lItemValue)) - #Если является массиваом - вызвать функцию нормализации массива - if type(lItemValue) is list: - lResult.append(JSONNormalizeList(lItemValue)) - #Вернуть результат - return lResult -#Определить объект - dict or list - и нормализовать его для JSON -def JSONNormalizeDictList(inDictList): - lResult={} - if type(inDictList) is dict: - lResult=JSONNormalizeDictionary(inDictList) - if type(inDictList) is list: - lResult=JSONNormalizeList(inDictList) - return lResult; + + + +############################ +#Старая версия +############################ +mFlagIsDebug=False + + + #Получить объект из атрибутов, которые удалось прочитать def ElementInfoExportObject(inElementInfo): #Подготовить выходную структуру данных