Atualizar dica de balão do Windows do segmento Python
Estou usando um módulo para notificações de dicas de balão na bandeja do sistema sempre que o usuário recebe uma nova mensagem. (usando Python 3.3 e Kivy 1.8. Estou implantando no Windows 7.)
Eu acredito que o código original vemeste github.
Este é o módulo como eu o alterei:
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.
Estou instanciando oWindowsBalloonTip
classe em um encadeamento, se e somente se uma nova mensagem chegar. Depois que a classe for instanciada, a se um encadeamento subsequente detectar outra nova mensagem, eu estava tentando chamaronClose
como um método da classe pypops e obtendo
pywintypes.error: (1400, 'DestroyWindow', 'Identificador de janela inválido.').
Sei de outras fontes que isso ocorre porque o segmento que cria a janela deve ser usado para destruí-lo. Qual é o caminho para contornar isso?
otime.sleep
solução, comentada no meu código, é inviável por pelo menos estes motivos:
time.sleep()
mata todo o meu aplicativo, evita a entrada do usuário, redesenha, etc.Eu pesquisei:Manipulação de identificador de janela inválido e muitos outros.
Como posso destruir a janela e cancelar o registro da classe dinamicamente de um thread ou atualizar a janelaText
?
Quando tentoDestroyWindow
como um seqüencial--init--
passo, funciona bem. Exploração madeireira'hwnd'
produz um número inteiro. No entanto, quando tento ligaronClose
, Estou recebendo o erro 1400, apesar de registrar'hwnd'
nesse caso, gera o mesmo valor exato que o outro'hwnd'
: em outras palavras, o parâmetro para o qual estou passandoDestroyWindow
é o mesmo valor seDestroyWindow
acontece no--init--
estágio, ou como parte de um método que chamo mais tarde. O que está informando o erro neste último caso?
Estou muito familiarizado com o Python e melhorando com o Kivy. No entanto, esta é minha primeira incursão em qualquer intercompatibilidade do Windows GUI / API.
Obrigado por todas as respostas, sugestões, críticas,conduz!
"Leads? Leads, sim, com certeza. Eu vou apenas verificar com os garotos no Laboratório do Crime. Eles têm mais quatro detetives trabalhando no caso. Eles nos fazem trabalhar em turnos."