def EnumWindows(self, selector): names = [] # 一个应用程序会有多个窗口,因此我们要先枚举一个应用程序里的所有窗口 if 'bundleid' in selector: self.app = OSXFunc.getAppRefByBundleId(selector['bundleid']) windows = self.app.windows() for i, w in enumerate(windows): names.append((w.AXTitle, i)) return names if 'appname' in selector: self.app = OSXFunc.getAppRefByLocalizedName(selector['appname']) windows = self.app.windows() for i, w in enumerate(windows): names.append((w.AXTitle, i)) return names if 'appname_re' in selector: # 此方法由于MacOS API,问题较多 apps = OSXFunc.getRunningApps() # 获取当前运行的所有应用程序 appset = [] # 应用程序集合 appnameset = set() # 应用程序标题集合 for t in apps: tempapp = OSXFunc.getAppRefByPid(t.processIdentifier()) if str(tempapp) == str(atomac.AXClasses.NativeUIElement() ): # 通过trick判断应用程序是都否为空 continue attrs = tempapp.getAttributes() if 'AXTitle' in attrs: tit = tempapp.AXTitle if re.match(selector['appname_re'], tit): appset.append(tempapp) appnameset.add( tit) # 这里有Bug,可能会获取到进程的不同副本,所以要通过名字去判断是否唯一 if len(appnameset) is 0: raise InvalidSurfaceException( selector, "Can't find any applications by the given parameter") if len(appnameset) != 1: raise NonuniqueSurfaceException(selector) while len(names) is 0: # 有可能有多个副本,但只有一个真的应用程序有窗口,所以要枚举去找 if len(appset) is 0: return names self.app = appset.pop() windows = self.app.windows() # 获取当前应用程序的所有窗口 for i, w in enumerate(windows): names.append((w.AXTitle, i)) return names return names
def Scroll(self, direction, percent, duration): if direction not in ('vertical', 'horizontal'): raise ValueError( 'Argument `direction` should be one of "vertical" or "horizontal". Got {}' .format(repr(direction))) x = 0.5 # 先把鼠标移到窗口中间,这样才能保证滚动的是这个窗口。 y = 0.5 steps = percent Left = self.GetWindowRect()[0] Top = self.GetWindowRect()[1] Width = self.GetScreenSize()[0] Height = self.GetScreenSize()[1] x = Left + Width * x y = Top + Height * y x = int(x) y = int(y) OSXFunc.move(x, y) if direction == 'horizontal': interval = float(duration) / (abs(steps) + 1) if steps < 0: for i in range(0, abs(steps)): time.sleep(interval) OSXFunc.scroll(None, 1) else: for i in range(0, abs(steps)): time.sleep(interval) OSXFunc.scroll(None, -1) else: interval = float(duration) / (abs(steps) + 1) if steps < 0: for i in range(0, abs(steps)): time.sleep(interval) OSXFunc.scroll(1) else: for i in range(0, abs(steps)): time.sleep(interval) OSXFunc.scroll(-1) return True
def Swipe(self, x1, y1, x2, y2, duration): self.SetForeground() Left = self.root.AXPosition[0] Top = self.root.AXPosition[1] Width = self.root.AXSize[0] Height = self.root.AXSize[1] x1 = Left + Width * x1 y1 = Top + Height * y1 x2 = Left + Width * x2 y2 = Top + Height * y2 sx = abs(x1 - x2) sy = abs(y1 - y2) stepx = sx / (duration * 10.0) # 将滑动距离分割,实现平滑的拖动 stepy = sy / (duration * 10.0) OSXFunc.move(x1, y1) OSXFunc.press(x1, y1) duration = int(duration * 10.0) for i in range(duration + 1): OSXFunc.drag(x1 + stepx * i, y1 + stepy * i) time.sleep(0.1) OSXFunc.release(x2, y2) return True
def LongClick(self, x, y, duration, **kwargs): self.SetForeground() # poco std暂不支持选择鼠标按键 button = kwargs.get("button", "left") if button not in ("left", "right"): raise ValueError("Unknow button: " + button) if button is "left": button = 1 else: button = 2 Left = self.root.AXPosition[0] Top = self.root.AXPosition[1] Width = self.root.AXSize[0] Height = self.root.AXSize[1] x = Left + Width * x y = Top + Height * y OSXFunc.move(x, y) OSXFunc.press(x, y, button=button) time.sleep(duration) OSXFunc.release(x, y, button=button) return True
def DoubleClick(self, x, y): self.SetForeground() size = self.root.AXSize pos = self.root.AXPosition OSXFunc.doubleclick(pos[0] + size[0] * x, pos[1] + size[1] * y) return True