You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ORPA-pyOpenRPA/Sources/pyOpenRPA/Robot/Screen.py

197 lines
10 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

from pyautogui import *
import pyscreeze
import ctypes
from pyOpenRPA.Tools import CrossOS
if CrossOS.IS_WINDOWS_BOOL:
from pywinauto import win32defines, win32structures, win32functions
def BoxCreate(inTopInt:int, inLeftInt:int, inHeightInt:int, inWidthInt:int) -> pyscreeze.Box:
"""Создать экземпляр прямоугольной области.
!ВНИМАНИЕ! Координаты inTopInt, inLeftInt определяют верхний левый край прямоугольной области.
:param inTopInt: Координата левой верхней точки в пикселях по оси X (горизонталь)
:type inTopInt: int
:param inLeftInt: Координата левой верхней точки в пикселях по оси Y (вертикаль)
:type inLeftInt: int
:param inHeightInt: Расстояние вниз от левой верхней точки в пикселях
:type inHeightInt: int
:param inWidthInt: Расстояние вправо от левой верхней точки в пикселях
:type inWidthInt: int
"""
return pyscreeze.Box(top = inTopInt, left = inLeftInt, height = inHeightInt, width = inWidthInt)
def BoxNormalize(*inArgList, **inAgrDict) -> list:
pass
def BoxMoveTo(inBox, inDXInt=None, inDYInt=None):
"""Переместить прямоугольную область (сохранить длину/ширину).
!ВНИМАНИЕ! ПОДДЕРЖИВАЕТ ПАКЕТНУЮ ОБРАТКУ ПРИ ПЕРЕДАЧЕ СПИСКА ЭКЗЕМПЛЯРОВ BOX
.. code-block:: python
# Screen: Взаимодействие с экраном
from pyOpenRPA.Robot import Screen
# Вариант изменения 1-го элемента
# Создать пробную прямоугольную область
lBox = Screen.BoxCreate(inTopInt=10, inLeftInt=10, inHeightInt=10, inWidthInt=10)
# Переместить пробную прямоугольную область
lBox = Screen.BoxMoveTo(lBox, inDXInt=100, inDYInt=200)
:param inBox: Экземпляр класса прямоугольной области Box
:type inBox: pyscreeze.Box
:param inDXInt: Смещение левой верхней координаты по оси X в пикселях (горизонтальная ось).
:type inDXInt: int, опциональный
:param inDYInt: Смещение левой верхней координаты по оси Y в пикселях (вертикальная ось).
:type inDYInt: int, опциональный
:return: Экземпляр класса прямоугольной области Box
:rtype: pyscreeze.Box
"""
if type(inBox) is list:
lResult = []
for lBox in inBox:
lResult.append(BoxMoveTo(lBox, inDXInt=inDXInt, inDYInt=inDYInt))
return lResult
else:
lTopInt = inBox.top
lLeftInt = inBox.left
if inDXInt: lLeftInt = inBox.left + inDXInt
if inDYInt: lTopInt = inBox.top + inDYInt
return BoxCreate(inTopInt=lTopInt, inLeftInt=lLeftInt,
inHeightInt=inBox.height, inWidthInt=inBox.width)
def BoxModify(inBox, inDWidthInt=None, inDHeightInt=None, inAnchorStr="CC"):
"""Изменить ширину / высоту прямоугольной области.
!ВНИМАНИЕ! ПОДДЕРЖИВАЕТ ПАКЕТНУЮ ОБРАТКУ ПРИ ПЕРЕДАЧЕ СПИСКА ЭКЗЕМПЛЯРОВ BOX
!ВНИМАНИЕ! ЕСЛИ СМЕЩЕНИЕ ПРИВЕДЕТ К ОБРАЗОВАНИЮ ДРОБНОГО ЧИСЛА, БУДЕТ ВЫПОЛНЕНО ОКРУГЛЕНИЕ ПО МАТЕМАТИЧЕСКИМ ПРАВИЛАМ
.. code-block:: python
# Screen: Взаимодействие с экраном
from pyOpenRPA.Robot import Screen
# Вариант изменения 1-го элемента
# Создать пробную прямоугольную область
lBox = Screen.BoxCreate(inTopInt=10, inLeftInt=10, inHeightInt=10, inWidthInt=10)
# Скорректировать пробную прямоугольную область
lBox2 = Screen.BoxModify(lBox,10,10,"CC"); print(lBox2)
lBox2 = Screen.BoxModify(lBox,10,10,"LU"); print(lBox2)
lBox2 = Screen.BoxModify(lBox,10,10,"LD"); print(lBox2)
lBox2 = Screen.BoxModify(lBox,10,10,"RU"); print(lBox2)
lBox2 = Screen.BoxModify(lBox,10,10,"RD"); print(lBox2)
:param inBox: Экземпляр класса прямоугольной области Box
:type inBox: pyscreeze.Box
:param inDXInt: Смещение левой верхней координаты по оси X в пикселях (горизонтальная ось).
:type inDXInt: int, опциональный
:param inDYInt: Смещение левой верхней координаты по оси Y в пикселях (вертикальная ось).
:type inDYInt: int, опциональный
:param inAnchorStr: Символьное указание точки (подробнее см. выше), относительно которой выполнить изменение прямоугольной области. Допустимые значения: "CC" (по умолчанию), "LU", "LD", "RD", "RU"
:type inAnchorStr: str, опциональный
:return: Экземпляр класса прямоугольной области Box
:rtype: pyscreeze.Box
"""
if type(inBox) is list:
lResult = []
for lBox in inBox:
lResult.append(BoxModify(lBox, inDWidthInt=inDWidthInt, inDHeightInt=inDHeightInt, inAnchorStr=inAnchorStr))
return lResult
else:
lTopInt = inBox.top
lLeftInt = inBox.left
lWidthInt = inBox.width + inDWidthInt
lHeightInt = inBox.height + inDHeightInt
inAnchorStr = inAnchorStr.upper() # ВЕРХНИЙ РЕГИСТР
if inDWidthInt: # Изменения по ширине
if "C" in inAnchorStr:
lLeftInt = round(lLeftInt - inDWidthInt / 2)
elif "R" in inAnchorStr:
lLeftInt = lLeftInt - inDWidthInt
if inDHeightInt: # Изменения по высоте
if "C" in inAnchorStr:
lTopInt = round(lTopInt - inDHeightInt / 2)
elif "D" in inAnchorStr:
lTopInt = lTopInt - inDHeightInt
return BoxCreate(inTopInt=lTopInt, inLeftInt=lLeftInt,
inHeightInt=lHeightInt, inWidthInt=lWidthInt)
def BoxDraw(inBox, inColorStr='green',inThicknessInt = 2):
""" Выполнить подсветку прямоугольной области inBox на экране
!ВНИМАНИЕ! РАБОТАЕТ ТОЛЬКО НА ОС WINDOWS
!ВНИМАНИЕ! ПОДДЕРЖИВАЕТ ПАКЕТНУЮ ОБРАТКУ ПРИ ПЕРЕДАЧЕ СПИСКА ЭКЗЕМПЛЯРОВ BOX
.. code-block:: python
# Screen: Взаимодействие с экраном
from pyOpenRPA.Robot import Screen
# ВАРИАНТ ОТРИСОВКИ 1ГО ЭЛЕМЕНТА
# Создать пробную прямоугольную область
lBox = Screen.BoxCreate(inTopInt=10, inLeftInt=10, inHeightInt=10, inWidthInt=10)
Screen.BoxDraw(lBox)
# ВАРИАНТ ПАКЕТНОЙ ОТРИСОВКИ
# Создать пробную прямоугольную область
lBox = Screen.BoxCreate(inTopInt=10, inLeftInt=10, inHeightInt=100, inWidthInt=100)
lBox2 = Screen.BoxCreate(inTopInt=60, inLeftInt=60, inHeightInt=100, inWidthInt=100)
Screen.BoxDraw([lBox, lBox2])
:param inBox: UIO объект, который будет подсвечен
:type inBox: object UIO, обязательный
:param inColorStr: цвет подсветки UIO объекта. Варианты: 'red', 'green', 'blue'. По умолчанию 'green'
:type inColorStr: str, необязательный
:param inThicknessInt: толщина подсветки UIO объекта. По умолчанию 2
:type inThicknessInt: int, необязательный
"""
if type(inBox) is list:
for lBox in inBox:
BoxDraw(inBox=lBox, inColorStr=inColorStr,inThicknessInt = inThicknessInt)
else:
fill = win32defines.BS_NULL
if inBox is not None:
"""
Draw an outline around the window.
* **inColorStr** can be either an integer or one of 'red', 'green', 'blue'
(default 'green')
* **inThicknessInt** inThicknessInt of rectangle (default 2)
* **fill** how to fill in the rectangle (default BS_NULL)
"""
# don't draw if dialog is not visible
#if not lWrapperObject.is_visible():
# return
colours = {
"green": 0x00ff00,
"blue": 0xff0000,
"red": 0x0000ff,
}
# if it's a known colour
if inColorStr in colours:
inColorStr = colours[inColorStr]
# create the pen(outline)
pen_handle = win32functions.CreatePen(
win32defines.PS_SOLID, inThicknessInt, inColorStr)
# create the brush (inside)
brush = win32structures.LOGBRUSH()
brush.lbStyle = fill
brush.lbHatch = win32defines.HS_DIAGCROSS
brush_handle = win32functions.CreateBrushIndirect(ctypes.byref(brush))
# get the Device Context
dc = win32functions.CreateDC("DISPLAY", None, None, None )
# push our objects into it
win32functions.SelectObject(dc, brush_handle)
win32functions.SelectObject(dc, pen_handle)
# draw the rectangle to the DC
win32functions.Rectangle(
dc, inBox.left, inBox.top, inBox.left+inBox.width, inBox.top+inBox.height)
# Delete the brush and pen we created
win32functions.DeleteObject(brush_handle)
win32functions.DeleteObject(pen_handle)
# delete the Display context that we created
win32functions.DeleteDC(dc)