Actualizar la sugerencia de globo de Windows desde el hilo de Python
Estoy usando un módulo para notificaciones de punta de globo en la bandeja del sistema, cada vez que el usuario recibe un nuevo mensaje. (usando Python 3.3 y Kivy 1.8. Estoy implementando en Windows 7.)
Creo que el código original proviene deeste github.
Este es el módulo como lo he modificado ::
from win32api import *
from win32gui import *
import win32con
import sys, os
import struct
import threading
import time
print ("Importing pypops")
class WindowsBalloonTip:
def __init__(self, title, msg):
message_map = {
win32con.WM_DESTROY: self.OnDestroy,
# win32con.WM_CLOSE: self.onClose
}
# Register the Window class.
wc = WNDCLASS()
hinst = wc.hInstance = GetModuleHandle(None)
wc.lpszClassName = "PythonTaskbar"
wc.lpfnWndProc = message_map # could also specify a wndproc.
classAtom = RegisterClass(wc)
# Create the Window.
style = win32con.WS_OVERLAPPED | win32con.WS_SYSMENU
self.hwnd = CreateWindow( classAtom, "Taskbar", style, \
0, 0, win32con.CW_USEDEFAULT, win32con.CW_USEDEFAULT, \
0, 0, hinst, None)
UpdateWindow(self.hwnd)
iconPathName = os.path.abspath(os.path.join( sys.path[0], "balloontip.ico" ))
icon_flags = win32con.LR_LOADFROMFILE | win32con.LR_DEFAULTSIZE
try:
hicon = LoadImage(hinst, iconPathName, \
win32con.IMAGE_ICON, 0, 0, icon_flags)
except:
hicon = LoadIcon(0, win32con.IDI_APPLICATION)
flags = NIF_ICON | NIF_MESSAGE | NIF_TIP
nid = (self.hwnd, 0, flags, win32con.WM_USER+20, hicon, "tooltip")
#Notify
Shell_NotifyIcon(NIM_ADD, nid)
Shell_NotifyIcon(NIM_MODIFY, \
(self.hwnd, 0, NIF_INFO, win32con.WM_USER+20,\
hicon, "Balloon tooltip",msg,400,title))
### from original code
# time.sleep(10) #cannot use this. it kills the whole app
# DestroyWindow(self.hwnd)
# classAtom = UnregisterClass(classAtom, hinst)
def onClose(self, hwnd): #to be called from thread as a method of the class instance
DestroyWindow(hwnd)
classAtom = UnregisterClass(classAtom, hinst)
return True
def OnDestroy(self, hwnd, msg, wparam, lparam):
nid = (self.hwnd, 0)
Shell_NotifyIcon(NIM_DELETE, nid)
PostQuitMessage(0) # Terminate the app.
Estoy instanciando elWindowsBalloonTip
clase en un hilo, si y solo si llega un nuevo mensaje. Después de que se instancia la clase, a si un hilo posterior detecta otro mensaje nuevo, estaba tratando de llamaronClose
como método de la clase pypops, y obteniendo
pywintypes.error: (1400, 'DestroyWindow', 'Identificador de ventana inválido').
Sé por otras fuentes que esto se debe a que el hilo que crea la ventana debe usarse para destruirla. ¿Cuál es la forma de evitar esto?
lostime.sleep
La solución, comentada en mi código, no es factible al menos por estas razones:
time.sleep()
mata toda mi aplicación, evita la entrada del usuario, redibuja, etc.He investigado:Manejo de manejador de ventana inválido y muchos otros.
¿Cómo puedo destruir la ventana y cancelar el registro de la clase dinámicamente desde un hilo o actualizar la ventana?Text
?
Cuando trato deDestroyWindow
como secuencial--init--
paso, funciona bien. Inicio sesión'hwnd'
produce un entero. Sin embargo, cuando trato de llamaronClose
, Obtengo el error 1400, aunque inicie sesión'hwnd'
en este caso produce el mismo valor exacto que el otro'hwnd'
: en otras palabras, el parámetro que estoy pasando aDestroyWindow
es el mismo valor siDestroyWindow
sucede en el--init--
etapa, o como parte de un método que llamo más tarde. ¿Qué está indicando el error en este último caso?
Estoy muy familiarizado con Python y estoy mejorando con Kivy. Sin embargo, esta es mi primera incursión en cualquier intercompatibilidad gui / api de windows.
Gracias por cualquier respuesta, sugerencia, crítica,Guías!
"¿Leads? Leads, sí, claro. Yo uh, solo consultaré con los chicos en el Laboratorio del Crimen. Ellos uh, tienen uh, cuatro detectives más trabajando en el caso. Nos tienen trabajando por turnos".