ventanas texto entry cuadro botones python windows user-interface text screen

entry - Cómo mostrar texto en la pantalla sin una ventana usando Python



entry python tkinter (1)

Resulta que hay dos problemas completamente diferentes aquí. Para mostrar texto en Windows, deberá crear una ventana superior sin decorar y la clave de croma el fondo. Sin embargo, esto no funcionará cuando se esté ejecutando una aplicación de pantalla completa (como un juego). La única forma confiable de mostrar texto en una aplicación de pantalla completa es usar un enlace Direct3D.

No he escrito un ejemplo de gancho Direct3D, pero daré dos soluciones diferentes para el primer problema.

Solución 1: Tkinter + pywin32

En este ejemplo, hago la mayoría del trabajo con Tkinter y uso win32api para evitar que el texto bloquee los clics del mouse. Si win32api no está disponible para usted, entonces puede simplemente eliminar esa parte del código.

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()

Solución 2: pywin32

Este ejemplo hace todo a través de pywin32. Esto lo hace más complicado y menos portátil, pero considerablemente más poderoso. He incluido enlaces a las partes relevantes de la API de Windows en todo el código.

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()

El problema:

Necesito escribir texto directamente en la pantalla sin una ventana. El texto debe aparecer sobre todas las demás ventanas y aplicaciones de pantalla completa y no debe poder hacer clic ni interactuar de ninguna manera.

Ejemplo: El texto no necesita tener un fondo transparente como se ve en el ejemplo. Puedo usar Python 2 o 3 en Windows 7.

Mi intento de solución:

Intenté hacer una etiqueta independiente usando Tkinter:

Editar: Mejorado con la ayuda de 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()

Que funciona:

  • El texto se muestra sin ventana
  • El texto permanece por encima de todas las demás ventanas
  • El fondo puede ser transparente

Qué no:

  • El texto no muestra las aplicaciones de pantalla completa anteriores
  • El texto bloquea los eventos de clic que ocurren sobre él
  • La transparencia de fondo no es alfa, por lo que hay bordes duros