Screen module in progress

dev-linux
Ivan Maslov 2 years ago
parent 3a40812d5d
commit 4d98aaa358

@ -29,8 +29,15 @@ height - расстояние вниз от левой верхней точки
width - расстояние вправо от левой верхней точки в пикселях width - расстояние вправо от левой верхней точки в пикселях
************************************************ ************************************************
Символьное указание точки (inAnchorStr) Символьное указание точки (inPointRuleStr)
************************************************ ************************************************
LU| |RU
--------
|CC|
--------
LD| |RD
Символьное указание точки - точка относительно которой выполнить изменение прямоугольной области. Символьное указание точки - точка относительно которой выполнить изменение прямоугольной области.
"CC", "CC",
@ -48,6 +55,54 @@ width - расстояние вправо от левой верхней точ
- "RD" - правый край по горизонтали, нижний край по вертикали - "RD" - правый край по горизонтали, нижний край по вертикали
- "RU" - правый край по горизонтали, верхний край по вертикали - "RU" - правый край по горизонтали, верхний край по вертикали
************************************************
Символьное указание области (inAnchorRuleStr)
************************************************
LU|CU|RU
--------
LC|CC|RC
--------
LD|CD|RD
Символьное указание области поиска - область относительно которой выполнить поиск другой прямоугольной области.
"CC",
Формат образования кода: XY, где
- X обозначает область по горизонтали (допустимые значения: "L", "C", "R")
- Y обозначает область по вертикали (допустимые значения: "U", "C", "D")
Допустимые значения:
- "CC" - выбранная прямоугольная область
- "LU" - слева и сверху от выбранной прямоугольной области
- "LD" - слева и снизу от выбранной прямоугольной области
- "LС" - слева от выбранной прямоугольной области
- "RC" - справа от выбранной прямоугольной области
- "СU" - сверху от выбранной прямоугольной области
- "CD" - сверху от выбранной прямоугольной области
- "RD" - справа и снизу от выбранной прямоугольной области
- "RU" - справа и сверху от выбранной прямоугольной области
Опция "S" (strict) - искомый объект должен всеми своими координатами находиться в обозначенной прямоугольной области
Формат допускает комбинации нескольких областей в одной строке.
Пример:
"CC,LU,LD,S"
"CC|LU|LD|S"
"CCLULDS"
Графическая интерпретация:
+|-|-
-----
-|+|-
-----
+|-|-
************************************************** **************************************************
Описание функций Описание функций
************************************************** **************************************************

