[英]How to run python program in background to keep active window the same
我编写了一个程序,它将前景窗口更改为监视器尺寸的 85%,并且要成功运行,前景窗口需要保持不变。
我已将python脚本(.pyw)放入批处理文件(运行pythonw)并在桌面上创建了批处理文件的快捷方式,并带有快捷方式以快速运行它。 我还让它运行了最小化的批处理文件,但它仍然将前台窗口切换到最小化的命令提示符。
根据下面的 python 代码,我使用 pywin32 进行窗口操作。 我得到了显示器的信息,因为我有一个三显示器设置,所以需要考虑适当显示器的坐标。
#! python
import win32api
import win32gui
import win32con
monitors = win32api.EnumDisplayMonitors()
monitorsDict = {}
hwnd = win32gui.GetForegroundWindow()
currentWindowDimensions = win32gui.GetWindowRect(hwnd)
monitorInFocus = str(win32api.MonitorFromWindow(hwnd))
for i in range(len(monitors)):
monitorsDict[str(monitors[i][0])] = monitors[i][2]
maxWidth = (monitorsDict[monitorInFocus][2]-monitorsDict[monitorInFocus][0]) * .85
maxHeight = (monitorsDict[monitorInFocus][3]-monitorsDict[monitorInFocus][1]) * .85
x = int(currentWindowDimensions[0])
y = int(currentWindowDimensions[1])
newWidth = int(maxWidth + x)
newHeight = int(maxHeight + y)
newDimensions = (x, y, newWidth, newHeight)
win32gui.SetWindowPos(hwnd, win32con.HWND_NOTOPMOST, x, y, newWidth, newHeight, 0)
批处理文件如下:
C:\path\to\pythonw\executable\pythonw.exe C:\path\to\pyw\script\WindowSizing.pyw
我的印象是,如果我运行 pythonw 而不是 python,它将在后台运行脚本而不打开命令提示符窗口,但这似乎没有发生。 因为命令提示符是前台窗口,所以脚本会更改命令提示符窗口的大小,然后关闭它,导致我想调整大小的窗口没有变化。
pywin32 模块中有什么东西可以让我获得前一个前景窗口的句柄吗? 或者,有没有办法静默运行 python 脚本,这样前景窗口就不会改变?
尽管pythonw
确实在后台运行脚本而不打开命令提示符窗口,但您的批处理文件可以(即使此窗口已最小化)。 因此,您必须找到在执行批处理文件之前处于活动状态的窗口。
我们使用EnumWindows函数来迭代我们的普通(即可见和带有标题)窗口。 前一个窗口是枚举中的第二个窗口。 但是,如果您从批处理文件运行 python 脚本,命令提示符窗口(如上所述)将是前一个窗口,因此我们要查找的是枚举中的第三个窗口。
#! python
import win32api
import win32gui
import win32con
monitors = win32api.EnumDisplayMonitors()
monitorsDict = {}
window_counter = [0]
def enumWindowsProc(hwnd, param):
if win32gui.IsWindowVisible(hwnd) and win32gui.GetWindowTextLength(hwnd) > 0:
window_counter[0] += 1
print(win32gui.GetWindowText(hwnd))
if window_counter[0] == 3:
window_counter[0] = hwnd
return False
return True
try:
win32gui.EnumWindows(enumWindowsProc,window_counter)
except:
pass
hwnd = window_counter[0]
currentWindowDimensions = win32gui.GetWindowRect(hwnd)
monitorInFocus = str(win32api.MonitorFromWindow(hwnd))
for i in range(len(monitors)):
monitorsDict[str(monitors[i][0])] = monitors[i][2]
maxWidth = (monitorsDict[monitorInFocus][2]-monitorsDict[monitorInFocus][0]) * .85
maxHeight = (monitorsDict[monitorInFocus][3]-monitorsDict[monitorInFocus][1]) * .85
x = int(currentWindowDimensions[0])
y = int(currentWindowDimensions[1])
newWidth = int(maxWidth + x)
newHeight = int(maxHeight + y)
newDimensions = (x, y, newWidth, newHeight)
win32gui.SetWindowPos(hwnd, win32con.HWND_NOTOPMOST, x, y, newWidth, newHeight, 0)
EnumWindows
调用传递给它的回调函数,直到返回False
。 不幸的是,win32 实现中有一个错误:当回调返回False
, EnumWindows
返回0
并且这个0
被错误地认为是一个错误,python 将引发一个运行时错误。 一种解决方法是忽略此错误(如此处所示)或从不返回False
从而枚举窗口列表直到最后,尽管我们已经找到了我们的窗口。
除了使用批处理文件之外,还有一种更优雅的方式来调用脚本而无需创建额外的批处理文件:在桌面的快捷方式中,您只需插入一行C:\\path\\to\\pythonw\\executable\\pythonw.exe C:\\path\\to\\pyw\\script\\WindowSizing.pyw
作为目标。 但请记住,在这种情况下,我们需要查找窗口编号 2 而不是 3,因此它将是C:\\path\\to\\pythonw\\executable\\pythonw.exe C:\\path\\to\\pyw\\script\\WindowSizing.pyw
。
我在 Windows 7 上测试了这两种方法(批处理文件和直接快捷目标),它们都可以正常工作,通过快捷键调用或单击桌面上的图标。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.