Hi,
I’m new to the group and have a perplexing problem.
Platform: Windows 7 x64 running 32-bit Python 2.7 and wxPython 3.0.2.0
In a nutshell:
-
Display a wxFrame
-
Post a message to put the display to sleep
-
Wake up the display manually
-
When I display another wxFrame, it causes the display to go back to sleep
Details:
I am running wxApp in a separate thread using the advice on the Wiki regarding locks, etc.
The full application is a systray app, so there is NO MAIN WINDOW. I am using wxPython just to display dialog boxes and messages.
I am signalling into the thread using a Queue to both display the frame and put the display to sleep
The attached example is gutted. To keep it small, I am displaying a splash message that closes with a timer, but displaying other dialogs and frames cause the same behavior.
It prints to the console when the code that puts the display to sleep is executed to ensure that it is not the culprit in causing the second undesired sleep.
This ONLY happens when:
A frame is displayed before sleep and then on the first frame displayed after the sleep. Displaying another frame after the one that causes the ‘resleep’ does not cause it again.
If you run the example, it will display a message and then put the display to sleep.
Make sure that you move your mouse or touch the keyboard promptly when the display goes to sleep or lengthen the amount of sleep in the main loop.
Then it will display another message. If the problem is reproducible, your display will go back to sleep.
To keep the main from terminating, it goes into a perpetual loop at the end that you will need to manually break.
I’ve been able to reproduce on VM’s running Win7 32bit and Win8.1 32bit and another real Win7 64.
Any help or insight would be greatly appreciated.
Ken
import wx
import threading
import Queue
import win32api, win32con
class SplashMessage ( wx.Frame ):
def __init__( self, parent, msg, showtime):
wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = wx.EmptyString, pos = wx.DefaultPosition, size = wx.Size( 381,116 ), style = wx.STAY_ON_TOP|wx.DOUBLE_BORDER )
self.timer = wx.Timer(self)
self.Bind(wx.EVT_TIMER, self.close, self.timer)
self.SetSizeHintsSz( wx.DefaultSize, wx.DefaultSize )
bSizer1 = wx.BoxSizer( wx.VERTICAL )
bSizer1.SetMinSize( wx.Size( 1,3 ) )
self.m_staticText1 = wx.StaticText( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 )
self.m_staticText1.Wrap( -1 )
bSizer1.Add( self.m_staticText1, 0, wx.ALL|wx.EXPAND, 5 )
self.m_staticText4 = wx.StaticText( self, wx.ID_ANY, ' %s ' % msg, wx.DefaultPosition, wx.DefaultSize, wx.ALIGN_CENTRE )
self.m_staticText4.Wrap( -1 )
self.m_staticText4.SetFont( wx.Font( wx.NORMAL_FONT.GetPointSize(), 70, 90, 92, False, wx.EmptyString ) )
bSizer1.Add( self.m_staticText4, 0, wx.ALL|wx.EXPAND, 5 )
self.m_staticText3 = wx.StaticText( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 )
self.m_staticText3.Wrap( -1 )
bSizer1.Add( self.m_staticText3, 0, wx.ALL|wx.EXPAND, 5 )
self.SetSizer( bSizer1 )
bSizer1.Fit(bSizer1.GetContainingWindow())
self.Layout()
self.Centre( wx.BOTH )
self.showtime = showtime
self.timer.Start(showtime)
def close(self, event):
self.Close()
self.Destroy()
class wxAppThread(threading.Thread):
def __init__(self):
super(wxAppThread, self).__init__()
self.messageq = Queue.Queue()
self.resultq = Queue.Queue()
self.abortrequest = threading.Event()
self.app = None
self.lock = threading.Lock()
self.lock.acquire()
def run(self):
self.app = wx.App(0, useBestVisual=True)
self.lock.release()
while not self.abortrequest.is_set():
try:
message = self.messageq.get(True, 0.05)
if message[0] == 1:
pass
elif message[0] == 2:
self.lock.acquire()
splash = SplashMessage(None, message[1], message[2])
splash.Show()
self.lock.release()
self.app.MainLoop()
elif message[0] == 3:
pass
elif message[0] == 4:
self.lock.acquire()
print 'Sleeping Display'
x = win32api.PostMessage(win32con.HWND_BROADCAST, win32con.WM_SYSCOMMAND, win32con.SC_MONITORPOWER, 2)
self.lock.release()
except Queue.Empty:
continue
wx.App_CleanUp()
def abort(self):
self.abortrequest.set()
super(wxAppThread, self).join()
def showSplashMessage(self, msg, showtime=1000):
self.messageq.put([2, msg, showtime])
def sleepDisplay(self):
self.messageq.put([4,])
if __name__ == '__main__':
import time
app = wxAppThread()
app.start()
app.showSplashMessage('Test Starting')
time.sleep(2)
app.sleepDisplay()
time.sleep(10)
app.showSplashMessage('Testing Resleep', 1000)
while True:
time.sleep(.25)
app.abort()
pass
sleepproblemdemo.py (3.41 KB)