How to create a customized splash screen (Phoenix)
Keywords : Splashscreen, Mask, Timeout, Shaped frame, Bitmap, Timer, Gauge, Throbber, Animated gif, Fade in, CallLater, ScreenDC, Alpha.
Contents
Demonstrating :
Tested py3.x, wx4.x and Win10.
Are you ready to use some samples ?
Test, modify, correct, complete, improve and share your discoveries !
With gauge :
First example
1 # sample_one_a.py
2
3 import sys
4 import os
5 import wx
6 from wx.adv import SplashScreen as SplashScreen
7
8 # class MyFrame
9 # class MySplash
10 # class MyApp
11
12 #---------------------------------------------------------------------------
13
14 class MyFrame(wx.Frame):
15 """
16 ...
17 """
18 def __init__(self):
19 super(MyFrame, self).__init__(None,
20 -1,
21 title="")
22
23 #------------
24
25 # Return application name.
26 self.app_name = wx.GetApp().GetAppName()
27 # Return icons folder.
28 self.icons_dir = wx.GetApp().GetIconsDir()
29
30 #------------
31
32 # Simplified init method.
33 self.SetProperties()
34 self.CreateCtrls()
35 self.BindEvents()
36 self.DoLayout()
37
38 #------------
39
40 self.CenterOnScreen(wx.BOTH)
41
42 #------------
43
44 self.Show(True)
45
46 #-----------------------------------------------------------------------
47
48 def SetProperties(self):
49 """
50 ...
51 """
52
53 self.SetTitle(self.app_name)
54 self.SetSize((340, 250))
55
56 #------------
57
58 frameIcon = wx.Icon(os.path.join(self.icons_dir,
59 "icon_wxWidgets.ico"),
60 type=wx.BITMAP_TYPE_ICO)
61 self.SetIcon(frameIcon)
62
63
64 def CreateCtrls(self):
65 """
66 ...
67 """
68
69 # Create a panel.
70 self.panel = wx.Panel(self, -1)
71
72 #------------
73
74 # Add a button.
75 self.btnClose = wx.Button(self.panel,
76 -1,
77 "&Close")
78
79
80 def BindEvents(self):
81 """
82 Bind some events to an event handler.
83 """
84
85 # Bind events to an events handler.
86 self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
87 self.Bind(wx.EVT_BUTTON, self.OnCloseMe, self.btnClose)
88
89
90 def DoLayout(self):
91 """
92 ...
93 """
94
95 # MainSizer is the top-level one that manages everything.
96 mainSizer = wx.BoxSizer(wx.VERTICAL)
97
98 # wx.BoxSizer(window, proportion, flag, border).
99 # wx.BoxSizer(sizer, proportion, flag, border).
100 mainSizer.Add(self.btnClose, 1, wx.EXPAND | wx.ALL, 10)
101
102 # Finally, tell the panel to use the sizer for layout.
103 self.panel.SetAutoLayout(True)
104 self.panel.SetSizer(mainSizer)
105
106 mainSizer.Fit(self.panel)
107
108
109 def OnCloseMe(self, event):
110 """
111 ...
112 """
113
114 self.Close(True)
115
116
117 def OnCloseWindow(self, event):
118 """
119 ...
120 """
121
122 self.Destroy()
123
124 #---------------------------------------------------------------------------
125
126 class MySplash(SplashScreen):
127 """
128 ...
129 """
130 def __init__(self):
131
132 #--------------
133
134 screen = wx.ScreenDC()
135
136 # Screen size.
137 ws, hs = screen.GetSize()
138
139 #--------------
140
141 # Return bitmaps folder.
142 self.bitmaps_dir = wx.GetApp().GetBitmapsDir()
143
144 # Load a background bitmap.
145 bitmap = wx.Bitmap(os.path.join(self.bitmaps_dir,
146 "python.png"),
147 type=wx.BITMAP_TYPE_PNG)
148
149 # Determine size of bitmap.
150 wi, hi = bitmap.GetWidth(), bitmap.GetHeight()
151 print("\n... Bitmap size : %sx%s px" % (wi, hi))
152
153 x = int((ws-wi)/2)
154 y = int((hs-hi)/2)
155
156 #--------------
157
158 super(MySplash, self).__init__(bitmap=bitmap,
159 splashStyle=wx.adv.SPLASH_CENTRE_ON_SCREEN |
160 wx.adv.SPLASH_TIMEOUT,
161 milliseconds=8000,
162 parent=None,
163 id=-1,
164 pos=(x, y),
165 size=(wi, hi),
166 style=wx.STAY_ON_TOP |
167 wx.BORDER_NONE)
168
169 #------------
170
171 self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
172
173 self.count = 0
174
175 wx.Sleep(1)
176
177 #------------
178
179 # Simplified init method.
180 self.CreateCtrls()
181 self.BindEvents()
182
183 #------------
184
185 # Create a timer for my gauge.
186 self.timer = wx.Timer(self)
187
188 # Gauge speed. Simulate long startup time.
189 self.timer.Start(90)
190
191 self.Bind(wx.EVT_TIMER, self.TimerHandler, self.timer)
192
193 #------------
194
195 print("\n... Display the splashScreen")
196
197 #--------------
198
199 wx.BeginBusyCursor()
200
201 #-----------------------------------------------------------------------
202
203 def CreateCtrls(self):
204 """
205 Create some controls for my splash screen.
206 """
207
208 #------------
209
210 # Put text.
211 self.text = wx.StaticText(parent=self,
212 id=-1,
213 label="Loading...",
214 pos=(4, 231),
215 size=(252, 18),
216 style=wx.ALIGN_CENTRE_HORIZONTAL)
217 self.text.SetBackgroundColour(wx.WHITE)
218
219 #------------
220
221 # Put gauge.
222 self.gauge = wx.Gauge(self,
223 id=-1,
224 range=50,
225 size=(-1, 20))
226
227 #------------
228
229 # Cody Precord... thank you !
230 rect = self.GetClientRect()
231 new_size = (rect.width, 20)
232 self.gauge.SetSize(new_size)
233 self.SetSize((rect.width, rect.height+20))
234 self.gauge.SetPosition((0, rect.height))
235
236
237 def BindEvents(self):
238 """
239 Bind all the events related to my splash screen.
240 """
241
242 # Bind events to an events handler.
243 self.Bind(wx.EVT_CLOSE, self.OnClose)
244
245
246 def TimerHandler(self, event):
247 """
248 ...
249 """
250
251 self.count = self.count + 1
252
253 if self.count >= 90:
254 self.count = 0
255
256 self.gauge.SetValue(self.count)
257 # or
258 # self.gauge.Pulse()
259
260
261 def OnClose(self, event):
262 """
263 Close the splash screen.
264 This method will be called under 2 cases :
265 1. time-limit is up, called automatically,
266 2. you left-click on the splash-bitmap.
267 """
268
269 # Make sure the default handler runs
270 # too so this window gets destroyed.
271 # Tell the event system to continue
272 # looking for an event handler, so the
273 # default handler will get called.
274 event.Skip()
275 self.Hide()
276
277 #------------
278
279 if self.timer.IsRunning():
280 # Stop the gauge timer.
281 self.timer.Stop()
282 # del self.timer
283 self.ShowMainFrame()
284
285
286 def ShowMainFrame(self):
287 """
288 ...
289 """
290
291 print("\n... Close the splash screen")
292 print("\n... Create and display the main frame")
293
294 #------------
295
296 wx.CallAfter(wx.EndBusyCursor)
297
298 #------------
299
300 # Create an instance of the MyFrame class.
301 frame = MyFrame()
302
303 #---------------------------------------------------------------------------
304
305 class MyApp(wx.App):
306 """
307 ...
308 """
309 def OnInit(self):
310
311 #------------
312
313 self.locale = wx.Locale(wx.LANGUAGE_ENGLISH)
314
315 #------------
316
317 self.SetAppName("Main frame")
318
319 #------------
320
321 self.installDir = os.path.split(os.path.abspath(sys.argv[0]))[0]
322
323 #------------
324
325 splash = MySplash()
326 splash.Show(True)
327
328 return True
329
330 #-----------------------------------------------------------------------
331
332 def GetInstallDir(self):
333 """
334 Returns the installation directory for my application.
335 """
336
337 return self.installDir
338
339
340 def GetIconsDir(self):
341 """
342 Returns the icons directory for my application.
343 """
344
345 icons_dir = os.path.join(self.installDir, "icons")
346 return icons_dir
347
348
349 def GetBitmapsDir(self):
350 """
351 Returns the bitmaps directory for my application.
352 """
353
354 bitmaps_dir = os.path.join(self.installDir, "bitmaps")
355 return bitmaps_dir
356
357 #---------------------------------------------------------------------------
358
359 def main():
360 app = MyApp(False)
361 app.MainLoop()
362
363 #---------------------------------------------------------------------------
364
365 if __name__ == "__main__" :
366 main()
Second example
1 # sample_one_b.py
2
3 import os
4 import sys
5 import platform
6 import wx
7
8 # class MyFrame
9 # class MyCaptionBox
10 # class MyPanel
11 # class MySplash
12 # class MyApp
13
14 #---------------------------------------------------------------------------
15
16 class MyFrame(wx.Frame):
17 """
18 ...
19 """
20 def __init__(self):
21 super(MyFrame, self).__init__(None,
22 -1,
23 title="")
24
25 #------------
26
27 # Return application name.
28 self.app_name = wx.GetApp().GetAppName()
29 # Return icons folder.
30 self.icons_dir = wx.GetApp().GetIconsDir()
31
32 #------------
33
34 # Simplified init method.
35 self.SetProperties()
36 self.CreateCtrls()
37 self.BindEvents()
38 self.DoLayout()
39
40 #------------
41
42 self.CenterOnScreen(wx.BOTH)
43
44 #------------
45
46 self.Show(True)
47
48 #-----------------------------------------------------------------------
49
50 def SetProperties(self):
51 """
52 ...
53 """
54
55 self.SetTitle(self.app_name)
56 self.SetSize((340, 250))
57
58 #------------
59
60 frameIcon = wx.Icon(os.path.join(self.icons_dir,
61 "icon_wxWidgets.ico"),
62 type=wx.BITMAP_TYPE_ICO)
63 self.SetIcon(frameIcon)
64
65
66 def CreateCtrls(self):
67 """
68 ...
69 """
70
71 # Create a panel.
72 self.panel = wx.Panel(self, -1)
73
74 #------------
75
76 # Add a buttons.
77 self.btnClose = wx.Button(self.panel,
78 -1,
79 "&Close")
80
81
82 def BindEvents(self):
83 """
84 Bind some events to an events handler.
85 """
86
87 # Bind events to an events handler.
88 self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
89 self.Bind(wx.EVT_BUTTON, self.OnCloseMe, self.btnClose)
90
91
92 def DoLayout(self):
93 """
94 ...
95 """
96
97 # MainSizer is the top-level one that manages everything.
98 mainSizer = wx.BoxSizer(wx.VERTICAL)
99
100 # wx.BoxSizer(window, proportion, flag, border)
101 # wx.BoxSizer(sizer, proportion, flag, border)
102 mainSizer.Add(self.btnClose, 1, wx.EXPAND | wx.ALL, 10)
103
104 # Finally, tell the panel to use the sizer for layout.
105 self.panel.SetAutoLayout(True)
106 self.panel.SetSizer(mainSizer)
107
108 mainSizer.Fit(self.panel)
109
110
111 def OnCloseMe(self, event):
112 """
113 ...
114 """
115
116 self.Close(True)
117
118
119 def OnCloseWindow(self, event):
120 """
121 ...
122 """
123
124 self.Destroy()
125 wx.Exit()
126
127 #---------------------------------------------------------------------------
128
129 class MyCaptionBox(wx.Panel):
130 """
131 ...
132 """
133 def __init__(self, parent, caption):
134 super(MyCaptionBox, self).__init__(parent,
135 style=wx.NO_BORDER |
136 wx.TAB_TRAVERSAL)
137
138 #------------
139
140 self.SetBackgroundColour("#344050")
141
142 #------------
143
144 # Attributes.
145 self._caption = caption
146 self._csizer = wx.BoxSizer(wx.VERTICAL)
147
148 #------------
149
150 # Simplified init method.
151 self.BindEvents()
152 self.DoLayout()
153
154 #-----------------------------------------------------------------------
155
156 def BindEvents(self):
157 """
158 ...
159 """
160
161 # Bind events to an events handler.
162 self.Bind(wx.EVT_PAINT, self.OnPaint)
163
164
165 def DoLayout(self):
166 """
167 ...
168 """
169
170 msizer = wx.BoxSizer(wx.HORIZONTAL)
171 self._csizer.AddSpacer(15) # Extra space for caption.
172 msizer.Add(self._csizer, 0, wx.EXPAND|wx.ALL, 0)
173 self.SetSizer(msizer)
174
175
176 def DoGetBestSize(self):
177 """
178 ...
179 """
180
181 size = super(MyCaptionBox, self).DoGetBestSize()
182 # Compensate for wide caption labels.
183 tw = self.GetTextExtent(self._caption)[0]
184 size.SetWidth(max(size.width, tw))
185 return size
186
187
188 def AddItem(self, item):
189 """
190 Add a window or sizer item to the caption box.
191 """
192
193 self._csizer.Add(item, 0, wx.ALL, 5)
194
195
196 def OnPaint(self, event):
197 """
198 Draws the Caption and border around the controls.
199 """
200
201 dc = wx.BufferedPaintDC(self)
202 dc.SetBackground(wx.Brush(wx.BLACK))
203 dc.Clear()
204 gcdc = wx.GCDC(dc)
205
206 # Get the working rectangle we can draw in.
207 rect = self.GetClientRect()
208
209 # Get the sytem color to draw the caption.
210 ss = wx.SystemSettings
211 color = ss.GetColour(wx.SYS_COLOUR_3DDKSHADOW)
212 gcdc.SetTextForeground(wx.WHITE)
213
214 # Draw the border.
215 rect.Inflate(-0, -0)
216 gcdc.SetPen(wx.Pen(color))
217 gcdc.SetBrush(wx.Brush(wx.Colour(70, 70, 70, 255)))
218 gcdc.DrawRoundedRectangle(rect, 5)
219
220 # Font size and style.
221 font = self.GetFont().GetPointSize()
222 font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)
223 font.SetWeight(wx.BOLD)
224
225 # Add the Caption.
226 rect = wx.Rect(rect.x, rect.y, rect.width, 20)
227 rect.Inflate(-5, 0)
228 gcdc.SetFont(font)
229 gcdc.DrawLabel(self._caption, rect, wx.ALIGN_CENTER)
230
231 #---------------------------------------------------------------------------
232
233 class MyPanel(wx.Panel):
234 """
235 ...
236 """
237 def __init__(self, parent):
238 wx.Panel.__init__(self, parent)
239
240 #------------
241
242 self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
243
244 #------------
245
246 # Return bitmaps folder.
247 self.bitmaps_dir = wx.GetApp().GetBitmapsDir()
248
249 # Load a background bitmap.
250 self.bmp = wx.Bitmap(os.path.join(self.bitmaps_dir,
251 "rocket.png"),
252 type=wx.BITMAP_TYPE_PNG)
253
254 #------------
255
256 # Attributes.
257 self.box1 = MyCaptionBox(self, "Loading...")
258
259 #------------
260
261 # Put a gauge in the box.
262 self.count = 0
263
264 self.gauge = wx.Gauge(self.box1,
265 id=-1,
266 range=20,
267 size=(155, 15))
268 self.box1.AddItem(self.gauge)
269
270 #------------
271
272 # Create a timer for my gauge.
273 self.timer = wx.Timer(self)
274
275 # Gauge speed. Simulate long startup time.
276 self.timer.Start(90)
277
278 self.Bind(wx.EVT_TIMER, self.TimerHandler, self.timer)
279
280 #------------
281
282 # Simplified init method.
283 self.BindEvents()
284 self.DoLayout()
285
286 #------------
287
288 self.SetClientSize((514, 386))
289
290 #-----------------------------------------------------------------------
291
292 def BindEvents(self):
293 """
294 ...
295 """
296
297 # Bind event to an events handler.
298 self.Bind(wx.EVT_PAINT, self.OnPaint)
299 self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy)
300 self.box1.Bind(wx.EVT_MOUSE_EVENTS, self.OnMouseEvents)
301 self.gauge.Bind(wx.EVT_MOUSE_EVENTS, self.OnMouseEvents)
302
303
304 def DoLayout(self):
305 """
306 ...
307 """
308
309 hsizer = wx.BoxSizer(wx.HORIZONTAL)
310 vsizer = wx.BoxSizer(wx.VERTICAL)
311
312 #------------
313
314 # Add the box to the panel.
315 hsizer.AddStretchSpacer()
316 hsizer.Add(self.box1, 0, wx.EXPAND)
317 hsizer.AddSpacer(0)
318 vsizer.AddStretchSpacer()
319 vsizer.Add(hsizer, 0, wx.EXPAND|wx.ALL, 15)
320
321 self.SetSizer(vsizer)
322
323
324 def OnPaint(self, event):
325 """
326 ...
327 """
328
329 dc = wx.BufferedPaintDC(self)
330 dc.Clear()
331 gcdc = wx.GCDC(dc)
332 gcdc.Clear()
333
334 # Draw a bitmap with an alpha channel
335 # on top of the last group.
336 gcdc.DrawBitmap(self.bmp, 0, 0, False)
337
338
339 def TimerHandler(self, event):
340 """
341 ...
342 """
343
344 self.count = self.count + 1
345
346 if self.count >= 90:
347 self.count = 0
348
349 self.gauge.SetValue(self.count)
350 # or
351 # self.gauge.Pulse()
352
353
354 def OnMouseEvents(self, event):
355 """
356 Handles the wx.EVT_MOUSE_EVENTS for AdvancedSplash.
357 This reproduces the behavior of wx.SplashScreen.
358 """
359
360 if event.LeftDown() or event.RightDown():
361 splash = wx.GetApp().GetTopWindow()
362 splash.OnClose(event)
363
364 event.Skip()
365
366
367 def OnDestroy(self, event):
368 """
369 ...
370 """
371
372 event.Skip()
373
374 #---------------------------------------------------------------------------
375
376 class MySplash(wx.Frame):
377 """
378 ...
379 """
380 def __init__(self):
381
382 #--------------
383
384 screen = wx.ScreenDC()
385
386 # Screen size.
387 ws, hs = screen.GetSize()
388
389 #--------------
390
391 # Return bitmaps folder.
392 self.bitmaps_dir = wx.GetApp().GetBitmapsDir()
393
394 # Load a background bitmap.
395 self.bmp = wx.Bitmap(os.path.join(self.bitmaps_dir,
396 "rocket.png"),
397 type=wx.BITMAP_TYPE_PNG)
398
399 mask = wx.Mask(self.bmp, wx.RED)
400 self.bmp.SetMask(mask)
401
402 # Determine size of bitmap.
403 wi, hi = self.bmp.GetWidth(), self.bmp.GetHeight()
404 print("\n... Bitmap size : %sx%s px" % (wi, hi))
405
406 x = int((ws-wi)/2)
407 y = int((hs-hi)/2)
408
409 #--------------
410
411 super(MySplash, self).__init__(parent=None,
412 id=-1,
413 title="SplashScreen",
414 pos=(x, y),
415 size=(wi, hi),
416 style=wx.FRAME_SHAPED |
417 wx.BORDER_NONE |
418 wx.FRAME_NO_TASKBAR |
419 wx.STAY_ON_TOP)
420
421 #--------------
422
423 self.SetBackgroundColour("#344050")
424
425 #--------------
426
427 # Attributes.
428 self.SetTransparent(0)
429 self.opacity_in = 0
430 self.deltaN = -30
431 self.hasShape = False
432
433 #--------------
434
435 if wx.Platform != "__WXMAC__":
436 # wxMac clips the tooltip to the window shape, YUCK!!!
437 self.SetToolTip("Right-click to close the window\n"
438 "Double-click the image to set/unset the window shape")
439
440 if wx.Platform == "__WXGTK__":
441 # wxGTK requires that the window be created before you can
442 # set its shape, so delay the call to SetWindowShape until
443 # this event.
444 self.Bind(wx.EVT_WINDOW_CREATE, self.SetWindowShape)
445 else:
446 # On wxMSW and wxMac the window has already
447 # been created, so go for it.
448 self.SetWindowShape()
449
450 #--------------
451
452 # Starts the Timer. Once Expired, splash is Destroyed.
453 self.timer = wx.Timer(self)
454
455 # Simulate long startup time.
456 self.timer.Start(4000)
457
458 self.Bind(wx.EVT_TIMER, self.TimeOut, self.timer)
459
460 #--------------
461
462 # Show main frame after 3000 ms.
463 self.fc = wx.CallLater(3000, self.ShowMainFrame)
464
465 #--------------
466
467 self.CenterOnScreen(wx.BOTH)
468 self.Show(True)
469
470 #--------------
471
472 # Simplified init method.
473 self.OnTimerIn(self)
474 self.CreateCtrls()
475 self.DoLayout()
476
477 #--------------
478
479 print("\n... Display the splashScreen")
480
481 #--------------
482
483 self.SetClientSize((wi, hi))
484 wx.BeginBusyCursor()
485
486 #-----------------------------------------------------------------------
487
488 def OnTimerIn(self, evt):
489 """
490 Thanks to Pascal Faut.
491 """
492
493 self.timer1 = wx.Timer(self, -1)
494 self.timer1.Start(1)
495 self.Bind(wx.EVT_TIMER, self.AlphaCycle1, self.timer1)
496
497 print("Fade-in was launched.")
498
499
500 def AlphaCycle1(self, *args):
501 """
502 Thanks to Pascal Faut.
503 """
504
505 self.opacity_in += self.deltaN
506 if self.opacity_in <= 0:
507 self.deltaN = -self.deltaN
508 self.opacity_in = 0
509
510 if self.opacity_in >= 255:
511 self.deltaN = -self.deltaN
512 self.opacity_in = 255
513
514 self.timer1.Stop()
515
516 self.SetTransparent(self.opacity_in)
517
518 print("Fade in = {}/255".format(self.opacity_in))
519
520
521 def CreateCtrls(self):
522 """
523 ...
524 """
525
526 self.panel = MyPanel(self)
527
528
529 def BindEvents(self):
530 """
531 Bind all the events related to my app.
532 """
533
534 # Bind some events to an events handler.
535 self.Bind(wx.EVT_CHAR, self.OnCharEvents)
536 self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
537 self.panel.Bind(wx.EVT_LEFT_DOWN, self.OnClose)
538
539
540 def DoLayout(self):
541 """
542 ...
543 """
544
545 sizer = wx.BoxSizer(wx.VERTICAL)
546 sizer.Add(self.panel, 1, wx.EXPAND)
547 self.SetSizer(sizer)
548
549
550 def SetWindowShape(self, *evt):
551 """
552 ...
553 """
554
555 # Use the bitmap's mask to determine the region.
556 r = wx.Region(self.bmp)
557 self.hasShape = self.SetShape(r)
558
559
560 def OnCharEvents(self, event):
561 """
562 Handles the wx.EVT_CHAR for Splash.
563 This reproduces the behavior of wx.SplashScreen.
564 """
565
566 self.OnClose(event)
567
568
569 def TimeOut(self, event):
570 """
571 ...
572 """
573
574 self.Close(True)
575
576
577 def OnCloseWindow(self, event):
578 """
579 ...
580 """
581
582 print("\n... Close timer")
583
584 #--------------
585
586 if hasattr(self, "timer"):
587 self.Show(False)
588 self.timer.Stop()
589 del self.timer
590
591
592 def OnClose(self, event):
593 """
594 Handles the wx.EVT_CLOSE event for SplashScreen.
595 """
596
597 # Make sure the default handler runs
598 # too so this window gets destroyed.
599 # Tell the event system to continue
600 # looking for an event handler, so the
601 # default handler will get called.
602 event.Skip()
603 self.Hide()
604
605 #------------
606
607 # If the timer is still running then go
608 # ahead and show the main frame now.
609 if self.fc.IsRunning():
610 # Stop the wx.CallLater timer.
611 # Stop the splash screen timer
612 # and close it.
613 self.fc.Stop()
614 self.ShowMainFrame()
615
616
617 def ShowMainFrame(self):
618 """
619 ...
620 """
621
622 print("\n... Close the splash screen")
623 print("\n... Create and display the main frame")
624
625 #------------
626
627 wx.CallAfter(wx.EndBusyCursor)
628
629 #------------
630
631 if self.fc.IsRunning():
632 # Stop the splash screen
633 # timer and close it.
634 self.Raise()
635
636 #------------
637
638 # Create an instance of the MyFrame class.
639 frame = MyFrame()
640
641 #---------------------------------------------------------------------------
642
643 class MyApp(wx.App):
644 """
645 ...
646 """
647 def OnInit(self):
648
649 #------------
650
651 self.locale = wx.Locale(wx.LANGUAGE_ENGLISH)
652
653 #------------
654
655 self.SetAppName("Main frame")
656
657 #------------
658
659 self.installDir = os.path.split(os.path.abspath(sys.argv[0]))[0]
660
661 #------------
662
663 splash = MySplash()
664 splash.BindEvents()
665 splash.CenterOnScreen(wx.BOTH)
666
667 return True
668
669 #-----------------------------------------------------------------------
670
671 def GetInstallDir(self):
672 """
673 Returns the installation directory for my application.
674 """
675
676 return self.installDir
677
678
679 def GetIconsDir(self):
680 """
681 Returns the icons directory for my application.
682 """
683
684 icons_dir = os.path.join(self.installDir, "icons")
685 return icons_dir
686
687
688 def GetBitmapsDir(self):
689 """
690 Returns the bitmaps directory for my application.
691 """
692
693 bitmaps_dir = os.path.join(self.installDir, "bitmaps")
694 return bitmaps_dir
695
696 #---------------------------------------------------------------------------
697
698 def main():
699 app = MyApp(False)
700 app.MainLoop()
701
702 #---------------------------------------------------------------------------
703
704 if __name__ == "__main__" :
705 main()
With shadow
1 # sample_two.py
2
3 import sys
4 import os
5 import wx
6 from wx.adv import SplashScreen as SplashScreen
7
8 # class MyFrame
9 # class MySplash
10 # class MyApp
11
12 #---------------------------------------------------------------------------
13
14 class MyFrame(wx.Frame):
15 """
16 ...
17 """
18 def __init__(self):
19 super(MyFrame, self).__init__(None,
20 -1,
21 title="")
22
23 #------------
24
25 # Return application name.
26 self.app_name = wx.GetApp().GetAppName()
27 # Return icons folder.
28 self.icons_dir = wx.GetApp().GetIconsDir()
29
30 #------------
31
32 # Simplified init method.
33 self.SetProperties()
34 self.CreateCtrls()
35 self.BindEvents()
36 self.DoLayout()
37
38 #------------
39
40 self.CenterOnScreen(wx.BOTH)
41
42 #------------
43
44 self.Show(True)
45
46 #-----------------------------------------------------------------------
47
48 def SetProperties(self):
49 """
50 ...
51 """
52
53 self.SetTitle(self.app_name)
54 self.SetSize((340, 250))
55
56 #------------
57
58 frameIcon = wx.Icon(os.path.join(self.icons_dir,
59 "icon_wxWidgets.ico"),
60 type=wx.BITMAP_TYPE_ICO)
61 self.SetIcon(frameIcon)
62
63
64 def CreateCtrls(self):
65 """
66 ...
67 """
68
69 # Create a panel.
70 self.panel = wx.Panel(self, -1)
71
72 #------------
73
74 # Add a button.
75 self.btnClose = wx.Button(self.panel,
76 -1,
77 "&Close")
78
79
80 def BindEvents(self):
81 """
82 Bind some events to an events handler.
83 """
84
85 # Bind events to an events handler.
86 self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
87 self.Bind(wx.EVT_BUTTON, self.OnCloseMe, self.btnClose)
88
89
90 def DoLayout(self):
91 """
92 ...
93 """
94
95 # MainSizer is the top-level one that manages everything.
96 mainSizer = wx.BoxSizer(wx.VERTICAL)
97
98 # wx.BoxSizer(window, proportion, flag, border)
99 # wx.BoxSizer(sizer, proportion, flag, border)
100 mainSizer.Add(self.btnClose, 1, wx.EXPAND | wx.ALL, 10)
101
102 # Finally, tell the panel to use the sizer for layout.
103 self.panel.SetAutoLayout(True)
104 self.panel.SetSizer(mainSizer)
105
106 mainSizer.Fit(self.panel)
107
108
109 def OnCloseMe(self, event):
110 """
111 ...
112 """
113
114 self.Close(True)
115
116
117 def OnCloseWindow(self, event):
118 """
119 ...
120 """
121
122 self.Destroy()
123
124 #---------------------------------------------------------------------------
125
126 class MySplash(SplashScreen):
127 """
128 ...
129 """
130 def __init__(self):
131
132 self.SaveScreen()
133
134 #------------
135
136 # Return bitmaps folder.
137 self.bitmaps_dir = wx.GetApp().GetBitmapsDir()
138
139 #------------
140
141 # Load a background bitmap.
142 bmp = wx.Bitmap(os.path.join(self.bitmaps_dir,
143 "splashscreen.bmp"),
144 type=wx.BITMAP_TYPE_BMP)
145
146 # Determine size of bitmap.
147 imgSize = (bmp.GetWidth(), bmp.GetHeight())
148 print("\n... Bitmap size : %sx%s px" % (imgSize))
149
150 #------------
151
152 super(MySplash, self).__init__(bitmap=bmp,
153 splashStyle=wx.adv.SPLASH_TIMEOUT,
154 milliseconds=4000,
155 parent=None,
156 id=-1,
157 pos=wx.DefaultPosition,
158 size=imgSize,
159 style=wx.STAY_ON_TOP |
160 wx.BORDER_NONE)
161
162 #------------
163
164 # Simplified init method.
165 self.BindEvents()
166
167 #------------
168
169 print("\n... Display the splashScreen")
170
171 #--------------
172
173 wx.BeginBusyCursor()
174
175 #-----------------------------------------------------------------------
176
177 def BindEvents(self):
178 """
179 ...
180 """
181
182 # Bind events to an events handler.
183 self.Bind(wx.EVT_CLOSE, self.OnClose)
184
185
186 def SaveScreen(self):
187 """
188 ...
189 """
190
191 # Return bitmaps folder.
192 self.bitmaps_dir = wx.GetApp().GetBitmapsDir()
193
194 # Load a bitmap.
195 bmp2 = wx.Bitmap(os.path.join(self.bitmaps_dir,
196 "shadow.png"),
197 type=wx.BITMAP_TYPE_PNG)
198
199 # Bitmap size.
200 w2, h2 = bmp2.GetSize()
201
202 #------------
203
204 # Create a screenshot.
205 screen = wx.ScreenDC()
206
207 # Screen size.
208 w, h = screen.GetSize()
209 print("\n... Screen size : %sx%s px" % (w, h))
210
211 bmp = wx.Bitmap(w, h)
212
213 mem = wx.MemoryDC(screen)
214 mem.SelectObject(bmp)
215 mem.Blit(0, 0, w, h, screen, 0, 0)
216 # Draw a bitmap with an alpha
217 # channel on the screenshot.
218 # image, x, y, transparency.
219 mem.DrawBitmap(bmp2, int((w-w2)/2), int((h-h2)/2), False)
220 mem.SelectObject(wx.NullBitmap)
221
222 #------------
223
224 # Save a background bitmap for splashscreen.
225 bmp.SaveFile(os.path.join(self.bitmaps_dir,
226 "splashscreen.bmp"),
227 type=wx.BITMAP_TYPE_BMP)
228
229
230 def OnClose(self, event):
231 """
232 Close the splash screen.
233 This method will be called under 2 cases :
234 1. time-limit is up, called automatically,
235 2. you left-click on the splash-bitmap.
236 """
237
238 # Make sure the default handler runs
239 # too so this window gets destroyed.
240 # Tell the event system to continue
241 # looking for an event handler, so the
242 # default handler will get called.
243 event.Skip()
244 self.Hide()
245
246 #------------
247
248 self.ShowMainFrame()
249
250
251 def ShowMainFrame(self):
252 """
253 ...
254 """
255
256 print("\n... Close the splash screen")
257 print("\n... Create and display the main frame")
258
259 #------------
260
261 wx.CallAfter(wx.EndBusyCursor)
262
263 #------------
264
265 # Create an instance of the MyFrame class.
266 frame = MyFrame()
267
268 #---------------------------------------------------------------------------
269
270 class MyApp(wx.App):
271 """
272 ...
273 """
274 def OnInit(self):
275
276 #------------
277
278 self.locale = wx.Locale(wx.LANGUAGE_ENGLISH)
279
280 #------------
281
282 self.SetAppName("Main frame")
283
284 #------------
285
286 self.installDir = os.path.split(os.path.abspath(sys.argv[0]))[0]
287
288 #------------
289
290 splash = MySplash()
291 splash.Show(True)
292
293 return True
294
295 #-----------------------------------------------------------------------
296
297 def GetInstallDir(self):
298 """
299 Returns the installation directory for my application.
300 """
301
302 return self.installDir
303
304
305 def GetIconsDir(self):
306 """
307 Returns the icons directory for my application.
308 """
309
310 icons_dir = os.path.join(self.installDir, "icons")
311 return icons_dir
312
313
314 def GetBitmapsDir(self):
315 """
316 Returns the bitmaps directory for my application.
317 """
318
319 bitmaps_dir = os.path.join(self.installDir, "bitmaps")
320 return bitmaps_dir
321
322 #---------------------------------------------------------------------------
323
324 def main():
325 app = MyApp(False)
326 app.MainLoop()
327
328 #---------------------------------------------------------------------------
329
330 if __name__ == "__main__" :
331 main()
With throbber
THROBBER file : throb_images.py
1 # sample_three.py
2
3 import os
4 import sys
5 import wx
6 import wx.lib.throbber as throb
7 import throb_images
8
9 # class MyFrame
10 # class MyCaptionBox
11 # class MyPanel
12 # class MySplash
13 # class MyApp
14
15 #---------------------------------------------------------------------------
16
17 class MyFrame(wx.Frame):
18 """
19 ...
20 """
21 def __init__(self):
22 super(MyFrame, self).__init__(None,
23 -1,
24 title="")
25
26 #------------
27
28 # Return application name.
29 self.app_name = wx.GetApp().GetAppName()
30 # Return icons folder.
31 self.icons_dir = wx.GetApp().GetIconsDir()
32
33 #------------
34
35 # Simplified init method.
36 self.SetProperties()
37 self.CreateCtrls()
38 self.BindEvents()
39 self.DoLayout()
40
41 #------------
42
43 self.CenterOnScreen(wx.BOTH)
44
45 #------------
46
47 self.Show(True)
48
49 #-----------------------------------------------------------------------
50
51 def SetProperties(self):
52 """
53 ...
54 """
55
56 self.SetTitle(self.app_name)
57 self.SetSize((340, 250))
58
59 #------------
60
61 frameIcon = wx.Icon(os.path.join(self.icons_dir,
62 "icon_wxWidgets.ico"),
63 type=wx.BITMAP_TYPE_ICO)
64 self.SetIcon(frameIcon)
65
66
67 def CreateCtrls(self):
68 """
69 ...
70 """
71
72 # Create a panel.
73 self.panel = wx.Panel(self, -1)
74
75 #------------
76
77 # Add a buttons.
78 self.btnClose = wx.Button(self.panel,
79 -1,
80 "&Close")
81
82
83 def BindEvents(self):
84 """
85 Bind some events to an events handler.
86 """
87
88 # Bind events to an events handler.
89 self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
90 self.Bind(wx.EVT_BUTTON, self.OnCloseMe, self.btnClose)
91
92
93 def DoLayout(self):
94 """
95 ...
96 """
97
98 # MainSizer is the top-level one that manages everything.
99 mainSizer = wx.BoxSizer(wx.VERTICAL)
100
101 # wx.BoxSizer(window, proportion, flag, border)
102 # wx.BoxSizer(sizer, proportion, flag, border)
103 mainSizer.Add(self.btnClose, 1, wx.EXPAND | wx.ALL, 10)
104
105 # Finally, tell the panel to use the sizer for layout.
106 self.panel.SetAutoLayout(True)
107 self.panel.SetSizer(mainSizer)
108
109 mainSizer.Fit(self.panel)
110
111
112 def OnCloseMe(self, event):
113 """
114 ...
115 """
116
117 self.Close(True)
118
119
120 def OnCloseWindow(self, event):
121 """
122 ...
123 """
124
125 self.Destroy()
126
127 #---------------------------------------------------------------------------
128
129 class MyCaptionBox(wx.Panel):
130 """
131 ...
132 """
133 def __init__(self, parent, caption):
134 super(MyCaptionBox, self).__init__(parent,
135 style=wx.NO_BORDER |
136 wx.TAB_TRAVERSAL)
137
138 #------------
139
140 self.SetBackgroundColour("#344050")
141
142 #------------
143
144 # Attributes.
145 self._caption = caption
146 self._csizer = wx.BoxSizer(wx.VERTICAL)
147
148 #------------
149
150 # Simplified init method.
151 self.BindEvents()
152 self.DoLayout()
153
154 #-----------------------------------------------------------------------
155
156 def BindEvents(self):
157 """
158 ...
159 """
160
161 # Bind events to an events handler.
162 self.Bind(wx.EVT_PAINT, self.OnPaint)
163
164
165 def DoLayout(self):
166 """
167 ...
168 """
169
170 msizer = wx.BoxSizer(wx.HORIZONTAL)
171 self._csizer.AddSpacer(15) # Extra space for caption.
172 msizer.Add(self._csizer, 0, wx.EXPAND)
173 self.SetSizer(msizer)
174
175
176 def DoGetBestSize(self):
177 """
178 ...
179 """
180
181 size = super(MyCaptionBox, self).DoGetBestSize()
182 # Compensate for wide caption labels.
183 tw = self.GetTextExtent(self._caption)[0]
184 size.SetWidth(max(size.width, tw))
185 return size
186
187
188 def AddItem(self, item):
189 """
190 Add a window or sizer item to the caption box.
191 """
192
193 self._csizer.Add(item, 0, wx.ALL, 10)
194
195
196 def OnPaint(self, event):
197 """
198 Draws the Caption and border around the controls.
199 """
200
201 dc = wx.BufferedPaintDC(self)
202 dc.SetBackground(wx.Brush(wx.Colour(52, 64, 80, 255)))
203 dc.Clear()
204 gcdc = wx.GCDC(dc)
205
206 # Get the working rectangle we can draw in.
207 rect = self.GetClientRect()
208
209 # Get the system color to draw the caption.
210 ss = wx.SystemSettings
211 color = ss.GetColour(wx.SYS_COLOUR_3DDKSHADOW)
212 gcdc.SetTextForeground(color)
213
214 # Draw the border.
215 rect.Inflate(-0, -0)
216 gcdc.SetPen(wx.Pen(color))
217 gcdc.SetBrush(wx.Brush(wx.Colour(52, 64, 80, 255)))
218
219 # Font size and style.
220 font = self.GetFont().GetPointSize()
221 font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)
222 font.SetWeight(wx.BOLD)
223
224 # Add the Caption.
225 rect = wx.Rect(rect.x, rect.y, rect.width, rect.height-34)
226 rect.Inflate(-5, 0)
227 gcdc.SetFont(font)
228 gcdc.DrawLabel(self._caption, rect, wx.ALIGN_CENTER)
229
230 #---------------------------------------------------------------------------
231
232 class MyPanel(wx.Panel):
233 """
234 ...
235 """
236 def __init__(self, parent):
237 wx.Panel.__init__(self, parent)
238
239 #------------
240
241 self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
242
243 #------------
244
245 # Return bitmaps folder.
246 self.bitmaps_dir = wx.GetApp().GetBitmapsDir()
247
248 # Load a background bitmap.
249 self.bmp = wx.Bitmap(os.path.join(self.bitmaps_dir,
250 "throbber.png"),
251 type=wx.BITMAP_TYPE_PNG)
252
253 #------------
254
255 # Attributes.
256 self.box1 = MyCaptionBox(self, "Loading...")
257
258 #------------
259
260 # Throbber image list.
261 self.images = [throb_images.catalog[img].GetBitmap()
262 for img in throb_images.index
263 if img not in ["eclouds", "logo"]]
264
265
266 # Put a throbber in the box.
267 self.throb = throb.Throbber(self.box1,
268 -1,
269 self.images,
270 frameDelay=0.1,
271 rest=4)
272 self.box1.AddItem(self.throb)
273
274 self.throb.Start()
275
276 #------------
277
278 # Simplified init method.
279 self.BindEvents()
280 self.DoLayout()
281
282 #------------
283
284 self.SetClientSize((262, 262))
285
286 #-----------------------------------------------------------------------
287
288 def BindEvents(self):
289 """
290 ...
291 """
292
293 # Bind some events to an events handler.
294 self.Bind(wx.EVT_PAINT, self.OnPaint)
295 self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy)
296 self.box1.Bind(wx.EVT_MOUSE_EVENTS, self.OnMouseEvents)
297 self.throb.Bind(wx.EVT_MOUSE_EVENTS, self.OnMouseEvents)
298
299
300 def DoLayout(self):
301 """
302 ...
303 """
304
305 hsizer = wx.BoxSizer(wx.HORIZONTAL)
306 vsizer = wx.BoxSizer(wx.VERTICAL)
307
308 #------------
309
310 # Add the box to the panel.
311 hsizer.AddStretchSpacer()
312 hsizer.Add(self.box1, 0, wx.ALIGN_CENTER)
313 vsizer.AddStretchSpacer(40)
314 vsizer.Add(hsizer, 0, wx.ALIGN_CENTER)
315 vsizer.AddStretchSpacer()
316
317 self.SetSizer(vsizer)
318
319
320 def OnPaint(self, event):
321 """
322 ...
323 """
324
325 dc = wx.BufferedPaintDC(self)
326 dc.Clear()
327 gcdc = wx.GCDC(dc)
328 gcdc.Clear()
329
330 # Draw a bitmap with an alpha channel
331 # on top of the last group.
332 gcdc.DrawBitmap(self.bmp, 0, 0, False)
333
334
335 def OnMouseEvents(self, event):
336 """
337 Handles the wx.EVT_MOUSE_EVENTS for AdvancedSplash.
338 This reproduces the behavior of wx.SplashScreen.
339 """
340
341 if event.LeftDown() or event.RightDown():
342 splash = wx.GetApp().GetTopWindow()
343 splash.OnClose(event)
344
345 event.Skip()
346
347
348 def OnDestroy(self, event):
349 """
350 ...
351 """
352
353 self.throb.Stop()
354 event.Skip()
355
356 #---------------------------------------------------------------------------
357
358 class MySplash(wx.Frame):
359 """
360 ...
361 """
362 def __init__(self):
363
364 #--------------
365
366 screen = wx.ScreenDC()
367
368 # Screen size.
369 ws, hs = screen.GetSize()
370
371 #--------------
372
373 # Return bitmaps folder.
374 self.bitmaps_dir = wx.GetApp().GetBitmapsDir()
375
376 # Load a background bitmap.
377 self.bmp = wx.Bitmap(os.path.join(self.bitmaps_dir,
378 "throbber.png"),
379 type=wx.BITMAP_TYPE_PNG)
380
381 mask = wx.Mask(self.bmp, wx.RED)
382 self.bmp.SetMask(mask)
383
384 # Determine size of bitmap.
385 wi, hi = self.bmp.GetWidth(), self.bmp.GetHeight()
386 print("\n... Bitmap size : %sx%s px" % (wi, hi))
387
388 x = int((ws-wi)/2)
389 y = int((hs-hi)/2)
390
391 #--------------
392
393 super(MySplash, self).__init__(parent=None,
394 id=-1,
395 title="SplashScreen",
396 pos=(x, y),
397 size=(wi, hi),
398 style=wx.FRAME_SHAPED |
399 wx.BORDER_NONE |
400 wx.FRAME_NO_TASKBAR |
401 wx.STAY_ON_TOP)
402
403 #--------------
404
405 self.SetBackgroundColour("#4a6991")
406
407 #--------------
408
409 # Attributes.
410 self.SetTransparent(0)
411 self.opacity_in = 0
412 self.deltaN = -30
413 self.hasShape = False
414
415 #--------------
416
417 if wx.Platform != "__WXMAC__":
418 # wxMac clips the tooltip to the window shape, YUCK!!!
419 self.SetToolTip("Right-click to close the window\n"
420 "Double-click the image to set/unset the window shape")
421
422 if wx.Platform == "__WXGTK__":
423 # wxGTK requires that the window be created before you can
424 # set its shape, so delay the call to SetWindowShape until
425 # this event.
426 self.Bind(wx.EVT_WINDOW_CREATE, self.SetWindowShape)
427 else:
428 # On wxMSW and wxMac the window has already
429 # been created, so go for it.
430 self.SetWindowShape()
431
432 #--------------
433
434 # Starts the Timer. Once Expired, splash is Destroyed.
435 self.timer = wx.Timer(self)
436
437 # Simulate long startup time.
438 self.timer.Start(4000)
439
440 self.Bind(wx.EVT_TIMER, self.TimeOut, self.timer)
441
442 #--------------
443
444 # Show main frame after 3000 ms.
445 self.fc = wx.CallLater(3000, self.ShowMainFrame)
446
447 #--------------
448
449 self.CenterOnScreen(wx.BOTH)
450 self.Show(True)
451
452 #--------------
453
454 # Simplified init method.
455 self.OnTimerIn(self)
456 self.CreateCtrls()
457 self.DoLayout()
458
459 #--------------
460
461 print("\n... Display the splashScreen")
462
463 #--------------
464
465 self.SetClientSize((wi, hi))
466 wx.BeginBusyCursor()
467
468 #-----------------------------------------------------------------------
469
470 def OnTimerIn(self, evt):
471 """
472 Thanks to Pascal Faut.
473 """
474
475 self.timer1 = wx.Timer(self, -1)
476 self.timer1.Start(1)
477 self.Bind(wx.EVT_TIMER, self.AlphaCycle1, self.timer1)
478
479 print("Fade-in was launched.")
480
481
482 def AlphaCycle1(self, *args):
483 """
484 Thanks to Pascal Faut.
485 """
486
487 self.opacity_in += self.deltaN
488 if self.opacity_in <= 0:
489 self.deltaN = -self.deltaN
490 self.opacity_in = 0
491
492 if self.opacity_in >= 255:
493 self.deltaN = -self.deltaN
494 self.opacity_in = 255
495
496 self.timer1.Stop()
497
498 self.SetTransparent(self.opacity_in)
499
500 print("Fade in = {}/255".format(self.opacity_in))
501
502
503 def CreateCtrls(self):
504 """
505 ...
506 """
507
508 self.panel = MyPanel(self)
509
510
511 def BindEvents(self):
512 """
513 Bind all the events related to my app.
514 """
515
516 # Bind some events to an events handler.
517 self.Bind(wx.EVT_CHAR, self.OnCharEvents)
518 self.Bind(wx.EVT_CLOSE, self.OnClose)
519 self.panel.Bind(wx.EVT_LEFT_DOWN, self.OnClose)
520 self.Bind(wx.EVT_CLOSE, self.CloseWindow)
521
522
523 def DoLayout(self):
524 """
525 ...
526 """
527
528 sizer = wx.BoxSizer(wx.VERTICAL)
529 sizer.Add(self.panel, 1, wx.EXPAND, 20)
530 self.SetSizer(sizer)
531
532
533 def SetWindowShape(self, *evt):
534 """
535 ...
536 """
537
538 # Use the bitmap's mask to determine the region.
539 r = wx.Region(self.bmp)
540 self.hasShape = self.SetShape(r)
541
542
543 def OnCharEvents(self, event):
544 """
545 Handles the wx.EVT_CHAR for Splash.
546 This reproduces the behavior of wx.SplashScreen.
547 """
548
549 self.OnClose(event)
550
551
552 def TimeOut(self, event):
553 """
554 ...
555 """
556
557 self.Close(True)
558
559
560 def OnClose(self, event):
561 """
562 Handles the wx.EVT_CLOSE event for SplashScreen.
563 """
564
565 # Make sure the default handler runs
566 # too so this window gets destroyed.
567 # Tell the event system to continue
568 # looking for an event handler, so the
569 # default handler will get called.
570 # event.Skip() # ?????
571 self.Hide()
572
573 #------------
574
575 # If the timer is still running then go
576 # ahead and show the main frame now.
577 if self.fc.IsRunning():
578 # Stop the wx.CallLater timer.
579 # Stop the splash screen timer
580 # and close it.
581 self.fc.Stop()
582 self.ShowMainFrame()
583
584
585 def ShowMainFrame(self):
586 """
587 ...
588 """
589
590 print("\n... Close the splash screen")
591 print("\n... Create and display the main frame")
592
593 #------------
594
595 wx.CallAfter(wx.EndBusyCursor)
596
597 #------------
598
599 if self.fc.IsRunning():
600 # Stop the splash screen
601 # timer and close it.
602 self.Raise()
603
604 #------------
605
606 # Create an instance of the MyFrame class.
607 frame = MyFrame()
608
609
610 def CloseWindow(self, event):
611 """
612 ...
613 """
614
615 self.timer.Stop()
616 self.Destroy()
617
618 #---------------------------------------------------------------------------
619
620 class MyApp(wx.App):
621 """
622 ...
623 """
624 def OnInit(self):
625
626 #------------
627
628 self.locale = wx.Locale(wx.LANGUAGE_ENGLISH)
629
630 #------------
631
632 self.SetAppName("Main frame")
633
634 #------------
635
636 self.installDir = os.path.split(os.path.abspath(sys.argv[0]))[0]
637
638 #------------
639
640 splash = MySplash()
641 splash.BindEvents()
642 splash.CenterOnScreen(wx.BOTH)
643
644 return True
645
646 #-----------------------------------------------------------------------
647
648 def GetInstallDir(self):
649 """
650 Returns the installation directory for my application.
651 """
652
653 return self.installDir
654
655
656 def GetIconsDir(self):
657 """
658 Returns the icons directory for my application.
659 """
660
661 icons_dir = os.path.join(self.installDir, "icons")
662 return icons_dir
663
664
665 def GetBitmapsDir(self):
666 """
667 Returns the bitmaps directory for my application.
668 """
669
670 bitmaps_dir = os.path.join(self.installDir, "bitmaps")
671 return bitmaps_dir
672
673 #---------------------------------------------------------------------------
674
675 def main():
676 app = MyApp(False)
677 app.MainLoop()
678
679 #---------------------------------------------------------------------------
680
681 if __name__ == "__main__" :
682 main()
With animated gif
1 # sample_four.py
2
3 import os
4 import sys
5 import wx
6 from wx.adv import Animation, AnimationCtrl
7
8 # class MyFrame
9 # class MyCaptionBox
10 # class MyPanel
11 # class MySplash
12 # class MyApp
13
14 #---------------------------------------------------------------------------
15
16 class MyFrame(wx.Frame):
17 """
18 ...
19 """
20 def __init__(self):
21 super(MyFrame, self).__init__(None,
22 -1,
23 title="")
24
25 #------------
26
27 # Return application name.
28 self.app_name = wx.GetApp().GetAppName()
29 # Return icons folder.
30 self.icons_dir = wx.GetApp().GetIconsDir()
31
32 #------------
33
34 # Simplified init method.
35 self.SetProperties()
36 self.CreateCtrls()
37 self.BindEvents()
38 self.DoLayout()
39
40 #------------
41
42 self.CenterOnScreen(wx.BOTH)
43
44 #------------
45
46 self.Show(True)
47
48 #-----------------------------------------------------------------------
49
50 def SetProperties(self):
51 """
52 ...
53 """
54
55 self.SetTitle(self.app_name)
56 self.SetSize((340, 250))
57
58 #------------
59
60 frameIcon = wx.Icon(os.path.join(self.icons_dir,
61 "icon_wxWidgets.ico"),
62 type=wx.BITMAP_TYPE_ICO)
63 self.SetIcon(frameIcon)
64
65
66 def CreateCtrls(self):
67 """
68 ...
69 """
70
71 # Create a panel.
72 self.panel = wx.Panel(self, -1)
73
74 #------------
75
76 # Add a buttons.
77 self.btnClose = wx.Button(self.panel,
78 -1,
79 "&Close")
80
81
82 def BindEvents(self):
83 """
84 Bind some events to an events handler.
85 """
86
87 # Bind events to an events handler.
88 self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
89 self.Bind(wx.EVT_BUTTON, self.OnCloseMe, self.btnClose)
90
91
92 def DoLayout(self):
93 """
94 ...
95 """
96
97 # MainSizer is the top-level one that manages everything.
98 mainSizer = wx.BoxSizer(wx.VERTICAL)
99
100 # wx.BoxSizer(window, proportion, flag, border)
101 # wx.BoxSizer(sizer, proportion, flag, border)
102 mainSizer.Add(self.btnClose, 1, wx.EXPAND | wx.ALL, 10)
103
104 # Finally, tell the panel to use the sizer for layout.
105 self.panel.SetAutoLayout(True)
106 self.panel.SetSizer(mainSizer)
107
108 mainSizer.Fit(self.panel)
109
110
111 def OnCloseMe(self, event):
112 """
113 ...
114 """
115
116 self.Close(True)
117
118
119 def OnCloseWindow(self, event):
120 """
121 ...
122 """
123
124 self.Destroy()
125
126 #---------------------------------------------------------------------------
127
128 class MyCaptionBox(wx.Panel):
129 """
130 ...
131 """
132 def __init__(self, parent, caption):
133 super(MyCaptionBox, self).__init__(parent,
134 style=wx.NO_BORDER |
135 wx.TAB_TRAVERSAL)
136
137 #------------
138
139 self.SetBackgroundColour("white")
140
141 #------------
142
143 # Attributes.
144 self._caption = caption
145 self._csizer = wx.BoxSizer(wx.VERTICAL)
146
147 #------------
148
149 # Simplified init method.
150 self.BindEvents()
151 self.DoLayout()
152
153 #-----------------------------------------------------------------------
154
155 def BindEvents(self):
156 """
157 ...
158 """
159
160 # Bind events to an events handler.
161 self.Bind(wx.EVT_PAINT, self.OnPaint)
162
163
164 def DoLayout(self):
165 """
166 ...
167 """
168
169 msizer = wx.BoxSizer(wx.HORIZONTAL)
170 self._csizer.AddSpacer(15) # Extra space for caption.
171 msizer.Add(self._csizer, 0, wx.EXPAND)
172 self.SetSizer(msizer)
173
174
175 def DoGetBestSize(self):
176 """
177 ...
178 """
179
180 size = super(MyCaptionBox, self).DoGetBestSize()
181 # Compensate for wide caption labels.
182 tw = self.GetTextExtent(self._caption)[0]
183 size.SetWidth(max(size.width, tw))
184 return size
185
186
187 def AddItem(self, item):
188 """
189 Add a window or sizer item to the caption box.
190 """
191
192 self._csizer.Add(item, 0, wx.ALL, 10)
193
194
195 def OnPaint(self, event):
196 """
197 Draws the Caption and border around the controls.
198 """
199
200 dc = wx.BufferedPaintDC(self)
201 dc.SetBackground(wx.Brush(wx.Colour(255, 255, 255, 255)))
202 dc.Clear()
203 gcdc = wx.GCDC(dc)
204
205 # Get the working rectangle we can draw in.
206 rect = self.GetClientRect()
207
208 # Get the sytem color to draw the caption.
209 ss = wx.SystemSettings
210 color = ss.GetColour(wx.SYS_COLOUR_3DDKSHADOW)
211 gcdc.SetTextForeground(wx.BLACK)
212
213 # Draw the border.
214 rect.Inflate(-0, -0)
215 gcdc.SetPen(wx.Pen(color))
216 gcdc.SetBrush(wx.Brush(wx.Colour(52, 64, 80, 255)))
217
218 # Font size and style.
219 font = self.GetFont().GetPointSize()
220 font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)
221 font.SetWeight(wx.BOLD)
222
223 # Add the Caption.
224 rect = wx.Rect(rect.x, rect.y, rect.width, 20)
225 rect.Inflate(-5, 0)
226 gcdc.SetFont(font)
227 gcdc.DrawLabel(self._caption, rect, wx.ALIGN_CENTER)
228
229 #---------------------------------------------------------------------------
230
231 class MyPanel(wx.Panel):
232 """
233 ...
234 """
235 def __init__(self, parent):
236 wx.Panel.__init__(self, parent)
237
238 #------------
239
240 self.SetBackgroundColour("white")
241
242 #------------
243
244 # Return bitmaps folder.
245 self.bitmaps_dir = wx.GetApp().GetBitmapsDir()
246
247 # Load a background bitmap.
248 self.bmp = wx.Bitmap(os.path.join(self.bitmaps_dir,
249 "gloss.png"),
250 type=wx.BITMAP_TYPE_PNG)
251
252 #------------
253
254 # Attributes.
255 self.box1 = MyCaptionBox(self, "Loading...")
256
257 #------------
258
259 # Pick the filename of an animated GIF file you have ...
260 # Give it the full path and file name.
261 animatedGif = Animation(os.path.join(self.bitmaps_dir,
262 "loader.gif"))
263 self.ag = AnimationCtrl(self.box1,
264 -1,
265 animatedGif)
266
267 # Clears the background.
268 self.ag.SetBackgroundColour(self.GetBackgroundColour())
269
270 # Continuously loop through the frames of
271 # the gif file (default).
272 self.ag.Play()
273
274 self.box1.AddItem(self.ag)
275
276 #------------
277
278 # Simplified init method.
279 self.BindEvents()
280 self.DoLayout()
281
282 #------------
283
284 self.SetClientSize((262, 282))
285
286 #-----------------------------------------------------------------------
287
288 def BindEvents(self):
289 """
290 ...
291 """
292
293 # Bind some events to an events handler.
294 self.Bind(wx.EVT_PAINT, self.OnPaint)
295 self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy)
296 self.box1.Bind(wx.EVT_MOUSE_EVENTS, self.OnMouseEvents)
297 self.ag.Bind(wx.EVT_MOUSE_EVENTS, self.OnMouseEvents)
298
299
300 def DoLayout(self):
301 """
302 ...
303 """
304
305 hsizer = wx.BoxSizer(wx.HORIZONTAL)
306 vsizer = wx.BoxSizer(wx.VERTICAL)
307
308 #------------
309
310 # Add the box to the panel.
311 hsizer.AddStretchSpacer()
312 hsizer.Add(self.box1, 0, wx.ALIGN_CENTER)
313 vsizer.AddStretchSpacer(40)
314 vsizer.Add(hsizer, 0, wx.ALIGN_CENTER)
315 vsizer.AddStretchSpacer()
316
317 self.SetSizer(vsizer)
318
319
320 def OnPaint(self, event):
321 """
322 ...
323 """
324
325 dc = wx.BufferedPaintDC(self)
326 dc.Clear()
327 gcdc = wx.GCDC(dc)
328 gcdc.Clear()
329
330 # Draw a bitmap with an alpha channel
331 # on top of the last group.
332 gcdc.DrawBitmap(self.bmp, 0, 0, False)
333
334
335 def OnMouseEvents(self, event):
336 """
337 Handles the wx.EVT_MOUSE_EVENTS for AdvancedSplash.
338 This reproduces the behavior of wx.SplashScreen.
339 """
340
341 if event.LeftDown() or event.RightDown():
342 splash = wx.GetApp().GetTopWindow()
343 splash.OnClose(event)
344
345 event.Skip()
346
347
348 def OnDestroy(self, event):
349 """
350 ...
351 """
352
353 event.Skip()
354
355 #---------------------------------------------------------------------------
356
357 class MySplash(wx.Frame):
358 """
359 ...
360 """
361 def __init__(self):
362
363 #--------------
364
365 screen = wx.ScreenDC()
366
367 # Screen size.
368 ws, hs = screen.GetSize()
369
370 #------------
371
372 # Return bitmaps folder.
373 self.bitmaps_dir = wx.GetApp().GetBitmapsDir()
374
375 # Load a background bitmap.
376 self.bmp = wx.Bitmap(os.path.join(self.bitmaps_dir,
377 "gloss.png"),
378 type=wx.BITMAP_TYPE_PNG)
379
380 mask = wx.Mask(self.bmp, wx.RED)
381 self.bmp.SetMask(mask)
382
383 # Determine size of bitmap.
384 wi, hi = self.bmp.GetWidth(), self.bmp.GetHeight()
385 print("\n... Bitmap size : %sx%s px" % (wi, hi))
386
387 x = int((ws-wi)/2)
388 y = int((hs-hi)/2)
389
390 #--------------
391
392 super(MySplash, self).__init__(parent=None,
393 id=-1,
394 title="SplashScreen",
395 pos=(x, y),
396 size=(wi, hi),
397 style=wx.FRAME_SHAPED |
398 wx.BORDER_NONE |
399 wx.FRAME_NO_TASKBAR |
400 wx.STAY_ON_TOP)
401
402 #--------------
403
404 self.SetBackgroundColour("white")
405
406 #--------------
407
408 # Attributes.
409 self.SetTransparent(0)
410 self.opacity_in = 0
411 self.deltaN = -30
412 self.hasShape = False
413
414 #--------------
415
416 if wx.Platform != "__WXMAC__":
417 # wxMac clips the tooltip to the window shape, YUCK!!!
418 self.SetToolTip("Right-click to close the window\n"
419 "Double-click the image to set/unset the window shape")
420
421 if wx.Platform == "__WXGTK__":
422 # wxGTK requires that the window be created before you can
423 # set its shape, so delay the call to SetWindowShape until
424 # this event.
425 self.Bind(wx.EVT_WINDOW_CREATE, self.SetWindowShape)
426 else:
427 # On wxMSW and wxMac the window has already
428 # been created, so go for it.
429 self.SetWindowShape()
430
431 #--------------
432
433 # Starts the Timer. Once Expired, splash is Destroyed.
434 self.timer = wx.Timer(self)
435
436 # Simulate long startup time.
437 self.timer.Start(4000)
438
439 self.Bind(wx.EVT_TIMER, self.TimeOut, self.timer)
440
441 #--------------
442
443 # Show main frame after 3000 ms.
444 self.fc = wx.CallLater(3000, self.ShowMainFrame)
445
446 #--------------
447
448 self.CenterOnScreen(wx.BOTH)
449 self.Show(True)
450
451 #--------------
452
453 # Simplified init method.
454 self.OnTimerIn(self)
455 self.CreateCtrls()
456 self.DoLayout()
457
458 #--------------
459
460 print("\n... Display the splashScreen")
461
462 #--------------
463
464 self.SetClientSize((wi, hi))
465 wx.BeginBusyCursor()
466
467 #-----------------------------------------------------------------------
468
469 def OnTimerIn(self, evt):
470 """
471 Thanks to Pascal Faut.
472 """
473
474 self.timer1 = wx.Timer(self, -1)
475 self.timer1.Start(1)
476 self.Bind(wx.EVT_TIMER, self.AlphaCycle1, self.timer1)
477
478 print("Fade-in was launched.")
479
480
481 def AlphaCycle1(self, *args):
482 """
483 Thanks to Pascal Faut.
484 """
485
486 self.opacity_in += self.deltaN
487 if self.opacity_in <= 0:
488 self.deltaN = -self.deltaN
489 self.opacity_in = 0
490
491 if self.opacity_in >= 255:
492 self.deltaN = -self.deltaN
493 self.opacity_in = 255
494
495 self.timer1.Stop()
496
497 self.SetTransparent(self.opacity_in)
498
499 print("Fade in = {}/255".format(self.opacity_in))
500
501
502 def CreateCtrls(self):
503 """
504 ...
505 """
506
507
508 self.panel = MyPanel(self)
509
510
511 def BindEvents(self):
512 """
513 Bind all the events related to my app.
514 """
515
516 # Bind some events to an events handler.
517 self.Bind(wx.EVT_CHAR, self.OnCharEvents)
518 self.Bind(wx.EVT_CLOSE, self.OnClose)
519 self.panel.Bind(wx.EVT_LEFT_DOWN, self.OnClose)
520 self.Bind(wx.EVT_CLOSE, self.CloseWindow)
521
522
523 def DoLayout(self):
524 """
525 ...
526 """
527
528 sizer = wx.BoxSizer(wx.VERTICAL)
529 sizer.Add(self.panel, 1, wx.EXPAND, 20)
530 self.SetSizer(sizer)
531
532
533 def SetWindowShape(self, *evt):
534 """
535 ...
536 """
537
538 # Use the bitmap's mask to determine the region.
539 r = wx.Region(self.bmp)
540 self.hasShape = self.SetShape(r)
541
542
543 def OnCharEvents(self, event):
544 """
545 Handles the wx.EVT_CHAR for Splash.
546 This reproduces the behavior of wx.SplashScreen.
547 """
548
549 self.OnClose(event)
550
551
552 def TimeOut(self, event):
553 """
554 ...
555 """
556
557 self.Close(True)
558
559
560 def OnClose(self, event):
561 """
562 Handles the wx.EVT_CLOSE event for SplashScreen.
563 """
564
565 # Make sure the default handler runs
566 # too so this window gets destroyed.
567 # Tell the event system to continue
568 # looking for an event handler, so the
569 # default handler will get called.
570 # event.Skip() # ?????
571 self.Hide()
572
573 #------------
574
575 # If the timer is still running then go
576 # ahead and show the main frame now.
577 if self.fc.IsRunning():
578 # Stop the wx.CallLater timer.
579 # Stop the splash screen timer
580 # and close it.
581 self.fc.Stop()
582 self.ShowMainFrame()
583
584
585 def ShowMainFrame(self):
586 """
587 ...
588 """
589
590 print("\n... Close the splash screen")
591 print("\n... Create and display the main frame")
592
593 #------------
594
595 wx.CallAfter(wx.EndBusyCursor)
596
597 #------------
598
599 if self.fc.IsRunning():
600 # Stop the splash screen
601 # timer and close it.
602 self.Raise()
603
604 #------------
605
606 # Create an instance of the MyFrame class.
607 frame = MyFrame()
608
609
610 def CloseWindow(self, event):
611 """
612 ...
613 """
614
615 self.timer.Stop()
616 self.Destroy()
617
618 #---------------------------------------------------------------------------
619
620 class MyApp(wx.App):
621 """
622 ...
623 """
624 def OnInit(self):
625
626 #------------
627
628 self.locale = wx.Locale(wx.LANGUAGE_ENGLISH)
629
630 #------------
631
632 self.SetAppName("Main frame")
633
634 #------------
635
636 self.installDir = os.path.split(os.path.abspath(sys.argv[0]))[0]
637
638 #------------
639
640 splash = MySplash()
641 splash.BindEvents()
642 splash.CenterOnScreen(wx.BOTH)
643
644 return True
645
646 #-----------------------------------------------------------------------
647
648 def GetInstallDir(self):
649 """
650 Returns the installation directory for my application.
651 """
652
653 return self.installDir
654
655
656 def GetIconsDir(self):
657 """
658 Returns the icons directory for my application.
659 """
660
661 icons_dir = os.path.join(self.installDir, "icons")
662 return icons_dir
663
664
665 def GetBitmapsDir(self):
666 """
667 Returns the bitmaps directory for my application.
668 """
669
670 bitmaps_dir = os.path.join(self.installDir, "bitmaps")
671 return bitmaps_dir
672
673 #---------------------------------------------------------------------------
674
675 def main():
676 app = MyApp(False)
677 app.MainLoop()
678
679 #---------------------------------------------------------------------------
680
681 if __name__ == "__main__" :
682 main()
With masked area
1 # sample_five.py
2
3 import os
4 import sys
5 import platform
6 import wx
7
8 # class MyFrame
9 # class MyPanel
10 # class MySplash
11 # class MyApp
12
13 #---------------------------------------------------------------------------
14
15 class MyFrame(wx.Frame):
16 """
17 ...
18 """
19 def __init__(self):
20 super(MyFrame, self).__init__(None,
21 -1,
22 title="")
23
24 #------------
25
26 # Return application name.
27 self.app_name = wx.GetApp().GetAppName()
28 # Return icons folder.
29 self.icons_dir = wx.GetApp().GetIconsDir()
30
31 #------------
32
33 # Simplified init method.
34 self.SetProperties()
35 self.CreateCtrls()
36 self.BindEvents()
37 self.DoLayout()
38
39 #------------
40
41 self.CenterOnScreen(wx.BOTH)
42
43 #------------
44
45 self.Show(True)
46
47 #-----------------------------------------------------------------------
48
49 def SetProperties(self):
50 """
51 ...
52 """
53
54 self.SetTitle(self.app_name)
55 self.SetSize((340, 250))
56
57 #------------
58
59 frameIcon = wx.Icon(os.path.join(self.icons_dir,
60 "icon_wxWidgets.ico"),
61 type=wx.BITMAP_TYPE_ICO)
62 self.SetIcon(frameIcon)
63
64
65 def CreateCtrls(self):
66 """
67 ...
68 """
69
70 # Create a panel.
71 self.panel = wx.Panel(self, -1)
72
73 #------------
74
75 # Add a buttons.
76 self.btnClose = wx.Button(self.panel,
77 -1,
78 "&Close")
79
80
81 def BindEvents(self):
82 """
83 Bind some events to an events handler.
84 """
85
86 # Bind events to an events handler.
87 self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
88 self.Bind(wx.EVT_BUTTON, self.OnCloseMe, self.btnClose)
89
90
91 def DoLayout(self):
92 """
93 ...
94 """
95
96 # MainSizer is the top-level one that manages everything.
97 mainSizer = wx.BoxSizer(wx.VERTICAL)
98
99 # wx.BoxSizer(window, proportion, flag, border)
100 # wx.BoxSizer(sizer, proportion, flag, border)
101 mainSizer.Add(self.btnClose, 1, wx.EXPAND | wx.ALL, 10)
102
103 # Finally, tell the panel to use the sizer for layout.
104 self.panel.SetAutoLayout(True)
105 self.panel.SetSizer(mainSizer)
106
107 mainSizer.Fit(self.panel)
108
109
110 def OnCloseMe(self, event):
111 """
112 ...
113 """
114
115 self.Close(True)
116
117
118 def OnCloseWindow(self, event):
119 """
120 ...
121 """
122
123 self.Destroy()
124
125 #---------------------------------------------------------------------------
126
127 class MyPanel(wx.Panel):
128 """
129 ...
130 """
131 def __init__(self, parent):
132 wx.Panel.__init__(self, parent)
133
134 #------------
135
136 self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
137
138 #------------
139
140 # Return bitmaps folder.
141 self.bitmaps_dir = wx.GetApp().GetBitmapsDir()
142
143 # Load a background bitmap.
144 self.bmp = wx.Bitmap(os.path.join(self.bitmaps_dir,
145 "mask.png"),
146 type=wx.BITMAP_TYPE_PNG)
147
148 #------------
149
150 # Simplified init method.
151 self.BindEvents()
152
153 #-----------------------------------------------------------------------
154
155 def BindEvents(self):
156 """
157 ...
158 """
159
160 # Bind event to an events handler.
161 self.Bind(wx.EVT_PAINT, self.OnPaint)
162 self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy)
163
164
165 def OnPaint(self, event):
166 """
167 ...
168 """
169
170 dc = wx.BufferedPaintDC(self)
171 dc.Clear()
172 gcdc = wx.GCDC(dc)
173 gcdc.Clear()
174
175 # Draw a bitmap with an alpha channel
176 # on top of the last group.
177 gcdc.DrawBitmap(self.bmp, 0, 0, False)
178
179
180 def OnMouseEvents(self, event):
181 """
182 Handles the wx.EVT_MOUSE_EVENTS for AdvancedSplash.
183 This reproduces the behavior of wx.SplashScreen.
184 """
185
186 if event.LeftDown() or event.RightDown():
187 splash = wx.GetApp().GetTopWindow()
188 splash.OnClose(event)
189
190 event.Skip()
191
192
193 def OnDestroy(self, event):
194 """
195 ...
196 """
197
198 event.Skip()
199
200 #---------------------------------------------------------------------------
201
202 class MySplash(wx.Frame):
203 """
204 ...
205 """
206 def __init__(self,
207 parent=None,
208 id=-1,
209 title="SplashScreen",
210 pos=wx.DefaultPosition,
211 size=wx.DefaultSize,
212 style=wx.FRAME_SHAPED |
213 wx.BORDER_NONE |
214 wx.FRAME_NO_TASKBAR |
215 wx.STAY_ON_TOP):
216
217 #--------------
218
219 # Return bitmaps folder.
220 self.bitmaps_dir = wx.GetApp().GetBitmapsDir()
221
222 # Load a background bitmap.
223 self.bmp = wx.Bitmap(os.path.join(self.bitmaps_dir,
224 "mask.png"),
225 type=wx.BITMAP_TYPE_PNG)
226
227 mask = wx.Mask(self.bmp, wx.RED)
228 self.bmp.SetMask(mask)
229
230 # Determine size of bitmap.
231 w, h = self.bmp.GetWidth(), self.bmp.GetHeight()
232 print("\n... Bitmap size : %sx%s px" % (w, h))
233
234 #--------------
235
236 super(MySplash, self).__init__(parent,
237 id,
238 title,
239 pos,
240 size,
241 style)
242
243 #--------------
244
245 self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
246
247 #--------------
248
249 # Attributes.
250 self.hasShape = False
251
252 #--------------
253
254 if wx.Platform != "__WXMAC__":
255 # wxMac clips the tooltip to the window shape, YUCK!!!
256 self.SetToolTip("Right-click to close the window\n"
257 "Double-click the image to set/unset the window shape")
258
259 if wx.Platform == "__WXGTK__":
260 # wxGTK requires that the window be created before you can
261 # set its shape, so delay the call to SetWindowShape until
262 # this event.
263 self.Bind(wx.EVT_WINDOW_CREATE, self.SetWindowShape)
264 else:
265 # On wxMSW and wxMac the window has already
266 # been created, so go for it.
267 self.SetWindowShape()
268
269 #--------------
270
271 # Starts the Timer. Once Expired, splash is Destroyed.
272 self.timer = wx.Timer(self)
273
274 # Simulate long startup time.
275 self.timer.Start(4000)
276
277 self.Bind(wx.EVT_TIMER, self.TimeOut, self.timer)
278
279 #--------------
280
281 # Show main frame after 3000 ms.
282 self.fc = wx.CallLater(3000, self.ShowMainFrame)
283
284 #--------------
285
286 self.CenterOnScreen(wx.BOTH)
287 self.Show(True)
288
289 #--------------
290
291 # Simplified init method.
292 self.CreateCtrls()
293 self.DoLayout()
294
295 #--------------
296
297 print("\n... Display the splashScreen")
298
299 #--------------
300
301 self.SetClientSize((w, h))
302 wx.BeginBusyCursor()
303
304 #-----------------------------------------------------------------------
305
306 def CreateCtrls(self):
307 """
308 ...
309 """
310
311 self.panel = MyPanel(self)
312
313
314 def BindEvents(self):
315 """
316 Bind all the events related to my app.
317 """
318
319 # Bind some events to an events handler.
320 self.Bind(wx.EVT_CHAR, self.OnCharEvents)
321 self.Bind(wx.EVT_CLOSE, self.OnClose)
322 self.panel.Bind(wx.EVT_LEFT_DOWN, self.OnClose)
323 self.Bind(wx.EVT_CLOSE, self.CloseWindow)
324
325
326 def DoLayout(self):
327 """
328 ...
329 """
330
331 sizer = wx.BoxSizer(wx.VERTICAL)
332 sizer.Add(self.panel, 1, wx.EXPAND)
333 self.SetSizer(sizer)
334
335
336 def SetWindowShape(self, *evt):
337 """
338 ...
339 """
340
341 # Use the bitmap's mask to determine the region.
342 r = wx.Region(self.bmp)
343 self.hasShape = self.SetShape(r)
344
345
346 def OnCharEvents(self, event):
347 """
348 Handles the wx.EVT_CHAR for Splash.
349 This reproduces the behavior of wx.SplashScreen.
350 """
351
352 self.OnClose(event)
353
354
355 def TimeOut(self, event):
356 """
357 ...
358 """
359
360 self.Close(True)
361
362
363 def OnClose(self, event):
364 """
365 Handles the wx.EVT_CLOSE event for SplashScreen.
366 """
367
368 # Make sure the default handler runs
369 # too so this window gets destroyed.
370 # Tell the event system to continue
371 # looking for an event handler, so the
372 # default handler will get called.
373 event.Skip()
374 self.Hide()
375
376 #------------
377
378 # If the timer is still running then go
379 # ahead and show the main frame now.
380 if self.fc.IsRunning():
381 # Stop the wx.CallLater timer.
382 # Stop the splash screen timer
383 # and close it.
384 self.fc.Stop()
385 self.ShowMainFrame()
386
387
388 def ShowMainFrame(self):
389 """
390 ...
391 """
392
393 print("\n... Close the splash screen")
394 print("\n... Create and display the main frame")
395
396 #------------
397
398 wx.CallAfter(wx.EndBusyCursor)
399
400 #------------
401
402 if self.fc.IsRunning():
403 # Stop the splash screen
404 # timer and close it.
405 self.Raise()
406
407 #------------
408
409 # Create an instance of the MyFrame class.
410 frame = MyFrame()
411
412
413 def CloseWindow(self, event):
414 """
415 ...
416 """
417
418 self.timer.Stop()
419 self.Destroy()
420
421 #---------------------------------------------------------------------------
422
423 class MyApp(wx.App):
424 """
425 ...
426 """
427 def OnInit(self):
428
429 #------------
430
431 self.locale = wx.Locale(wx.LANGUAGE_ENGLISH)
432
433 #------------
434
435 self.SetAppName("Main frame")
436
437 #------------
438
439 self.installDir = os.path.split(os.path.abspath(sys.argv[0]))[0]
440
441 #------------
442
443 splash = MySplash(None, -1)
444 splash.BindEvents()
445 splash.CenterOnScreen(wx.BOTH)
446
447 return True
448
449 #-----------------------------------------------------------------------
450
451 def GetInstallDir(self):
452 """
453 Returns the installation directory for my application.
454 """
455
456 return self.installDir
457
458
459 def GetIconsDir(self):
460 """
461 Returns the icons directory for my application.
462 """
463
464 icons_dir = os.path.join(self.installDir, "icons")
465 return icons_dir
466
467
468 def GetBitmapsDir(self):
469 """
470 Returns the bitmaps directory for my application.
471 """
472
473 bitmaps_dir = os.path.join(self.installDir, "bitmaps")
474 return bitmaps_dir
475
476 #---------------------------------------------------------------------------
477
478 def main():
479 app = MyApp(False)
480 app.MainLoop()
481
482 #---------------------------------------------------------------------------
483
484 if __name__ == "__main__" :
485 main()
With advancedsplash (Andrea Gavana)
Available with wxPython demo (Advanced Generic Widgets (AGW)).
1 # sample_six.py
2
3 import sys
4 import os
5 import wx
6
7 #-------------------------------------------------------------------------------
8 # ADVANCEDSPLASH Control wxPython IMPLEMENTATION
9 # Python Code By:
10 #
11 # Andrea Gavana, @ 10 Oct 2005
12 # Latest Revision: 19 Dec 2012, 21.00 GMT
13 #
14 #
15 # TODO List/Caveats
16 #
17 # 1. Actually, Setting The Shape Of AdvancedSplash Is Done Using "SetShape"
18 # Function On A Frame. This Works, AFAIK, On This Following Platforms:
19 #
20 # - MSW
21 # - UNIX/Linux
22 # - MacOS Carbon
23 #
24 # Obviously I May Be Wrong Here. Could Someone Verify That Lines 139-145
25 # Work Correctly On Other Platforms Than Mine (MSW XP/2000)?
26 # Moreover, Is There A Way To Avoid The Use Of The "SetShape" Method?
27 # I Don't Know.
28 #
29 #
30 # For All Kind Of Problems, Requests Of Enhancements And Bug Reports, Please
31 # Write To Me At:
32 #
33 # andrea.gavana@gmail.com
34 # andrea.gavana@maerskoil.com
35 #
36 # Or, Obviously, To The wxPython Mailing List!!!
37 #
38 # Tags: phoenix-port, unittest, documented, py3-port
39 #
40 # End Of Comments
41 #-------------------------------------------------------------------------------
42
43
44 """
45
46 :class:`~wx.lib.agw.advancedsplash.AdvancedSplash` tries to reproduce the behavior
47 of :class:`~adv.SplashScreen`, with some enhancements.
48
49
50 Description
51 ===========
52
53 :class:`AdvancedSplash` tries to reproduce the behavior of :class:`~adv.SplashScreen`,
54 but with some enhancements (in my opinion).
55
56 :class:`AdvancedSplash` starts its construction from a simple frame. Then, depending
57 on the options passed to it, it sets the frame shape accordingly to the image passed
58 as input. :class:`AdvancedSplash` behaves somewhat like :class:`~adv.SplashScreen`,
59 and almost all the methods available in :class:`~adv.SplashScreen` are available also
60 in this module.
61
62
63 Usage
64 =====
65
66 Sample usage::
67
68 import wx
69 import wx.lib.agw.advancedsplash as AS
70
71 app = wx.App(0)
72
73 frame = wx.Frame(None, -1, "AdvancedSplash Test")
74
75 imagePath = "my_splash_image.png"
76 bitmap = wx.Bitmap(imagePath, wx.BITMAP_TYPE_PNG)
77 shadow = wx.WHITE
78
79 splash = AS.AdvancedSplash(frame, bitmap=bitmap, timeout=5000,
80 agwStyle=AS.AS_TIMEOUT |
81 AS.AS_CENTER_ON_PARENT |
82 AS.AS_SHADOW_BITMAP,
83 shadowcolour=shadow)
84
85 app.MainLoop()
86
87
88 None of the options are strictly required (a part of the `bitmap` parameter).
89 If you use the defaults you get a very simple :class:`AdvancedSplash`.
90
91
92 Methods and Settings
93 ====================
94
95 :class:`AdvancedSplash` is customizable, and in particular you can set:
96
97 - Whether you want to mask a colour or not in your input bitmap;
98 - Where to center the splash screen (on screen, on parent or nowhere);
99 - Whether it is a "timeout" splashscreen or not;
100 - The time after which :class:`AdvancedSplash` is destroyed (if it is a timeout splashscreen);
101 - The (optional) text you wish to display;
102 - The font, colour and position of the displayed text (optional).
103
104
105 Window Styles
106 =============
107
108 This class supports the following window styles:
109
110 ======================= =========== ==================================================
111 Window Styles Hex Value Description
112 ======================= =========== ==================================================
113 ``AS_TIMEOUT`` 0x1 :class:`AdvancedSplash` will be destroyed after `timeout` milliseconds.
114 ``AS_NOTIMEOUT`` 0x2 :class:`AdvancedSplash` can be destroyed by clicking on it,
115 pressing a key or by explicitly call the `Close()` method.
116 ``AS_CENTER_ON_SCREEN`` 0x4 :class:`AdvancedSplash` will be centered on screen.
117 ``AS_CENTER_ON_PARENT`` 0x8 :class:`AdvancedSplash` will be centered on parent.
118 ``AS_NO_CENTER`` 0x10 :class:`AdvancedSplash` will not be centered.
119 ``AS_SHADOW_BITMAP`` 0x20 If the bitmap you pass as input has no transparency,
120 you can choose one colour that will be masked in your bitmap.
121 the final shape of :class:`AdvancedSplash` will be defined only
122 by non-transparent (non-masked) pixels.
123 ======================= =========== ==================================================
124
125
126 Events Processing
127 =================
128
129 `No custom events are available for this class.`
130
131
132 License And Version
133 ===================
134
135 :class:`AdvancedSplash` control is distributed under the wxPython license.
136
137 Latest revision: Andrea Gavana @ 19 Dec 2012, 21.00 GMT
138
139 Version 0.5
140
141 """
142
143 # def opj
144 # class AdvancedSplash
145 # class MyFrame
146 # class MyApp
147
148 #-------------------------------------------------------------------------------
149 # Beginning Of ADVANCEDSPLASH wxPython Code.
150 #-------------------------------------------------------------------------------
151
152 # These Are Used To Declare If The AdvancedSplash Should Be
153 # Destroyed After The Timeout Or Not.
154 AS_TIMEOUT = 1
155 """:class:`AdvancedSplash` will be destroyed after `timeout` milliseconds. """
156 AS_NOTIMEOUT = 2
157 """ :class:`AdvancedSplash` can be destroyed by clicking on it,
158 pressing a key or by explicitly call the `Close()` method. """
159
160 # These Flags Are Used To Position AdvancedSplash Correctly On Screen.
161 AS_CENTER_ON_SCREEN = 4
162 """ :class:`AdvancedSplash` will be centered on screen. """
163 AS_CENTER_ON_PARENT = 8
164 """ :class:`AdvancedSplash` will be centered on parent. """
165 AS_NO_CENTER = 16
166 """ :class:`AdvancedSplash` will not be centered. """
167
168 # This Option Allow To Mask A Colour In The Input Bitmap.
169 AS_SHADOW_BITMAP = 32
170 """ If the bitmap you pass as input has no transparency,
171 you can choose one colour that will be masked in your bitmap.
172 The final shape of :class:`AdvancedSplash` will be defined
173 only by non-transparent (non-masked) pixels. """
174
175 #-------------------------------------------------------------------------------
176
177 def opj(path):
178 """
179 Convert paths to the platform-specific separator.
180 """
181
182 st = os.path.join(*tuple(path.split('/')))
183 # HACK: on Linux, a leading / gets lost...
184 if path.startswith('/'):
185 st = '/' + st
186 return st
187
188 #-------------------------------------------------------------------------------
189 # ADVANCEDSPLASH Class.
190 # This Is The Main Class Implementation. See __init__() Method For
191 # details.
192 #-------------------------------------------------------------------------------
193
194 class AdvancedSplash(wx.Frame):
195 """
196 :class:`AdvancedSplash` tries to reproduce the behavior of :class:`~adv.SplashScreen`, with
197 some enhancements.
198
199 This is the main class implementation.
200 """
201 def __init__(self, parent, id=-1, pos=wx.DefaultPosition, size=wx.DefaultSize,
202 style=wx.FRAME_NO_TASKBAR | wx.FRAME_SHAPED | wx.STAY_ON_TOP,
203 bitmap=None, timeout=5000,
204 agwStyle=AS_TIMEOUT | AS_CENTER_ON_SCREEN,
205 shadowcolour=wx.NullColour):
206 """
207 Default class constructor.
208
209 :param `parent`: parent window;
210 :param integer `id`: window identifier. A value of -1 indicates a default value;
211 :param `pos`: the control position. A value of (-1, -1) indicates a default position,
212 chosen by either the windowing system or wxPython, depending on platform;
213 :param `size`: the control size. A value of (-1, -1) indicates a default size,
214 chosen by either the windowing system or wxPython, depending on platform;
215 :param integer `style`: the underlying :class:`wx.Frame` style;
216 :param `bitmap`: this must be a valid bitmap, that you may construct using
217 whatever image file format supported by wxPython. If the file you load
218 already supports mask/transparency (like png), the transparent areas
219 will not be drawn on screen, and the :class:`AdvancedSplash` frame will have
220 the shape defined only by *non-transparent* pixels.
221 If you use other file formats that does not supports transparency, you
222 can obtain the same effect as above by masking a specific colour in
223 your :class:`wx.Bitmap`.
224 :param integer `timeout`: if you construct :class:`AdvancedSplash` using the style ``AS_TIMEOUT``,
225 :class:`AdvancedSplash` will be destroyed after `timeout` milliseconds;
226 :param integer `agwStyle`: this value specifies the :class:`AdvancedSplash` styles:
227
228 ======================= =========== ==================================================
229 Window Styles Hex Value Description
230 ======================= =========== ==================================================
231 ``AS_TIMEOUT`` 0x1 :class:`AdvancedSplash` will be destroyed after `timeout` milliseconds.
232 ``AS_NOTIMEOUT`` 0x2 :class:`AdvancedSplash` can be destroyed by clicking on it,
233 pressing a key or by explicitly call the `Close()` method.
234 ``AS_CENTER_ON_SCREEN`` 0x4 :class:`AdvancedSplash` will be centered on screen.
235 ``AS_CENTER_ON_PARENT`` 0x8 :class:`AdvancedSplash` will be centered on parent.
236 ``AS_NO_CENTER`` 0x10 :class:`AdvancedSplash` will not be centered.
237 ``AS_SHADOW_BITMAP`` 0x20 If the bitmap you pass as input has no transparency,
238 you can choose one colour that will be masked in your bitmap.
239 The final shape of :class:`AdvancedSplash` will be defined
240 only by non-transparent (non-masked) pixels.
241 ======================= =========== ==================================================
242
243 :param `shadowcolour`: if you construct :class:`AdvancedSplash` using the style
244 ``AS_SHADOW_BITMAP``, here you can specify the colour that will be masked on
245 your input bitmap. This has to be a valid wxPython colour.
246
247 :type parent: :class:`wx.Window`
248 :type pos: tuple or :class:`wx.Point`
249 :type size: tuple or :class:`wx.Size`
250 :type bitmap: :class:`wx.Bitmap`
251 :type shadowcolour: :class:`wx.Colour`
252
253 :raise: `Exception` in the following cases:
254
255 - The ``AS_TIMEOUT`` style is set but `timeout` is not a positive integer;
256 - The ``AS_SHADOW_BITMAP`` style is set but `shadowcolour` is not a valid wxPython colour;
257 - The :class:`AdvancedSplash` bitmap is an invalid :class:`wx.Bitmap`.
258 """
259
260 wx.Frame.__init__(self, parent, id, "", pos, size, style)
261
262 # Some Error Checking.
263 if agwStyle & AS_TIMEOUT and timeout <= 0:
264 raise Exception('\nERROR: Style "AS_TIMEOUT" Used With Invalid "timeout" Parameter Value (' \
265 + str(timeout) + ')')
266
267 if agwStyle & AS_SHADOW_BITMAP and not shadowcolour.IsOk():
268 raise Exception('\nERROR: Style "AS_SHADOW_BITMAP" Used With Invalid "shadowcolour" Parameter')
269
270 if not bitmap or not bitmap.IsOk():
271 raise Exception("\nERROR: Bitmap Passed To AdvancedSplash Is Invalid.")
272
273 if agwStyle & AS_SHADOW_BITMAP:
274 # Our Bitmap Is Masked Accordingly To User Input.
275 self.bmp = self.ShadowBitmap(bitmap, shadowcolour)
276 else:
277 self.bmp = bitmap
278
279 self._agwStyle = agwStyle
280
281 #--------------
282
283 # Attributes.
284 self.SetTransparent(0)
285 self.opacity_in = 0
286 self.deltaN = -50
287
288 #--------------
289
290 # Setting Initial Properties.
291 self.SetText()
292 self.SetTextFont()
293 self.SetTextPosition()
294 self.SetTextColour()
295
296 #------------
297
298 # Calculate The Shape Of AdvancedSplash Using The Input-Modified Bitmap.
299 self.reg = wx.Region(self.bmp)
300
301 # Don't Know If It Works On Other Platforms!!
302 # Tested Only In Windows XP/2000.
303
304 if wx.Platform == "__WXGTK__":
305 self.Bind(wx.EVT_WINDOW_CREATE, self.SetSplashShape)
306 else:
307 self.SetSplashShape()
308
309 #------------
310
311 w = self.bmp.GetWidth() + 1
312 h = self.bmp.GetHeight() + 1
313
314 # Set The AdvancedSplash Size To The Bitmap Size.
315 self.SetClientSize((w, h))
316
317 #------------
318
319 if agwStyle & AS_CENTER_ON_SCREEN:
320 self.CenterOnScreen()
321 elif agwStyle & AS_CENTER_ON_PARENT:
322 self.CenterOnParent()
323
324 if agwStyle & AS_TIMEOUT:
325 # Starts The Timer. Once Expired, AdvancedSplash Is Destroyed.
326 self._splashtimer = wx.Timer(self)
327 self.Bind(wx.EVT_TIMER, self.OnNotify)
328 self._splashtimer.Start(timeout)
329
330 #------------
331
332 # Catch Some Mouse Events, To Behave Like wx.SplashScreen.
333 self.Bind(wx.EVT_PAINT, self.OnPaint)
334 self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
335 self.Bind(wx.EVT_MOUSE_EVENTS, self.OnMouseEvents)
336 self.Bind(wx.EVT_CHAR, self.OnCharEvents)
337
338 #------------
339
340 # Show main frame after 3000 ms.
341 self.fc = wx.CallLater(3000, self.ShowMainFrame)
342
343 #------------
344
345 # Simplified init method.
346 self.OnTimerIn(self)
347
348 #------------
349
350 self.Show()
351
352 if wx.Platform == "__WXMAC__":
353 wx.SafeYield(self, True)
354
355 #------------
356
357 wx.BeginBusyCursor()
358
359 #---------------------------------------------------------------------------
360
361 def OnTimerIn(self, evt):
362 """
363 Thanks to Pascal Faut.
364 """
365
366 self.timer1 = wx.Timer(self, -1)
367 self.timer1.Start(1)
368 self.Bind(wx.EVT_TIMER, self.AlphaCycle1, self.timer1)
369
370 print("Fade-in was launched.")
371
372
373 def AlphaCycle1(self, *args):
374 """
375 Thanks to Pascal Faut.
376 """
377
378 self.opacity_in += self.deltaN
379 if self.opacity_in <= 0:
380 self.deltaN = -self.deltaN
381 self.opacity_in = 0
382
383 if self.opacity_in >= 255:
384 self.deltaN = -self.deltaN
385 self.opacity_in = 255
386
387 self.timer1.Stop()
388
389 self.SetTransparent(self.opacity_in)
390
391 print("Fade in = {}/255".format(self.opacity_in))
392
393
394 def SetSplashShape(self, event=None):
395 """
396 Sets :class:`AdvancedSplash` shape using the region created from the bitmap.
397
398 :param `event`: a :class:`wx.WindowCreateEvent` event (GTK only, as GTK supports setting
399 the window shape only during window creation).
400 """
401
402 self.SetShape(self.reg)
403
404 if event is not None:
405 event.Skip()
406
407
408 def ShadowBitmap(self, bmp, shadowcolour):
409 """
410 Applies a mask on the bitmap accordingly to user input.
411
412 :param `bmp`: the bitmap to which we want to apply the mask colour `shadowcolour`;
413 :param `shadowcolour`: the mask colour for our bitmap.
414 :type bmp: :class:`wx.Bitmap`
415 :type shadowcolour: :class:`wx.Colour`
416
417 :return: A masked version of the input bitmap, an instance of :class:`wx.Bitmap`.
418 """
419
420 mask = wx.Mask(bmp, shadowcolour)
421 bmp.SetMask(mask)
422
423 return bmp
424
425
426 def OnPaint(self, event):
427 """
428 Handles the ``wx.EVT_PAINT`` event for :class:`AdvancedSplash`.
429
430 :param `event`: a :class:`PaintEvent` to be processed.
431 """
432
433 dc = wx.BufferedPaintDC(self)
434
435 # Here We Redraw The Bitmap Over The Frame.
436 dc.DrawBitmap(self.bmp, -1, -1, True)
437
438 # We Draw The Text Anyway, Wheter It Is Empty ("") Or Not.
439 textcolour = self.GetTextColour()
440 textfont = self.GetTextFont()
441 textpos = self.GetTextPosition()
442 text = self.GetText()
443
444 dc.SetFont(textfont[0])
445 dc.SetTextForeground(textcolour)
446 dc.DrawText(text, textpos[0], textpos[1])
447
448
449 def OnNotify(self, event):
450 """
451 Handles the timer expiration, and calls the `Close()` method.
452
453 :param `event`: a :class:`wx.TimerEvent` to be processed.
454 """
455
456 self.Close()
457
458
459 def OnMouseEvents(self, event):
460 """
461 Handles the ``wx.EVT_MOUSE_EVENTS`` events for :class:`AdvancedSplash`.
462
463 :param `event`: a :class:`MouseEvent` to be processed.
464
465 :note: This reproduces the behavior of :class:`~adv.SplashScreen`.
466 """
467
468 if event.LeftDown() or event.RightDown():
469 self.OnClose(event)
470
471 event.Skip()
472
473
474 def OnCharEvents(self, event):
475 """
476 Handles the ``wx.EVT_CHAR`` event for :class:`AdvancedSplash`.
477
478 :param `event`: a :class:`KeyEvent` to be processed.
479
480 :note: This reproduces the behavior of :class:`~adv.SplashScreen`.
481 """
482
483 self.OnClose(event)
484
485
486 def OnCloseWindow(self, event):
487 """
488 Handles the ``wx.EVT_CLOSE`` event for :class:`AdvancedSplash`.
489
490 :param `event`: a :class:`CloseEvent` to be processed.
491
492 :note: This reproduces the behavior of :class:`~adv.SplashScreen`.
493 """
494
495 if hasattr(self, "_splashtimer"):
496 self._splashtimer.Stop()
497 del self._splashtimer
498
499 self.Destroy()
500
501
502 def OnClose(self, event):
503 """
504 Handles the wx.EVT_CLOSE event for SplashScreen.
505 """
506
507 # Make sure the default handler runs
508 # too so this window gets destroyed.
509 # Tell the event system to continue
510 # looking for an event handler, so the
511 # default handler will get called.
512 event.Skip()
513 self.Hide()
514
515 #------------
516
517 # If the timer is still running then go
518 # ahead and show the main frame now.
519 if self.fc.IsRunning():
520 # Stop the wx.CallLater timer.
521 # Stop the splash screen timer
522 # and close it.
523 self.fc.Stop()
524 self.ShowMainFrame()
525
526
527 def SetText(self, text=None):
528 """
529 Sets the text to be displayed on :class:`AdvancedSplash`.
530
531 :param `text`: the text we want to display on top of the bitmap. If `text` is
532 set to ``None``, nothing will be drawn on top of the bitmap.
533 :type text: string or ``None``
534 """
535
536 if text is None:
537 text = ""
538
539 self._text = text
540
541 self.Refresh()
542 self.Update()
543
544
545 def GetText(self):
546 """
547 Returns the text displayed on :class:`AdvancedSplash`.
548
549 :return: A string representing the text drawn on top of the :class:`AdvancedSplash` bitmap.
550 """
551
552 return self._text
553
554
555 def SetTextFont(self, font=None):
556 """
557 Sets the font for the text in :class:`AdvancedSplash`.
558
559 :param `font`: the font to use while drawing the text on top of our bitmap. If `font`
560 is ``None``, a simple generic font is generated.
561 :type font: :class:`wx.Font` or ``None``
562 """
563
564 if font is None:
565 self._textfont = wx.Font(1, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD, False)
566 self._textsize = 10.0
567 self._textfont.SetPointSize(int(self._textsize))
568 else:
569 self._textfont = font
570 self._textsize = font.GetPointSize()
571 self._textfont.SetPointSize(int(self._textsize))
572
573 self.Refresh()
574 self.Update()
575
576
577 def GetTextFont(self):
578 """
579 Gets the font for the text in :class:`AdvancedSplash`.
580
581 :return: An instance of :class:`wx.Font` to draw the text and a :class:`wx.Size` object containing
582 the text width an height, in pixels.
583 """
584
585 return self._textfont, self._textsize
586
587
588 def SetTextColour(self, colour=None):
589 """
590 Sets the colour for the text in :class:`AdvancedSplash`.
591
592 :param `colour`: the text colour to use while drawing the text on top of our
593 bitmap. If `colour` is ``None``, then ``wx.BLACK`` is used.
594 :type colour: :class:`wx.Colour` or ``None``
595 """
596
597 if colour is None:
598 colour = wx.BLACK
599
600 self._textcolour = colour
601 self.Refresh()
602 self.Update()
603
604
605 def GetTextColour(self):
606 """
607 Gets the colour for the text in :class:`AdvancedSplash`.
608
609 :return: An instance of :class:`wx.Colour`.
610 """
611
612 return self._textcolour
613
614
615 def SetTextPosition(self, position=None):
616 """
617 Sets the text position inside :class:`AdvancedSplash` frame.
618
619 :param `position`: the text position inside our bitmap. If `position` is ``None``,
620 the text will be placed at the top-left corner.
621 :type position: tuple or ``None``
622 """
623
624 if position is None:
625 position = (0, 0)
626
627 self._textpos = position
628 self.Refresh()
629 self.Update()
630
631
632 def GetTextPosition(self):
633 """
634 Returns the text position inside :class:`AdvancedSplash` frame.
635
636 :return: A tuple containing the text `x` and `y` position inside the :class:`AdvancedSplash` frame.
637 """
638
639 return self._textpos
640
641
642 def GetSplashStyle(self):
643 """
644 Returns a list of strings and a list of integers containing the styles.
645
646 :return: Two Python lists containing the style name and style values for :class:`AdvancedSplash`.
647 """
648
649 stringstyle = []
650 integerstyle = []
651
652 if self._agwStyle & AS_TIMEOUT:
653 stringstyle.append("AS_TIMEOUT")
654 integerstyle.append(AS_TIMEOUT)
655
656 if self._agwStyle & AS_NOTIMEOUT:
657 stringstyle.append("AS_NOTIMEOUT")
658 integerstyle.append(AS_NOTIMEOUT)
659
660 if self._agwStyle & AS_CENTER_ON_SCREEN:
661 stringstyle.append("AS_CENTER_ON_SCREEN")
662 integerstyle.append(AS_CENTER_ON_SCREEN)
663
664 if self._agwStyle & AS_CENTER_ON_PARENT:
665 stringstyle.append("AS_CENTER_ON_PARENT")
666 integerstyle.append(AS_CENTER_ON_PARENT)
667
668 if self._agwStyle & AS_NO_CENTER:
669 stringstyle.append("AS_NO_CENTER")
670 integerstyle.append(AS_NO_CENTER)
671
672 if self._agwStyle & AS_SHADOW_BITMAP:
673 stringstyle.append("AS_SHADOW_BITMAP")
674 integerstyle.append(AS_SHADOW_BITMAP)
675
676 return stringstyle, integerstyle
677
678
679 def ShowMainFrame(self):
680 """
681 ...
682 """
683
684 #------------
685
686 wx.CallAfter(wx.EndBusyCursor)
687
688 #------------
689
690 if self.fc.IsRunning():
691 # Stop the splash screen
692 # timer and close it.
693 self.Raise()
694
695 #------------
696
697 # Create an instance of the MyFrame class.
698 frame = MyFrame()
699 frame.Center()
700 frame.Show(True)
701
702 #-------------------------------------------------------------------------------
703
704 class MyFrame(wx.Frame):
705 """
706 ...
707 """
708 def __init__(self):
709 super(MyFrame, self).__init__(None,
710 -1,
711 title="")
712
713 #------------
714
715 # Return application name.
716 self.app_name = wx.GetApp().GetAppName()
717 # Return icons folder.
718 self.icons_dir = wx.GetApp().GetIconsDir()
719
720 #------------
721
722 # Simplified init method.
723 self.SetProperties()
724 self.CreateCtrls()
725 self.BindEvents()
726 self.DoLayout()
727
728 #------------
729
730 self.CenterOnScreen(wx.BOTH)
731
732 #---------------------------------------------------------------------------
733
734 def SetProperties(self):
735 """
736 ...
737 """
738
739 self.SetTitle("Main frame")
740 self.SetSize((400, 300))
741
742 #------------
743
744 frameIcon = wx.Icon(os.path.join(self.icons_dir,
745 "icon_wxWidgets.ico"),
746 type=wx.BITMAP_TYPE_ICO)
747 self.SetIcon(frameIcon)
748
749
750 def CreateCtrls(self):
751 """
752 ...
753 """
754
755 # Create a panel.
756 self.panel = wx.Panel(self, -1)
757
758 #------------
759
760 # Add a button.
761 self.btnClose = wx.Button(self.panel,
762 -1,
763 "&Close")
764
765
766 def BindEvents(self):
767 """
768 Bind some events to an events handler.
769 """
770
771 # Bind events to an events handler.
772 self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
773 self.Bind(wx.EVT_BUTTON, self.OnCloseMe, self.btnClose)
774
775
776 def DoLayout(self):
777 """
778 ...
779 """
780
781 # MainSizer is the top-level one that manages everything.
782 mainSizer = wx.BoxSizer(wx.VERTICAL)
783
784 # wx.BoxSizer(window, proportion, flag, border)
785 # wx.BoxSizer(sizer, proportion, flag, border)
786 mainSizer.Add(self.btnClose, 1, wx.EXPAND | wx.ALL, 10)
787
788 # Finally, tell the panel to use the sizer for layout.
789 self.panel.SetAutoLayout(True)
790 self.panel.SetSizer(mainSizer)
791
792 mainSizer.Fit(self.panel)
793
794
795 def OnCloseMe(self, event):
796 """
797 ...
798 """
799
800 self.Close(True)
801
802
803 def OnCloseWindow(self, event):
804 """
805 ...
806 """
807
808 self.Destroy()
809
810 #-------------------------------------------------------------------------------
811
812 class MyApp(wx.App):
813 """
814 ...
815 """
816 def OnInit(self):
817
818 #------------
819
820 self.locale = wx.Locale(wx.LANGUAGE_ENGLISH)
821
822 #------------
823
824 self.installDir = os.path.split(os.path.abspath(sys.argv[0]))[0]
825
826 #------------
827
828 # Return bitmaps folder.
829 self.bitmaps_dir = wx.GetApp().GetBitmapsDir()
830
831 # Load a background bitmap.
832 bmp = wx.Bitmap(os.path.join(self.bitmaps_dir,
833 "advancedsplash.png"),
834 type=wx.BITMAP_TYPE_PNG)
835 shadow = wx.WHITE
836
837 splash = AdvancedSplash(None,
838 bitmap=bmp,
839 timeout=5000,
840 agwStyle=AS_TIMEOUT |
841 AS_CENTER_ON_PARENT |
842 AS_SHADOW_BITMAP,
843 shadowcolour=shadow)
844 splash.SetText("Loading...")
845 splash.SetTextColour(wx.WHITE)
846 position = (40, 270)
847 splash.SetTextPosition(position)
848
849 #------------
850
851 return True
852
853 #---------------------------------------------------------------------------
854
855 def GetInstallDir(self):
856 """
857 Returns the installation directory for my application.
858 """
859
860 return self.installDir
861
862
863 def GetIconsDir(self):
864 """
865 Returns the icons directory for my application.
866 """
867
868 icons_dir = os.path.join(self.installDir, "icons")
869 return icons_dir
870
871
872 def GetBitmapsDir(self):
873 """
874 Returns the bitmaps directory for my application.
875 """
876
877 bitmaps_dir = os.path.join(self.installDir, "bitmaps")
878 return bitmaps_dir
879
880 #-------------------------------------------------------------------------------
881
882 def main():
883 app = MyApp(False)
884 app.MainLoop()
885
886 #-------------------------------------------------------------------------------
887
888 if __name__ == "__main__" :
889 main()
With alpha (only Windows)
Thank you so much to Kevin Schlosser and Metallicow for the "Alpha" source code.
ShapedWindow with Alpha that works on wxPy4.0 and 4.1.
I like it ! (Ecco ).
First example
1 # sample_seven_a.py
2
3 import os
4 import sys
5 import platform
6 import time
7 import wx
8 import wx.lib.fancytext as fancytext
9 try:
10 from wx.lib.mswalpha import draw_alpha
11 except ImportError:
12 from mswalpha import draw_alpha
13
14 # class MyFrame
15 # class MySplash
16 # class MyApp
17
18 #---------------------------------------------------------------------------
19
20 class MyFrame(wx.Frame):
21 """
22 ...
23 """
24 def __init__(self):
25 super(MyFrame, self).__init__(None,
26 -1,
27 title="")
28
29 #------------
30
31 # Return application name.
32 self.app_name = wx.GetApp().GetAppName()
33 # Return icons folder.
34 self.icons_dir = wx.GetApp().GetIconsDir()
35
36 #------------
37
38 # Simplified init method.
39 self.SetProperties()
40 self.CreateCtrls()
41 self.BindEvents()
42 self.DoLayout()
43
44 #------------
45
46 self.CenterOnScreen(wx.BOTH)
47
48 #------------
49
50 self.Show(True)
51
52 #-----------------------------------------------------------------------
53
54 def SetProperties(self):
55 """
56 ...
57 """
58
59 self.SetTitle(self.app_name)
60 self.SetSize((340, 200))
61
62 #------------
63
64 frameIcon = wx.Icon(os.path.join(self.icons_dir,
65 "icon_wxWidgets.ico"),
66 type=wx.BITMAP_TYPE_ICO)
67 self.SetIcon(frameIcon)
68
69
70 def CreateCtrls(self):
71 """
72 ...
73 """
74
75 # Create a panel.
76 self.panel = wx.Panel(self, -1)
77
78 #------------
79
80 # Add a buttons.
81 self.btnClose = wx.Button(self.panel,
82 -1,
83 "&Close")
84
85
86 def BindEvents(self):
87 """
88 Bind some events to an events handler.
89 """
90
91 # Bind events to an events handler.
92 self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
93 self.Bind(wx.EVT_BUTTON, self.OnCloseMe, self.btnClose)
94
95
96 def DoLayout(self):
97 """
98 ...
99 """
100
101 # MainSizer is the top-level one that manages everything.
102 mainSizer = wx.BoxSizer(wx.VERTICAL)
103
104 # wx.BoxSizer(window, proportion, flag, border)
105 # wx.BoxSizer(sizer, proportion, flag, border)
106 mainSizer.Add(self.btnClose, 1, wx.EXPAND | wx.ALL, 10)
107
108 # Finally, tell the panel to use the sizer for layout.
109 self.panel.SetAutoLayout(True)
110 self.panel.SetSizer(mainSizer)
111
112 mainSizer.Fit(self.panel)
113
114
115 def OnCloseMe(self, event):
116 """
117 ...
118 """
119
120 self.Close(True)
121
122
123 def OnCloseWindow(self, event):
124 """
125 ...
126 """
127
128 self.Destroy()
129 wx.Exit()
130
131 #-------------------------------------------------------------------------------
132
133 class MySplash(wx.Frame):
134 """
135 Thanks to Robin Dunn.
136 """
137 style = (wx.FRAME_SHAPED | wx.BORDER_NONE |
138 wx.FRAME_NO_TASKBAR | wx.STAY_ON_TOP)
139 def __init__(self, parent, id=wx.ID_ANY, title=wx.EmptyString,
140 pos=wx.DefaultPosition, size=wx.DefaultSize,
141 style=style,
142 name='frame'):
143 wx.Frame.__init__(self, parent, id, title, pos, size, style, name)
144
145 #------------
146
147 # Attributes.
148 self.delta = wx.Point(0,0)
149
150 #------------
151
152 # Return application name.
153 self.app_name = wx.GetApp().GetAppName()
154 # Return bitmaps folder.
155 self.bitmaps_dir = wx.GetApp().GetBitmapsDir()
156 # Return icons folder.
157 self.icons_dir = wx.GetApp().GetIconsDir()
158
159 #------------
160
161 # Starts the Timer. Once Expired, splash is Destroyed.
162 self.timer = wx.Timer(self)
163 self.timer.Start(4000)
164 self.Bind(wx.EVT_TIMER, self.TimeOut, self.timer)
165
166 #--------------
167
168 # Show main frame after 3000 ms.
169 self.fc = wx.CallLater(3000, self.ShowMainFrame)
170
171 #------------
172
173 # Simplified init method.
174 self.SetProperties()
175 self.CreateCtrls()
176 self.BindEvents()
177
178 #--------------
179
180 self.CenterOnScreen(wx.BOTH)
181
182 #------------
183
184 wx.BeginBusyCursor()
185
186 #---------------------------------------------------------------------------
187
188 def SetProperties(self):
189 """
190 ...
191 """
192
193 self.SetTitle(self.app_name)
194 self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
195
196 frameIcon = wx.Icon(os.path.join(self.icons_dir,
197 "icon_wxWidgets.ico"),
198 type=wx.BITMAP_TYPE_ICO)
199 self.SetIcon(frameIcon)
200
201
202 def CreateCtrls(self):
203 """
204 ...
205 """
206
207 # Load a background bitmap.
208 self.bitmap = wx.Bitmap(os.path.join(self.bitmaps_dir,
209 "wxPython.png"),
210 type=wx.BITMAP_TYPE_PNG)
211 # or
212 # image = wx.Image('phone.png', wx.BITMAP_TYPE_PNG)
213 # blurimage = image.Blur(1)
214 # self.bitmap = blurimage.ConvertToBitmap()
215
216 self.SetClientSize((self.bitmap.GetWidth(), self.bitmap.GetHeight()))
217
218 #------------
219
220 if wx.Platform == "__WXGTK__":
221 # wxGTK requires that the window be created before you can
222 # set its shape, so delay the call to SetWindowShape until
223 # this event.
224 self.Bind(wx.EVT_WINDOW_CREATE, self.SetWindowShape)
225 else:
226 # On wxMSW and wxMac the window has
227 # already been created, so go for it.
228 self.SetWindowShape()
229
230
231 def BindEvents(self):
232 """
233 Bind some events to an events handle.
234 """
235
236 self.Bind(wx.EVT_ERASE_BACKGROUND, lambda x: None)
237 # self.Bind(wx.EVT_MOTION, self.OnMouseMove)
238 self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
239 self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
240 self.Bind(wx.EVT_RIGHT_UP, self.OnClose)
241 self.Bind(wx.EVT_CHAR, self.OnCharEvents)
242 self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
243 self.Bind(wx.EVT_PAINT, self.OnPaint)
244
245
246 def SetWindowShape(self, *event):
247 """
248 ...
249 """
250
251 # Use the bitmap's mask to determine the region.
252 self.region = wx.Region(self.bitmap)
253 self.hasShape = self.SetShape(self.region)
254
255
256 def OnLeftDown(self, event):
257 """
258 ...
259 """
260
261 if self.HasCapture():
262 self.ReleaseMouse()
263
264 self.CaptureMouse()
265 x, y = self.ClientToScreen(event.GetPosition())
266 originx, originy = self.GetPosition()
267 dx = x - originx
268 dy = y - originy
269 self.delta = (dx, dy)
270
271
272 def OnLeftUp(self, event):
273 """
274 ...
275 """
276
277 if self.HasCapture():
278 self.ReleaseMouse()
279
280
281 def OnMouseMove(self, event):
282 """
283 ...
284 """
285
286 if event.Dragging() and event.LeftIsDown():
287 x, y = self.ClientToScreen(event.GetPosition())
288 fp = (x - self.delta[0], y - self.delta[1])
289 self.SetPosition(fp)
290
291
292 def Draw(self):
293 """
294 ...
295 """
296
297 # Return client size.
298 width, height = self.GetClientSize()
299
300 # Return main image size.
301 bw, bh = self.bitmap.GetWidth(), self.bitmap.GetHeight()
302
303 #------------
304
305 dc = wx.MemoryDC()
306
307 #------------
308
309 fontSize = self.GetFont().GetPointSize()
310
311 # wx.Font(pointSize, family, style, weight, underline, faceName)
312 if wx.Platform == "__WXMSW__":
313 self.normalBoldFont = wx.Font(fontSize-1,
314 wx.DEFAULT, wx.NORMAL,
315 wx.NORMAL, False, "")
316 self.normalFont = wx.Font(fontSize,
317 wx.DEFAULT, wx.NORMAL,
318 wx.NORMAL, False, "")
319
320 dc.SetFont(self.normalFont)
321 dc.SetFont(self.normalBoldFont)
322
323 #------------
324
325 bmp = wx.Bitmap.FromRGBA(width, height, red=0, green=0, blue=0, alpha=0)
326 dc.SelectObject(bmp)
327
328 #------------
329
330 gc = wx.GraphicsContext.Create(dc)
331 gcdc = wx.GCDC(gc)
332
333 # Draw a bitmap with an alpha channel
334 # on top of the last group.
335 # image, x, y, transparence
336 gcdc.DrawBitmap(self.bitmap, -1, -1, useMask=False)
337
338 # Draw text.
339 gcdc.SetTextForeground(wx.Colour(255, 255, 255, 100)) # white
340 gcdc.SetTextBackground(wx.TransparentColour)
341 gcdc.SetFont(self.normalBoldFont)
342 firstTxt = "wxPython is a Python extension module that\n"\
343 " encapsulates the wxWindows GUI classes."
344 tw, th = gcdc.GetTextExtent(firstTxt)
345 gcdc.DrawText(firstTxt, (int((bw-tw)/2), int(245)))
346
347 gcdc.SetTextForeground(wx.Colour(250, 250, 250, 255)) # white
348 gcdc.SetTextBackground(wx.TransparentColour)
349 gcdc.SetFont(self.normalFont)
350 secondTxt = " wxPython is brought to you by Robin Dunn and\n"\
351 "Total Control Software, Copyright (c) 1997-2020."
352 tw, th = gcdc.GetTextExtent(secondTxt)
353 gcdc.DrawText(secondTxt, (int((bw-tw)/2), int(280)))
354
355 #------------
356
357 gcdc.Destroy()
358 del gcdc
359
360 dc.Destroy()
361 del dc
362
363 #------------
364
365 draw_alpha(self, bmp)
366
367
368 def OnTimer(self, event):
369 """
370 ...
371 """
372
373 dc = wx.BufferedDC(wx.ClientDC(self))
374 dc.Clear()
375
376 self.Draw()
377
378
379 def OnPaint(self, event):
380 """
381 ...
382 """
383
384 dc = wx.BufferedPaintDC(self)
385 dc.Clear()
386
387 self.Draw()
388
389
390 def OnCharEvents(self, event):
391 """
392 Handles the wx.EVT_CHAR for Splash.
393 This reproduces the behavior of wx.SplashScreen.
394 """
395
396 self.OnClose(event)
397
398
399 def TimeOut(self, event):
400 """
401 ...
402 """
403
404 self.Close(True)
405
406
407 def OnClose(self, event):
408 """
409 Handles the wx.EVT_CLOSE event for SplashScreen.
410 """
411
412 # Make sure the default handler runs
413 # too so this window gets destroyed.
414 # Tell the event system to continue
415 # looking for an event handler, so the
416 # default handler will get called.
417 event.Skip()
418 self.Hide()
419
420 #------------
421
422 # If the timer is still running then go
423 # ahead and show the main frame now.
424 if self.fc.IsRunning():
425 # Stop the wx.CallLater timer.
426 # Stop the splash screen timer
427 # and close it.
428 self.fc.Stop()
429 self.ShowMainFrame()
430
431
432 def ShowMainFrame(self):
433 """
434 ...
435 """
436
437 print("\n... Close the splash screen")
438 print("\n... Create and display the main frame")
439
440 #------------
441
442 wx.CallAfter(wx.EndBusyCursor)
443
444 #------------
445
446 if self.fc.IsRunning():
447 # Stop the splash screen
448 # timer and close it.
449 self.Raise()
450
451 #------------
452
453 # Create an instance of the MyFrame class.
454 frame = MyFrame()
455
456
457 def OnCloseWindow(self, event):
458 """
459 ...
460 """
461
462 self.timer.Stop()
463 self.Destroy()
464
465 #---------------------------------------------------------------------------
466
467 class MyApp(wx.App):
468 """
469 ...
470 """
471 def OnInit(self):
472
473 #------------
474
475 self.locale = wx.Locale(wx.LANGUAGE_ENGLISH)
476
477 #------------
478
479 self.SetAppName("Main frame")
480
481 #------------
482
483 self.installDir = os.path.split(os.path.abspath(sys.argv[0]))[0]
484
485 #------------
486
487 frame = MySplash(None)
488 self.SetTopWindow(frame)
489 frame.Show(True)
490
491 return True
492
493 #-----------------------------------------------------------------------
494
495 def GetInstallDir(self):
496 """
497 Returns the installation directory for my application.
498 """
499
500 return self.installDir
501
502
503 def GetIconsDir(self):
504 """
505 Returns the icons directory for my application.
506 """
507
508 icons_dir = os.path.join(self.installDir, "icons")
509 return icons_dir
510
511
512 def GetBitmapsDir(self):
513 """
514 Returns the bitmaps directory for my application.
515 """
516
517 bitmaps_dir = os.path.join(self.installDir, "bitmaps")
518 return bitmaps_dir
519
520 #---------------------------------------------------------------------------
521
522 def main():
523 app = MyApp(False)
524 app.MainLoop()
525
526 #---------------------------------------------------------------------------
527
528 if __name__ == "__main__" :
529 main()
Second example
1 # sample_seven_b.py
2
3 import os
4 import sys
5 import platform
6 import time
7 import wx
8 import wx.lib.fancytext as fancytext
9 try:
10 from wx.lib.mswalpha import draw_alpha
11 except ImportError:
12 from mswalpha import draw_alpha
13
14 # class MyFrame
15 # class MySplash
16 # class MyControls
17 # class MyApp
18
19 #---------------------------------------------------------------------------
20
21 class MyFrame(wx.Frame):
22 """
23 ...
24 """
25 def __init__(self):
26 super(MyFrame, self).__init__(None,
27 -1,
28 title="")
29
30 #------------
31
32 # Return application name.
33 self.app_name = wx.GetApp().GetAppName()
34 # Return icons folder.
35 self.icons_dir = wx.GetApp().GetIconsDir()
36
37 #------------
38
39 # Simplified init method.
40 self.SetProperties()
41 self.CreateCtrls()
42 self.BindEvents()
43 self.DoLayout()
44
45 #------------
46
47 self.CenterOnScreen(wx.BOTH)
48
49 #------------
50
51 self.Show(True)
52
53 #-----------------------------------------------------------------------
54
55 def SetProperties(self):
56 """
57 ...
58 """
59
60 self.SetTitle(self.app_name)
61 self.SetSize((340, 200))
62
63 #------------
64
65 frameIcon = wx.Icon(os.path.join(self.icons_dir,
66 "icon_wxWidgets.ico"),
67 type=wx.BITMAP_TYPE_ICO)
68 self.SetIcon(frameIcon)
69
70
71 def CreateCtrls(self):
72 """
73 ...
74 """
75
76 # Create a panel.
77 self.panel = wx.Panel(self, -1)
78
79 #------------
80
81 # Add a buttons.
82 self.btnClose = wx.Button(self.panel,
83 -1,
84 "&Close")
85
86
87 def BindEvents(self):
88 """
89 Bind some events to an events handler.
90 """
91
92 # Bind events to an events handler.
93 self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
94 self.Bind(wx.EVT_BUTTON, self.OnCloseMe, self.btnClose)
95
96
97 def DoLayout(self):
98 """
99 ...
100 """
101
102 # MainSizer is the top-level one that manages everything.
103 mainSizer = wx.BoxSizer(wx.VERTICAL)
104
105 # wx.BoxSizer(window, proportion, flag, border)
106 # wx.BoxSizer(sizer, proportion, flag, border)
107 mainSizer.Add(self.btnClose, 1, wx.EXPAND | wx.ALL, 10)
108
109 # Finally, tell the panel to use the sizer for layout.
110 self.panel.SetAutoLayout(True)
111 self.panel.SetSizer(mainSizer)
112
113 mainSizer.Fit(self.panel)
114
115
116 def OnCloseMe(self, event):
117 """
118 ...
119 """
120
121 self.Close(True)
122
123
124 def OnCloseWindow(self, event):
125 """
126 ...
127 """
128
129 self.Destroy()
130 wx.Exit()
131
132 #-------------------------------------------------------------------------------
133
134 class MySplash(wx.Frame):
135 """
136 ...
137 """
138 style = (wx.FRAME_SHAPED | wx.NO_BORDER |
139 wx.FRAME_NO_TASKBAR | wx.STAY_ON_TOP)
140 def __init__(self, parent, id=wx.ID_ANY, title=wx.EmptyString,
141 pos=wx.DefaultPosition, size=wx.DefaultSize,
142 style=style,
143 name='frame'):
144 wx.Frame.__init__(self, parent, id, title, pos, size, style, name)
145
146 #------------
147
148 # Attributes.
149 self.delta = wx.Point(0,0)
150
151 #------------
152
153 # Return application name.
154 self.app_name = wx.GetApp().GetAppName()
155 # Return bitmaps folder.
156 self.bitmaps_dir = wx.GetApp().GetBitmapsDir()
157 # Return icons folder.
158 self.icons_dir = wx.GetApp().GetIconsDir()
159
160 #------------
161
162 # Starts the Timer. Once Expired, splash is Destroyed.
163 self.timer = wx.Timer(self)
164 self.timer.Start(4000)
165 self.Bind(wx.EVT_TIMER, self.TimeOut, self.timer)
166
167 #--------------
168
169 # Show main frame after 3000 ms.
170 self.fc = wx.CallLater(3000, self.ShowMainFrame)
171
172 #------------
173
174 # Simplified init method.
175 self.SetProperties()
176 self.CreateCtrls()
177 self.BindEvents()
178
179 #--------------
180
181 self.CenterOnScreen(wx.BOTH)
182
183 #------------
184
185 wx.BeginBusyCursor()
186
187 #---------------------------------------------------------------------------
188
189 def SetProperties(self):
190 """
191 ...
192 """
193
194 self.SetTitle(self.app_name)
195 self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
196
197 frameIcon = wx.Icon(os.path.join(self.icons_dir,
198 "icon_wxWidgets.ico"),
199 type=wx.BITMAP_TYPE_ICO)
200 self.SetIcon(frameIcon)
201
202
203 def CreateCtrls(self):
204 """
205 ...
206 """
207
208 # Load a background bitmap.
209 self.bitmap = wx.Bitmap(os.path.join(self.bitmaps_dir,
210 "wxWidgets.png"),
211 type=wx.BITMAP_TYPE_PNG)
212 # or
213 # image = wx.Image('phone.png', wx.BITMAP_TYPE_PNG)
214 # blurimage = image.Blur(1)
215 # self.bitmap = blurimage.ConvertToBitmap()
216
217 self.SetClientSize((self.bitmap.GetWidth(), self.bitmap.GetHeight()))
218
219 #------------
220
221 if wx.Platform == "__WXGTK__":
222 # wxGTK requires that the window be created before you can
223 # set its shape, so delay the call to SetWindowShape until
224 # this event.
225 self.Bind(wx.EVT_WINDOW_CREATE, self.SetWindowShape)
226 else:
227 # On wxMSW and wxMac the window has
228 # already been created, so go for it.
229 self.SetWindowShape()
230
231 #------------
232
233 # It appears that we cannot make child widgets on the Frame
234 # when using mswalpha, there fore we will make a "child" shaped
235 # frame that will handle widgets transparency also.
236 # self.button = wx.Button(self, -1, 'Button', pos=(100, 100))
237
238 #------------
239
240 self.Centre()
241 self.widgetsframe = MyControls(self,
242 pos=self.GetPosition(),
243 size=self.GetSize())
244 self.widgetsframe.Show()
245
246
247 def BindEvents(self):
248 """
249 Bind some events to an events handle.
250 """
251
252 self.Bind(wx.EVT_ERASE_BACKGROUND, lambda x: None)
253 # self.Bind(wx.EVT_MOTION, self.OnMouseMove)
254 self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
255 self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
256 self.Bind(wx.EVT_RIGHT_UP, self.OnClose)
257 self.Bind(wx.EVT_CHAR, self.OnCharEvents)
258 self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
259 self.Bind(wx.EVT_PAINT, self.OnPaint)
260
261
262 def SetWindowShape(self, *event):
263 """
264 ...
265 """
266
267 # Use the bitmap's mask to determine the region.
268 self.region = wx.Region(self.bitmap)
269 self.hasShape = self.SetShape(self.region)
270
271
272 def OnLeftDown(self, event):
273 """
274 ...
275 """
276
277 if self.HasCapture():
278 self.ReleaseMouse()
279
280 self.CaptureMouse()
281 x, y = self.ClientToScreen(event.GetPosition())
282 originx, originy = self.GetPosition()
283 dx = x - originx
284 dy = y - originy
285 self.delta = (dx, dy)
286
287
288 def OnLeftUp(self, event):
289 """
290 ...
291 """
292
293 if self.HasCapture():
294 self.ReleaseMouse()
295
296
297 def OnMouseMove(self, event):
298 """
299 ...
300 """
301
302 if event.Dragging() and event.LeftIsDown():
303 x, y = self.ClientToScreen(event.GetPosition())
304 fp = (x - self.delta[0], y - self.delta[1])
305 self.SetPosition(fp)
306 self.widgetsframe.SetPosition(fp)
307
308
309 def Draw(self):
310 """
311 ...
312 """
313
314 # Return client size.
315 width, height = self.GetClientSize()
316
317 # Return main image size.
318 bw, bh = self.bitmap.GetWidth(), self.bitmap.GetHeight()
319
320 #------------
321
322 dc = wx.MemoryDC()
323
324 #------------
325
326 fontSize = self.GetFont().GetPointSize()
327
328 # wx.Font(pointSize, family, style, weight, underline, faceName)
329 if wx.Platform == "__WXMSW__":
330 self.normalBoldFont = wx.Font(fontSize-1,
331 wx.DEFAULT, wx.NORMAL,
332 wx.NORMAL, False, "")
333 self.normalFont = wx.Font(fontSize,
334 wx.DEFAULT, wx.NORMAL,
335 wx.NORMAL, False, "")
336
337 dc.SetFont(self.normalFont)
338 dc.SetFont(self.normalBoldFont)
339
340 #------------
341
342 bmp = wx.Bitmap.FromRGBA(width, height, red=0, green=0, blue=0, alpha=0)
343 dc.SelectObject(bmp)
344
345 #------------
346
347 gc = wx.GraphicsContext.Create(dc)
348 gcdc = wx.GCDC(gc)
349
350 # Draw a bitmap with an alpha channel
351 # on top of the last group.
352 # image, x, y, transparence
353 gcdc.DrawBitmap(self.bitmap, -1, -1, useMask=False)
354
355 # Draw text.
356 gcdc.SetTextForeground(wx.Colour(0, 0, 0, 100)) # black
357 gcdc.SetTextBackground(wx.TransparentColour)
358 gcdc.SetFont(self.normalBoldFont)
359 firstTxt = "wxPython is a Python extension module that\n"\
360 " encapsulates the wxWindows GUI classes."
361 tw, th = gcdc.GetTextExtent(firstTxt)
362 gcdc.DrawText(firstTxt, (int((bw-tw)/2-25), int(240)))
363
364 gcdc.SetTextForeground(wx.Colour(250, 250, 250, 255)) # white
365 gcdc.SetTextBackground(wx.TransparentColour)
366 gcdc.SetFont(self.normalFont)
367 secondTxt = " wxPython is brought to you by Robin Dunn and\n"\
368 "Total Control Software, Copyright (c) 1997-2020."
369 tw, th = gcdc.GetTextExtent(secondTxt)
370 gcdc.DrawText(secondTxt, (int((bw-tw)/2-25), int(275)))
371
372 #------------
373
374 gcdc.Destroy()
375 del gcdc
376
377 dc.Destroy()
378 del dc
379
380 #------------
381
382 draw_alpha(self, bmp)
383
384
385 def OnTimer(self, event):
386 """
387 ...
388 """
389
390 dc = wx.BufferedDC(wx.ClientDC(self))
391 dc.Clear()
392
393 self.Draw()
394
395
396 def OnPaint(self, event):
397 """
398 ...
399 """
400
401 dc = wx.BufferedPaintDC(self)
402 dc.Clear()
403
404 self.Draw()
405
406
407 def OnCharEvents(self, event):
408 """
409 Handles the wx.EVT_CHAR for Splash.
410 This reproduces the behavior of wx.SplashScreen.
411 """
412
413 self.OnClose(event)
414
415
416 def TimeOut(self, event):
417 """
418 ...
419 """
420
421 self.Close(True)
422
423
424 def OnClose(self, event):
425 """
426 Handles the wx.EVT_CLOSE event for SplashScreen.
427 """
428
429 self.widgetsframe.Close()
430
431 #------------
432
433 # Make sure the default handler runs
434 # too so this window gets destroyed.
435 # Tell the event system to continue
436 # looking for an event handler, so the
437 # default handler will get called.
438 event.Skip()
439 self.Hide()
440
441 #------------
442
443 # If the timer is still running then go
444 # ahead and show the main frame now.
445 if self.fc.IsRunning():
446 # Stop the wx.CallLater timer.
447 # Stop the splash screen timer
448 # and close it.
449 self.fc.Stop()
450 self.ShowMainFrame()
451
452
453 def ShowMainFrame(self):
454 """
455 ...
456 """
457
458 print("\n... Close the splash screen")
459 print("\n... Create and display the main frame")
460
461 #------------
462
463 wx.CallAfter(wx.EndBusyCursor)
464
465 #------------
466
467 if self.fc.IsRunning():
468 # Stop the splash screen
469 # timer and close it.
470 self.Raise()
471
472 #------------
473
474 # Create an instance of the MyFrame class.
475 frame = MyFrame()
476
477
478 def OnCloseWindow(self, event):
479 """
480 ...
481 """
482
483 self.timer.Stop()
484 self.Destroy()
485
486 #-------------------------------------------------------------------------------
487
488 class MyControls(wx.Frame):
489 """
490 ...
491 """
492 style = (wx.FRAME_SHAPED | wx.NO_BORDER |
493 wx.FRAME_NO_TASKBAR | wx.FRAME_FLOAT_ON_PARENT)
494 def __init__(self, parent, id=wx.ID_ANY, title=wx.EmptyString,
495 pos=wx.DefaultPosition, size=wx.DefaultSize,
496 style=style,
497 name='frame'):
498 wx.Frame.__init__(self, parent, id, title, pos, size, style, name)
499
500 #------------
501
502 # Attributes.
503 self.SetTransparent(200)
504
505 #------------
506
507 # Return bitmaps folder.
508 self.bitmaps_dir = wx.GetApp().GetBitmapsDir()
509 # Return icons folder.
510 self.icons_dir = wx.GetApp().GetIconsDir()
511
512 #------------
513
514 # Simplified init method.
515 self.SetProperties()
516 self.CreateCtrls()
517 self.BindEvents()
518
519 #---------------------------------------------------------------------------
520
521 def SetProperties(self):
522 """
523 ...
524 """
525
526 self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
527
528
529 def CreateCtrls(self):
530 """
531 ...
532 """
533
534 # Gauge.
535 self.gauge = wx.Gauge(self,
536 id=-1,
537 #range=50,
538 pos=(25, 312),
539 size=(275, 15))
540 self.gauge.Pulse()
541
542 #------------
543
544 if wx.Platform == "__WXGTK__":
545 # wxGTK requires that the window be created before you can
546 # set its shape, so delay the call to SetWindowShape until
547 # this event.
548 self.Bind(wx.EVT_WINDOW_CREATE, self.SetWindowShape)
549 else:
550 # On wxMSW and wxMac the window has
551 # already been created, so go for it.
552 self.SetWindowShape()
553
554
555 def BindEvents(self):
556 """
557 Bind some events to an events handler.
558 """
559
560 self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
561 self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
562
563
564 def TimerHandler(self, event):
565 """
566 ...
567 """
568
569
570 #self.gauge.SetValue(self.count)
571 # or
572 self.gauge.Pulse()
573
574
575 def SetWindowShape(self, *event):
576 """
577 ...
578 """
579
580 # Use the widget's rect's to determine the region.
581 wxRegion = wx.Region
582 self.region = wxRegion()
583 widgets = [child for child in self.GetChildren()]
584 regions = [wxRegion(widget.GetRect()) for widget in widgets]
585 Union = self.region.Union
586 [Union(reg) for reg in regions]
587 self.hasShape = self.SetShape(self.region)
588
589
590 def OnLeftDown(self, event):
591 """
592 ...
593 """
594
595 if self.HasCapture():
596 self.ReleaseMouse()
597
598 self.CaptureMouse()
599 x, y = self.ClientToScreen(event.GetPosition())
600 originx, originy = self.GetPosition()
601 dx = x - originx
602 dy = y - originy
603 self.delta = (dx, dy)
604
605
606 def OnLeftUp(self, event):
607 """
608 ...
609 """
610
611 if self.HasCapture():
612 self.ReleaseMouse()
613
614 #-------------------------------------------------------------------------------
615
616 class MyApp(wx.App):
617 """
618 ...
619 """
620 def OnInit(self):
621
622 #------------
623
624 self.locale = wx.Locale(wx.LANGUAGE_ENGLISH)
625
626 #------------
627
628 self.SetAppName("Main frame")
629
630 #------------
631
632 self.installDir = os.path.split(os.path.abspath(sys.argv[0]))[0]
633
634 #------------
635
636 frame = MySplash(None)
637 self.SetTopWindow(frame)
638 frame.Show(True)
639
640 return True
641
642 #-----------------------------------------------------------------------
643
644 def GetInstallDir(self):
645 """
646 Returns the installation directory for my application.
647 """
648
649 return self.installDir
650
651
652 def GetIconsDir(self):
653 """
654 Returns the icons directory for my application.
655 """
656
657 icons_dir = os.path.join(self.installDir, "icons")
658 return icons_dir
659
660
661 def GetBitmapsDir(self):
662 """
663 Returns the bitmaps directory for my application.
664 """
665
666 bitmaps_dir = os.path.join(self.installDir, "bitmaps")
667 return bitmaps_dir
668
669 #---------------------------------------------------------------------------
670
671 def main():
672 app = MyApp(False)
673 app.MainLoop()
674
675 #---------------------------------------------------------------------------
676
677 if __name__ == "__main__" :
678 main()
Download source
Additional Information
Link :
https://www.blog.pythonlibrary.org/2018/09/
https://stackoverflow.com/questions/12181185/wxpython-and-splash-screen
https://stackoverflow.com/questions/9435498/wxpython-splash-screen-trouble
http://wxpython-users.1045709.n5.nabble.com/Splash-Screen-td2368727.html
https://github.com/ponty/pyscreenshot
https://stackoverflow.com/questions/28742324/wxpython-screenshot-windows
https://stackoverflow.com/questions/8644908/take-screenshot-in-python-cross-platform
- - - - -
https://wiki.wxpython.org/TitleIndex
Thanks to
Cody Precord, Chris Barker, Robin Dunn, Mike Driscoll, Andrea Gavana, Vegaseat (DaniWeb), Cliff Wells, Harald Massa, Jeff Grimmett, Kevin Schlosser and Metallicow , the wxPython community...
About this page
Date (d/m/y) Person (bot) Comments :
27/04/18 - Ecco (Created page for wxPython Phoenix).
Comments
- blah, blah, blah....