@ -64,7 +64,7 @@ def BoxMoveTo(inBox, inDXInt=None, inDYInt=None):
return BoxCreate(inTopInt=lTopInt, inLeftInt=lLeftInt, return BoxCreate(inTopInt=lTopInt, inLeftInt=lLeftInt,
inHeightInt=inBox.height, inWidthInt=inBox.width) inHeightInt=inBox.height, inWidthInt=inBox.width)
def BoxModify(inBox, inDWidthInt=None, inDHeightInt=None, inAnchorStr="CC"): def BoxModify(inBox, inDWidthInt=None, inDHeightInt=None, inPointRuleStr="CC"):
"""Изменить ширину / высоту прямоугольной области. """Изменить ширину / высоту прямоугольной области.
!ВНИМАНИЕ! ПОДДЕРЖИВАЕТ ПАКЕТНУЮ ОБРАТКУ ПРИ ПЕРЕДАЧЕ СПИСКА ЭКЗЕМПЛЯРОВ BOX !ВНИМАНИЕ! ПОДДЕРЖИВАЕТ ПАКЕТНУЮ ОБРАТКУ ПРИ ПЕРЕДАЧЕ СПИСКА ЭКЗЕМПЛЯРОВ BOX
@ -91,31 +91,31 @@ def BoxModify(inBox, inDWidthInt=None, inDHeightInt=None, inAnchorStr="CC"):
:type inDXInt: int, опциональный :type inDXInt: int, опциональный
:param inDYInt: Смещение левой верхней координаты по оси Y в пикселях (вертикальная ось). :param inDYInt: Смещение левой верхней координаты по оси Y в пикселях (вертикальная ось).
:type inDYInt: int, опциональный :type inDYInt: int, опциональный
:param inAnchorStr: Символьное указание точки (подробнее см. выше), относительно которой выполнить изменение прямоугольной области. Допустимые значения: "CC" (по умолчанию), "LU", "LD", "RD", "RU" :param inPointRuleStr: Символьное указание точки (подробнее см. выше), относительно которой выполнить изменение прямоугольной области. Допустимые значения: "CC" (по умолчанию), "LU", "LD", "RD", "RU"
:type inAnchorStr: str, опциональный :type inPointRuleStr: str, опциональный
:return: Экземпляр класса прямоугольной области Box :return: Экземпляр класса прямоугольной области Box
:rtype: pyscreeze.Box :rtype: pyscreeze.Box
""" """
if type(inBox) is list: if type(inBox) is list:
lResult = [] lResult = []
for lBox in inBox: for lBox in inBox:
lResult.append(BoxModify(lBox, inDWidthInt=inDWidthInt, inDHeightInt=inDHeightInt, inAnchorStr=inAnchorStr)) lResult.append(BoxModify(lBox, inDWidthInt=inDWidthInt, inDHeightInt=inDHeightInt, inPointRuleStr=inPointRuleStr))
return lResult return lResult
else: else:
lTopInt = inBox.top lTopInt = inBox.top
lLeftInt = inBox.left lLeftInt = inBox.left
lWidthInt = inBox.width + inDWidthInt lWidthInt = inBox.width + inDWidthInt
lHeightInt = inBox.height + inDHeightInt lHeightInt = inBox.height + inDHeightInt
inAnchorStr = inAnchorStr.upper() # ВЕРХНИЙ РЕГИСТР inPointRuleStr = inPointRuleStr.upper() # ВЕРХНИЙ РЕГИСТР
if inDWidthInt: # Изменения по ширине if inDWidthInt: # Изменения по ширине
if "C" in inAnchorStr: if "C" in inPointRuleStr:
lLeftInt = round(lLeftInt - inDWidthInt / 2) lLeftInt = round(lLeftInt - inDWidthInt / 2)
elif "R" in inAnchorStr: elif "R" in inPointRuleStr:
lLeftInt = lLeftInt - inDWidthInt lLeftInt = lLeftInt - inDWidthInt
if inDHeightInt: # Изменения по высоте if inDHeightInt: # Изменения по высоте
if "C" in inAnchorStr: if "C" in inPointRuleStr:
lTopInt = round(lTopInt - inDHeightInt / 2) lTopInt = round(lTopInt - inDHeightInt / 2)
elif "D" in inAnchorStr: elif "D" in inPointRuleStr:
lTopInt = lTopInt - inDHeightInt lTopInt = lTopInt - inDHeightInt
return BoxCreate(inTopInt=lTopInt, inLeftInt=lLeftInt, return BoxCreate(inTopInt=lTopInt, inLeftInt=lLeftInt,
inHeightInt=lHeightInt, inWidthInt=lWidthInt) inHeightInt=lHeightInt, inWidthInt=lWidthInt)
@ -143,11 +143,11 @@ def BoxDraw(inBox, inColorStr='green',inThicknessInt = 2):
lBox2 = Screen.BoxCreate(inTopInt=60, inLeftInt=60, inHeightInt=100, inWidthInt=100) lBox2 = Screen.BoxCreate(inTopInt=60, inLeftInt=60, inHeightInt=100, inWidthInt=100)
Screen.BoxDraw([lBox, lBox2]) Screen.BoxDraw([lBox, lBox2])
:param inBox: UIO объект, который будет подсвечен :param inBox: Экземпляр класса прямоугольной области Box
:type inBox: object UIO, обязательный :type inBox: pyscreeze.Box
:param inColorStr: цвет подсветки UIO объекта. Варианты: 'red', 'green', 'blue'. По умолчанию 'green' :param inColorStr: цвет подсветки прямоугольной области. Варианты: 'red', 'green', 'blue'. По умолчанию 'green'
:type inColorStr: str, необязательный :type inColorStr: str, необязательный
:param inThicknessInt: толщина подсветки UIO объекта. По умолчанию 2 :param inThicknessInt: толщина подсветки прямоугольной области. По умолчанию 2
:type inThicknessInt: int, необязательный :type inThicknessInt: int, необязательный
""" """
if type(inBox) is list: if type(inBox) is list:
@ -195,3 +195,117 @@ def BoxDraw(inBox, inColorStr='green',inThicknessInt = 2):
win32functions.DeleteObject(pen_handle) win32functions.DeleteObject(pen_handle)
# delete the Display context that we created # delete the Display context that we created
win32functions.DeleteDC(dc) win32functions.DeleteDC(dc)
def BoxAnchorRuleCheck(inBox, inAnchorBox=None, inAnchorRuleStr=None) -> bool:
"""Выполнить проверку соответствия всем условиям вхождения inBox в inAnchorBox с учетом правил inAnchorRule
.. code-block:: python
# Screen: Взаимодействие с экраном
from pyOpenRPA.Robot import Screen
lBox1 = Screen.BoxCreate(inTopInt=265, inLeftInt=62, inHeightInt=100, inWidthInt=90)
lBox2 = Screen.BoxCreate(inTopInt=160, inLeftInt=160, inHeightInt=100, inWidthInt=100)
lBox3 = Screen.BoxCreate(inTopInt=460, inLeftInt=60, inHeightInt=100, inWidthInt=100)
l = Screen.BoxAnchorRuleCheck(inBox=lBox1, inAnchorBox=[lBox2,lBox3], inAnchorRuleStr=["LD","CUS"])
Screen.BoxDraw([lBox1,lBox2,lBox3])
:param inBox: Экземпляр класса прямоугольной области Box
:type inBox: pyscreeze.Box
:param inAnchorBox: Экземпляр класса прямоугольной области Box
:type inAnchorBox: pyscreeze.Box или list из pyscreeze.Box
:param inAnchorRuleStr: Символьное указание области проверки соответствия. Может принимать единственное значение (единый формат для всех inAnchorBox), или список форматов для каждого inAnchorBox (если inAnchorBox является списком Box)
:type inAnchorRuleStr: str или list из str
:return: True - соответствует всем правилам
:rtype: bool
"""
# Формирование стартовых переменных
if inAnchorBox is None: inAnchorBox = []
if type(inAnchorBox) is not list:
inAnchorBox = [inAnchorBox]
lAnchorRuleStr = "CC,S"
if inAnchorRuleStr is None or inAnchorRuleStr=="": inAnchorRuleStr = [lAnchorRuleStr]
if type(inAnchorRuleStr) is not list:
inAnchorRuleStr = [inAnchorRuleStr]
lResult = True
# Дополнение списка правил до длины якорей, если они расходятся и список правил равен длине 1 или 0 (по умолчанию CC,S)
if len(inAnchorRuleStr)==1 and len(inAnchorBox)==1:
if inAnchorRuleStr[0]=="" or inAnchorRuleStr[0] is None:
inAnchorRuleStr = [lAnchorRuleStr]
elif len(inAnchorRuleStr)==1 and len(inAnchorBox)!=1:
if inAnchorRuleStr[0]!="" and inAnchorRuleStr[0] is not None:
lAnchorRuleStr = inAnchorRuleStr[0]
if len(inAnchorRuleStr) != len(inAnchorBox):
inAnchorRuleStr = []
for lItem in inAnchorBox:
inAnchorRuleStr.append(lAnchorRuleStr)
for lIndexInt, lItemBox in enumerate(inAnchorBox): # Остановиться, если итог False
lItemRuleStr = inAnchorRuleStr[lIndexInt].upper()
print(lItemRuleStr)
# Подготовка вспомогательных областей
lScreenWidthPXInt = 9999
lScreenHeightPXInt = 5555
lAnchorLUBox = BoxCreate(inTopInt=0, inLeftInt=0, inHeightInt=lItemBox.top, inWidthInt=lItemBox.left)
lAnchorRUBox = BoxCreate(inTopInt=0, inLeftInt=lItemBox.left+lItemBox.width, inHeightInt=lItemBox.top, inWidthInt=lScreenWidthPXInt)
lAnchorCUBox = BoxCreate(inTopInt=0, inLeftInt=lItemBox.left, inHeightInt=lItemBox.top, inWidthInt=lItemBox.width)
lAnchorLCBox = BoxCreate(inTopInt=lItemBox.top, inLeftInt=0, inHeightInt=lItemBox.height, inWidthInt=lItemBox.left)
lAnchorRCBox = BoxCreate(inTopInt=lItemBox.top, inLeftInt=lItemBox.left+lItemBox.width, inHeightInt=lItemBox.height, inWidthInt=lScreenWidthPXInt)
lAnchorLDBox = BoxCreate(inTopInt=lItemBox.top+lItemBox.height, inLeftInt=0, inHeightInt=lScreenHeightPXInt, inWidthInt=lItemBox.left)
lAnchorRDBox = BoxCreate(inTopInt=lItemBox.top+lItemBox.height, inLeftInt=lItemBox.left+lItemBox.width, inHeightInt=lScreenHeightPXInt, inWidthInt=lScreenWidthPXInt)
lAnchorCDBox = BoxCreate(inTopInt=lItemBox.top+lItemBox.height, inLeftInt=lItemBox.left, inHeightInt=lScreenHeightPXInt, inWidthInt=lItemBox.width)
#import pdb
#pdb.set_trace()
if "S" not in lItemRuleStr: # Проверка без S - Strict
lResult = False
# Алгоритм проверки соответствия хотя бы на одно вхождение
if ("CC" in lItemRuleStr) and BoxOverlay(inBox1=inBox, inBox2=lItemBox)==True: lResult = True
elif ("LU" in lItemRuleStr) and BoxOverlay(inBox1=inBox, inBox2=lAnchorLUBox)==True: lResult = True
elif ("RU" in lItemRuleStr) and BoxOverlay(inBox1=inBox, inBox2=lAnchorRUBox)==True: lResult = True
elif ("CU" in lItemRuleStr) and BoxOverlay(inBox1=inBox, inBox2=lAnchorCUBox)==True: lResult = True
elif ("LC" in lItemRuleStr) and BoxOverlay(inBox1=inBox, inBox2=lAnchorLCBox)==True: lResult = True
elif ("RC" in lItemRuleStr) and BoxOverlay(inBox1=inBox, inBox2=lAnchorRCBox)==True: lResult = True
elif ("LD" in lItemRuleStr) and BoxOverlay(inBox1=inBox, inBox2=lAnchorLDBox)==True: lResult = True
elif ("RD" in lItemRuleStr) and BoxOverlay(inBox1=inBox, inBox2=lAnchorRDBox)==True: lResult = True
elif ("CD" in lItemRuleStr) and BoxOverlay(inBox1=inBox, inBox2=lAnchorCDBox)==True: lResult = True
if lResult == False: break # Остановиться, если итог False
else: # Проверка с S - Strict
lResult = True
# Алгоритм проверки соответствия хотя бы на одно вхождение для того сегмента, который недоступен
if ("CC" not in lItemRuleStr) and BoxOverlay(inBox1=inBox, inBox2=lItemBox)==True: lResult = False
elif ("LU" not in lItemRuleStr) and BoxOverlay(inBox1=inBox, inBox2=lAnchorLUBox)==True: lResult = False
elif ("RU" not in lItemRuleStr) and BoxOverlay(inBox1=inBox, inBox2=lAnchorRUBox)==True: lResult = False
elif ("CU" not in lItemRuleStr) and BoxOverlay(inBox1=inBox, inBox2=lAnchorCUBox)==True: lResult = False
elif ("LC" not in lItemRuleStr) and BoxOverlay(inBox1=inBox, inBox2=lAnchorLCBox)==True: lResult = False
elif ("RC" not in lItemRuleStr) and BoxOverlay(inBox1=inBox, inBox2=lAnchorRCBox)==True: lResult = False
elif ("LD" not in lItemRuleStr) and BoxOverlay(inBox1=inBox, inBox2=lAnchorLDBox)==True: lResult = False
elif ("RD" not in lItemRuleStr) and BoxOverlay(inBox1=inBox, inBox2=lAnchorRDBox)==True: lResult = False
elif ("CD" not in lItemRuleStr) and BoxOverlay(inBox1=inBox, inBox2=lAnchorCDBox)==True: lResult = False
if lResult == False: break # Остановиться, если итог False
return lResult
def BoxOverlay(inBox1, inBox2) -> bool:
"""Проверить наложение 2-х прямоугольных областей друг на друга.
.. code-block:: python
# Screen: Взаимодействие с экраном
from pyOpenRPA.Robot import Screen
lBox1 = Screen.BoxCreate(inTopInt=10, inLeftInt=10, inHeightInt=100, inWidthInt=1000)
lBox2 = Screen.BoxCreate(inTopInt=160, inLeftInt=160, inHeightInt=100, inWidthInt=100)
Screen.BoxDraw([lBox1, lBox2])
Screen.BoxOverlay(lBox1,lBox2)
:param inBox1: Экземпляр класса прямоугольной области Box
:type inBox1: pyscreeze.Box
:param inBox2: Экземпляр класса прямоугольной области Box
:type inBox2: pyscreeze.Box
:return: True - inBox1 наложен на inBox2
:rtype: bool
"""
return not ((inBox1.left>inBox2.left + inBox2.width or inBox2.left>inBox1.left + inBox1.width) or (inBox1.top>inBox2.top + inBox2.height or inBox2.top>inBox1.top + inBox1.height))

