gpt4 book ai didi

python - 如何使用 Python 在没有窗口的情况下在屏幕上显示文本

转载 作者:太空狗 更新时间:2023-10-29 16:55:17 24 4
gpt4 key购买 nike

问题:

我需要在没有窗口的情况下直接将文本写入屏幕。文本需要显示在所有其他窗口和全屏应用程序之上,并且不应以任何方式可点击或交互。

例子: Screenshot of text on the screen.文本不需要像示例中那样具有透明背景。我可以在 Windows 7 上使用 Python 2 或 3。

我的解决方案尝试:

我尝试使用 Tkinter 制作独立标签:

编辑:在 Christian Rapp 的帮助下改进

import Tkinter
label = Tkinter.Label(text='Text on the screen', font=('Times','30'), fg='black', bg='white')
label.master.overrideredirect(True)
label.master.geometry("+250+250")
label.master.lift()
label.master.wm_attributes("-topmost", True)
label.master.wm_attributes("-disabled", True)
label.master.wm_attributes("-transparentcolor", "white")
label.pack()
label.mainloop()

什么有效:

  • 文本显示时没有窗口
  • 文本保持在所有其他窗口之上
  • 背景可以是透明的

什么不是:

  • 文本不会在全屏应用程序上方显示
  • 文本会阻止在其上发生的点击事件
  • 背景透明度不是 alpha,因此存在硬边

最佳答案

事实证明这里有两个完全不同的问题。要在窗口上显示文本,您需要创建一个未修饰的最顶层窗口并为背景设置色度键。但是,当有全屏应用程序(例如游戏)正在运行时,这将不起作用。在全屏应用程序上显示文本的唯一可靠方法是使用 Direct3D Hook 。

我还没有编写 Direct3D Hook 示例,但我将为第一个问题提供两种不同的解决方案。

方案一:Tkinter + pywin32

在此示例中,我使用 Tkinter 完成大部分工作,并使用 win32api 来防止文本阻止鼠标点击。如果 win32api 对您不可用,那么您可以删除该部分代码。

import Tkinter, win32api, win32con, pywintypes

label = Tkinter.Label(text='Text on the screen', font=('Times New Roman','80'), fg='black', bg='white')
label.master.overrideredirect(True)
label.master.geometry("+250+250")
label.master.lift()
label.master.wm_attributes("-topmost", True)
label.master.wm_attributes("-disabled", True)
label.master.wm_attributes("-transparentcolor", "white")

hWindow = pywintypes.HANDLE(int(label.master.frame(), 16))
# http://msdn.microsoft.com/en-us/library/windows/desktop/ff700543(v=vs.85).aspx
# The WS_EX_TRANSPARENT flag makes events (like mouse clicks) fall through the window.
exStyle = win32con.WS_EX_COMPOSITED | win32con.WS_EX_LAYERED | win32con.WS_EX_NOACTIVATE | win32con.WS_EX_TOPMOST | win32con.WS_EX_TRANSPARENT
win32api.SetWindowLong(hWindow, win32con.GWL_EXSTYLE, exStyle)

label.pack()
label.mainloop()

方案二:pywin32

此示例通过 pywin32 完成所有操作。这使得它更复杂,更不便携,但功能更强大。我在整个代码中包含了指向 Windows API 相关部分的链接。

import win32api, win32con, win32gui, win32ui

def main():
hInstance = win32api.GetModuleHandle()
className = 'MyWindowClassName'

# http://msdn.microsoft.com/en-us/library/windows/desktop/ms633576(v=vs.85).aspx
# win32gui does not support WNDCLASSEX.
wndClass = win32gui.WNDCLASS()
# http://msdn.microsoft.com/en-us/library/windows/desktop/ff729176(v=vs.85).aspx
wndClass.style = win32con.CS_HREDRAW | win32con.CS_VREDRAW
wndClass.lpfnWndProc = wndProc
wndClass.hInstance = hInstance
wndClass.hCursor = win32gui.LoadCursor(None, win32con.IDC_ARROW)
wndClass.hbrBackground = win32gui.GetStockObject(win32con.WHITE_BRUSH)
wndClass.lpszClassName = className
# win32gui does not support RegisterClassEx
wndClassAtom = win32gui.RegisterClass(wndClass)

