作為一枚游戲測試抵拘,日常工作的時候,經(jīng)常需要同時開著多個游戲賬號進行測試述呐。
以Unity打包出來的PC客戶端為例馏谨,每次都需要雙擊運行exe程序,等著游戲啟動后物舒,因為同時開著多個客戶端,所以還需要拖動客戶端,來調(diào)整游戲在屏幕上的位置闻牡,防止遮擋,方便查看绳矩。
操作流程差不多就像這樣子(本文用記事本來替代游戲客戶端):
這個操作其實還是挺繁瑣的罩润,尤其你開了3個以上客戶端的時候,能不能將上邊的操作做成工具來自動完成呢翼馆?
首先我們分析下這個操作的流程
那接下來用Python各個擊破吧~
啟動游戲
啟動游戲只需要一句代碼~
subprocess.Popen(r"C:\Windows\system32\notepad.exe")
subprocess
是Python自帶的子進程管理模塊割以,定義有數(shù)個創(chuàng)建子進程的函數(shù),也提供了一些管理標準流(standard stream)和管道(pipe)的工具应媚,從而在進程間使用文本通信严沥。簡單理解就是,通過CMD敲的命令中姜,都基本可以用subprocess來實現(xiàn)批量處理消玄。
計算客戶端的坐標位置
基本思路:
- 確認游戲的窗口大小,如800*450
- 計算整個屏幕大小丢胚,可以放多少個800*450的客戶端翩瓜,并計算出每個客戶端的坐標位置
如何獲取屏幕大小呢?Python在Windows平臺有一個庫叫pywin32携龟,它為Python提供訪問Windows API的擴展兔跌,提供了齊全的Windows常量、接口峡蟋、線程以及COM機制等坟桅。
安裝pywin32相满,在sourceforge下載對于你電腦Py版本的exe安裝包,直接運行即可桦卒。
pywin32提供了一個方法win32gui.GetClientRect
立美,可以獲取窗口坐標及大小,只需要將桌面窗口句柄作為參數(shù)傳進去即可方灾。
所以獲取桌面分辨率的方式就是:
_, _, width, height = win32gui.GetClientRect(win32gui.GetDesktopWindow())
接下來就是計算在桌面上建蹄,可以擺放多少個游戲客戶端了,就像下圖這個樣子裕偿。
這個不復雜洞慎,就直接上代碼了,計算出桌面可以擺放的客戶端的左上角坐標嘿棘,保存到一個列表里邊備用
game_width = 450
game_height = 800
_, _, width, height = win32gui.GetClientRect(win32gui.GetDesktopWindow())
x_num = int(width / game_width)
y_num = int(height / game_height)
result = list()
for y in range(y_num):
for x in range(x_num):
result.append((x * game_width, y * game_height, game_width, game_height))
print(result)
output: [(0, 0, 450, 800), (450, 0, 450, 800), (900, 0, 450, 800), (1350, 0, 450, 800)]
調(diào)整窗口大小并拖動到指定位置
win32gui.MoveWindow(hwnd, x, y, width, height, bRepaint)
提供了一個移動窗口的方式劲腿,函數(shù)的幾個參數(shù)分別表示句柄,起始點x坐標鸟妙,y坐標焦人,寬度,高度重父,是否重繪界面花椭。
app_pid = subprocess.Popen(r"C:\Windows\system32\notepad.exe").pid # 獲取進程pid
time.sleep(1)
hwnd_list = []
win32gui.EnumWindows(lambda _hwnd, _hwnd_list: _hwnd_list.append(_hwnd), hwnd_list) # 獲取當前全部的窗口句柄
app_hwnd = None
for hwnd in hwnd_list:
hid, pid = win32process.GetWindowThreadProcessId(hwnd) # 根據(jù)窗口句柄取出窗口的hid和pid
if pid == app_pid:
app_hwnd = hwnd
break
if not app_hwnd:
raise Exception("沒有找到hwnd")
app_position = result.pop(0)
win32gui.MoveWindow(app_hwnd, *app_position, True) # 移動窗口位置
再封裝下
import win32gui
import win32process
import subprocess
import time
def calculate_app_positions(app_width, app_height, scale):
_, _, width, height = win32gui.GetClientRect(win32gui.GetDesktopWindow())
final_app_width = int(app_width * scale)
final_app_height = int(app_height * scale)
x_num = int(width / final_app_width)
y_num = int(height / final_app_height)
positions = list()
for y in range(y_num):
for x in range(x_num):
positions.append((x * final_app_width, y * final_app_height, final_app_width, final_app_height))
return positions
def start_app(app_path, num, app_width, app_height, scale):
app_positions = calculate_app_positions(app_width, app_height, scale)
for i in range(num):
app_pid = subprocess.Popen(app_path).pid # 獲取進程pid
time.sleep(1)
hwnd_list = []
win32gui.EnumWindows(lambda _hwnd, _hwnd_list: _hwnd_list.append(_hwnd), hwnd_list) # 獲取當前全部的窗口句柄
app_hwnd = None
for hwnd in hwnd_list:
hid, pid = win32process.GetWindowThreadProcessId(hwnd) # 根據(jù)窗口句柄取出窗口的hid和pid
if pid == app_pid:
app_hwnd = hwnd
break
if not app_hwnd:
raise Exception("沒有找到hwnd")
app_position = app_positions.pop(0)
win32gui.MoveWindow(app_hwnd, *app_position, True) # 移動窗口位置
if __name__ == '__main__':
app_path = r"C:\Windows\system32\notepad.exe"
app_width = 450
app_height = 800
result = input("輸入要打開的客戶端數(shù)量和顯示比例,默認比例是1.0房午,例子:3 0.75\n")
result = result.split()
if len(result) == 2:
num, scale = result
else:
num = result[0]
scale = 1
start_app(app_path, int(num), app_width, app_height, float(scale))
最終運行效果~