@ -2,7 +2,7 @@
"cells": [ "cells": [
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 2, "execution_count": 1,
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
@ -16,20 +16,18 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 3, "execution_count": 1,
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
{ {
"name": "stdout", "ename": "NameError",
"output_type": "stream", "evalue": "name 'Screen' is not defined",
"text": [ "output_type": "error",
"Box(left=10, top=10, width=100, height=100)\n", "traceback": [
"Box(left=110, top=210, width=100, height=100)\n", "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
"Box(left=115, top=215, width=90, height=90)\n", "\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)",
"Box(left=110, top=210, width=90, height=90)\n", "\u001b[1;32m<ipython-input-1-e5d2939d0bc7>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;31m# Создать пробную прямоугольную область\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 2\u001b[1;33m \u001b[0mlBox\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mScreen\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mBoxCreate\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0minTopInt\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m10\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0minLeftInt\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m10\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0minHeightInt\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m100\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0minWidthInt\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m100\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 3\u001b[0m \u001b[0mlBoxX\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mScreen\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mBoxCreate\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0minTopInt\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m60\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0minLeftInt\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m60\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0minHeightInt\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m100\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0minWidthInt\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m100\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 4\u001b[0m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mlBox\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[1;31m# Переместить пробную прямоугольную область\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
"Box(left=110, top=220, width=90, height=90)\n", "\u001b[1;31mNameError\u001b[0m: name 'Screen' is not defined"
"Box(left=120, top=210, width=90, height=90)\n",
"Box(left=120, top=220, width=90, height=90)\n"
] ]
} }
], ],
@ -99,22 +97,61 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 7, "execution_count": 1,
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
{ {
"data": { "data": {
"text/plain": [ "text/plain": [
"True" "False"
] ]
}, },
"execution_count": 7, "execution_count": 1,
"metadata": {}, "metadata": {},
"output_type": "execute_result" "output_type": "execute_result"
} }
], ],
"source": [ "source": [
"type([]) is list" "type([]) is not list"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"def BoxOverlay(inBox1, inBox2) -> bool:\n",
"\n",
" return not (inBox1.left>inBox2.left + inBox2.width or inBox2.left>inBox1.left + inBox1.width) or (inBox1.top>inBox2.top + inBox2.height or inBox2.top>inBox1.top + inBox1.height)"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"LD\n",
"CUS\n",
"True\n"
]
}
],
"source": [
"lBox1 = Screen.BoxCreate(inTopInt=265, inLeftInt=62, inHeightInt=100, inWidthInt=90)\n",
"lBox2 = Screen.BoxCreate(inTopInt=160, inLeftInt=160, inHeightInt=100, inWidthInt=100)\n",
"lBox3 = Screen.BoxCreate(inTopInt=460, inLeftInt=60, inHeightInt=100, inWidthInt=100)\n",
"\n",
"lScreenWidthPXInt = 2000\n",
"lScreenHeightPXInt = 1000\n",
"\n",
"l = Screen.BoxAnchorRuleCheck(inBox=lBox1, inAnchorBox=[lBox2,lBox3], inAnchorRuleStr=[\"LD\",\"CUS\"])\n",
"Screen.BoxDraw([lBox1,lBox2,lBox3])\n",
"print(l)"
] ]
}, },
{ {

Loading…
Cancel
Save