# http://msdn.microsoft.com/en-us/library/windows/desktop/ff700543(v=vs.85).aspx
# Consider using: WS_EX_COMPOSITED, WS_EX_LAYERED, WS_EX_NOACTIVATE, WS_EX_TOOLWINDOW, WS_EX_TOPMOST, WS_EX_TRANSPARENT
# The WS_EX_TRANSPARENT flag makes events (like mouse clicks) fall through the window.
exStyle = win32con.WS_EX_COMPOSITED | win32con.WS_EX_LAYERED | win32con.WS_EX_NOACTIVATE | win32con.WS_EX_TOPMOST | win32con.WS_EX_TRANSPARENT

# http://msdn.microsoft.com/en-us/library/windows/desktop/ms632600(v=vs.85).aspx
# Consider using: WS_DISABLED, WS_POPUP, WS_VISIBLE
style = win32con.WS_DISABLED | win32con.WS_POPUP | win32con.WS_VISIBLE

# http://msdn.microsoft.com/en-us/library/windows/desktop/ms632680(v=vs.85).aspx
hWindow = win32gui.CreateWindowEx(
exStyle,
wndClassAtom,
None, # WindowName
style,
0, # x
0, # y
win32api.GetSystemMetrics(win32con.SM_CXSCREEN), # width
win32api.GetSystemMetrics(win32con.SM_CYSCREEN), # height
None, # hWndParent
None, # hMenu
hInstance,
None # lpParam
)

# http://msdn.microsoft.com/en-us/library/windows/desktop/ms633540(v=vs.85).aspx
win32gui.SetLayeredWindowAttributes(hWindow, 0x00ffffff, 255, win32con.LWA_COLORKEY | win32con.LWA_ALPHA)

# http://msdn.microsoft.com/en-us/library/windows/desktop/dd145167(v=vs.85).aspx
#win32gui.UpdateWindow(hWindow)

# http://msdn.microsoft.com/en-us/library/windows/desktop/ms633545(v=vs.85).aspx
win32gui.SetWindowPos(hWindow, win32con.HWND_TOPMOST, 0, 0, 0, 0,
win32con.SWP_NOACTIVATE | win32con.SWP_NOMOVE | win32con.SWP_NOSIZE | win32con.SWP_SHOWWINDOW)

# http://msdn.microsoft.com/en-us/library/windows/desktop/ms633548(v=vs.85).aspx
#win32gui.ShowWindow(hWindow, win32con.SW_SHOW)

win32gui.PumpMessages()

def wndProc(hWnd, message, wParam, lParam):
if message == win32con.WM_PAINT:
hdc, paintStruct = win32gui.BeginPaint(hWnd)

dpiScale = win32ui.GetDeviceCaps(hdc, win32con.LOGPIXELSX) / 60.0
fontSize = 80

# http://msdn.microsoft.com/en-us/library/windows/desktop/dd145037(v=vs.85).aspx
lf = win32gui.LOGFONT()
lf.lfFaceName = "Times New Roman"
lf.lfHeight = int(round(dpiScale * fontSize))
#lf.lfWeight = 150
# Use nonantialiased to remove the white edges around the text.
# lf.lfQuality = win32con.NONANTIALIASED_QUALITY
hf = win32gui.CreateFontIndirect(lf)
win32gui.SelectObject(hdc, hf)

rect = win32gui.GetClientRect(hWnd)
# http://msdn.microsoft.com/en-us/library/windows/desktop/dd162498(v=vs.85).aspx
win32gui.DrawText(
hdc,
'Text on the screen',
-1,
rect,
win32con.DT_CENTER | win32con.DT_NOCLIP | win32con.DT_SINGLELINE | win32con.DT_VCENTER
)
win32gui.EndPaint(hWnd, paintStruct)
return 0

elif message == win32con.WM_DESTROY:
print 'Closing the window.'
win32gui.PostQuitMessage(0)
return 0

else:
return win32gui.DefWindowProc(hWnd, message, wParam, lParam)


if __name__ == '__main__':
main()

关于python - 如何使用 Python 在没有窗口的情况下在屏幕上显示文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21840133/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com