How to create a customized frame - Part 1 (Phoenix)
Keywords : Shaped frame, Customized frame, Customized button, Transparency, Roll, Unroll, Fade in, Fade out, Shape, Region, BufferedPaintDC, BufferedDC, ClientDC, GCDC, AutoBufferedPaintDCFactory, Config, AcceleratorTable.
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 !
Shaped frame with mask :
First example
1 # sample_one.py
2
3 import sys
4 import os
5 import platform
6 import time
7 import wx
8 import wx.adv
9 import wx.lib.fancytext as fancytext
10
11 # class MyAboutDlg
12 # class MyWindow
13 # class MyButtonBox
14 # class MyPanel
15 # class MyFrame
16 # class MyApp
17
18 #-------------------------------------------------------------------------------
19
20 class MyAboutDlg(wx.Frame):
21 """
22 Thanks to Robin Dunn.
23 """
24 def __init__(self, parent):
25 style = (wx.FRAME_SHAPED | wx.SIMPLE_BORDER |
26 wx.CLIP_CHILDREN | wx.STAY_ON_TOP |
27 wx.SYSTEM_MENU | wx.CLOSE_BOX |
28 wx.NO_FULL_REPAINT_ON_RESIZE)
29 wx.Frame.__init__(self,
30 parent,
31 id=-1,
32 title="About...",
33 style=style)
34
35 #------------
36
37 # Attributes.
38 self.SetTransparent(0)
39 self.opacity_in = 0
40 self.opacity_out = 255
41 self.deltaN = -70
42 self.hasShape = False
43 self.delta = wx.Point(0,0)
44
45 #------------
46
47 # Return application name.
48 self.app_name = wx.GetApp().GetAppName()
49 # Return bitmaps folder.
50 self.bitmaps_dir = wx.GetApp().GetBitmapsDir()
51 # Return icons folder.
52 self.icons_dir = wx.GetApp().GetIconsDir()
53
54 #------------
55
56 # Simplified init method.
57 self.SetProperties()
58 self.OnTimerIn(self)
59 self.CreateCtrls()
60 self.BindEvents()
61
62 #------------
63
64 self.CenterOnParent(wx.BOTH)
65 self.GetParent().Enable(False)
66
67 #------------
68
69 self.Show(True)
70
71 #------------
72
73 self.eventLoop = wx.GUIEventLoop()
74 self.eventLoop.Run()
75
76 #---------------------------------------------------------------------------
77
78 def SetProperties(self):
79 """
80 Set the dialog properties (title, icon, transparency...).
81 """
82
83 frameIcon = wx.Icon(os.path.join(self.icons_dir,
84 "icon_wxWidgets.ico"),
85 type=wx.BITMAP_TYPE_ICO)
86 self.SetIcon(frameIcon)
87
88
89 def OnTimerIn(self, evt):
90 """
91 Thanks to Pascal Faut.
92 """
93
94 self.timer1 = wx.Timer(self, -1)
95 self.timer1.Start(1)
96 self.Bind(wx.EVT_TIMER, self.AlphaCycle1, self.timer1)
97
98 print("Fade-in was launched.")
99
100
101 def OnTimerOut(self, evt):
102 """
103 Thanks to Pascal Faut.
104 """
105
106 self.timer2 = wx.Timer(self, -1)
107 self.timer2.Start(1)
108 self.Bind(wx.EVT_TIMER, self.AlphaCycle2, self.timer2)
109
110 print("Fade-out was launched.")
111
112
113 def AlphaCycle1(self, *args):
114 """
115 Thanks to Pascal Faut.
116 """
117
118 self.opacity_in += self.deltaN
119 if self.opacity_in <= 0:
120 self.deltaN = -self.deltaN
121 self.opacity_in = 0
122
123 if self.opacity_in >= 255:
124 self.deltaN = -self.deltaN
125 self.opacity_in = 255
126
127 self.timer1.Stop()
128
129 self.SetTransparent(self.opacity_in)
130
131 print("Fade in = {}/255".format(self.opacity_in))
132
133
134 def AlphaCycle2(self, *args):
135 """
136 Thanks to Pascal Faut.
137 """
138
139 self.opacity_out += self.deltaN
140 if self.opacity_out >= 255:
141 self.deltaN = -self.deltaN
142 self.opacity_out = 255
143
144 if self.opacity_out <= 0:
145 self.deltaN = -self.deltaN
146 self.opacity_out = 0
147
148 self.timer2.Stop()
149
150 wx.CallAfter(self.Destroy)
151
152 self.SetTransparent(self.opacity_out)
153
154 print("Fade out = {}/255".format(self.opacity_out))
155
156
157 def CreateCtrls(self):
158 """
159 Make widgets for my dialog.
160 """
161
162 # Load a background bitmap.
163 self.bmp = wx.Bitmap(os.path.join(self.bitmaps_dir,
164 "skin_about_1.png"),
165 type=wx.BITMAP_TYPE_PNG)
166 mask = wx.Mask(self.bmp, wx.RED)
167 self.bmp.SetMask(mask)
168
169 #------------
170
171 self.SetClientSize((self.bmp.GetWidth(), self.bmp.GetHeight()))
172
173 #------------
174
175 if wx.Platform == "__WXGTK__":
176 # wxGTK requires that the window be created before you can
177 # set its shape, so delay the call to SetWindowShape until
178 # this event.
179 self.Bind(wx.EVT_WINDOW_CREATE, self.SetWindowShape)
180 else:
181 # On wxMSW and wxMac the window has already
182 # been created, so go for it.
183 self.SetWindowShape()
184
185
186 def BindEvents(self):
187 """
188 Bind all the events related to my dialog.
189 """
190
191 # Bind some events to an events handler.
192 self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
193 self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
194 self.Bind(wx.EVT_RIGHT_UP, self.OnCloseWindow) # Panel right clic.
195 self.Bind(wx.EVT_LEFT_DCLICK, self.OnDoubleClick) # View mask.
196 self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)
197 self.Bind(wx.EVT_WINDOW_CREATE, self.SetWindowShape)
198 self.Bind(wx.EVT_MOTION, self.OnMouseMove)
199 self.Bind(wx.EVT_KEY_UP, self.OnKeyUp)
200 self.Bind(wx.EVT_PAINT, self.OnPaint)
201 self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
202
203
204 def SetWindowShape(self, event=None):
205 """
206 ...
207 """
208
209 # Use the bitmap's mask to determine the region.
210 r = wx.Region(self.bmp)
211 self.hasShape = self.SetShape(r)
212
213
214 def OnEraseBackground(self, event):
215 """
216 ...
217 """
218
219 dc = event.GetDC()
220 if not dc:
221 dc = wx.ClientDC(self)
222 rect = self.GetUpdateRegion().GetBox()
223 dc.SetClippingRect(rect)
224
225
226 def OnDoubleClick(self, event):
227 """
228 ...
229 """
230
231 if self.hasShape:
232 self.SetShape(wx.Region())
233 self.hasShape = False
234 else:
235 self.SetWindowShape()
236
237
238 def OnLeftDown(self, event):
239 """
240 ...
241 """
242
243 self.CaptureMouse()
244 x, y = self.ClientToScreen(event.GetPosition())
245 originx, originy = self.GetPosition()
246 dx = x - originx
247 dy = y - originy
248 self.delta = ((dx, dy))
249
250
251 def OnLeftUp(self, evt):
252 """
253 ...
254 """
255
256 if self.HasCapture():
257 self.ReleaseMouse()
258
259
260 def OnMouseMove(self, event):
261 """
262 ...
263 """
264
265 if event.Dragging() and event.LeftIsDown():
266 x, y = self.ClientToScreen(event.GetPosition())
267 fp = (x - self.delta[0], y - self.delta[1])
268 self.Move(fp)
269
270
271 def OnPaint(self, event):
272 """
273 ...
274 """
275
276 dc = wx.AutoBufferedPaintDCFactory(self)
277 dc.DrawBitmap(self.bmp, -1, -1, True)
278
279 #------------
280
281 # These are strings.
282 py_version = sys.version.split()[0]
283
284 str1 = (('<font style="normal" family="default" color="yellow" size="10" weight="bold">'
285 'Programming : </font>'
286 '<font style="normal" family="default" color="white" size="10" weight="normal">'
287 'Python {}</font>').format(py_version)) # Python 3.6.5
288
289 str2 = (('<font style="normal" family="default" color="red" size="10" weight="bold">'
290 'GUI toolkit : </font>'
291 '<font style="normal" family="default" color="white" size="10" weight="normal">'
292 'wxPython {}</font>').format(wx.VERSION_STRING)) # wxPython 4.0.2
293
294 str3 = (('<font style="normal" family="default" color="brown" size="10" weight="bold">'
295 'Library : </font>'
296 '<font style="normal" family="default" color="white" size="10" weight="normal">'
297 '{}</font>').format(wx.GetLibraryVersionInfo().VersionString)) # wxWidgets 3.0.5
298
299 str4 = (('<font style="normal" family="default" color="cyan" size="10" weight="bold">'
300 'Operating system : </font>'
301 '<font style="normal" family="default" color="white" size="10" weight="normal">'
302 '{}</font>').format(platform.system())) # Windows
303
304 str5 = (('<font style="normal" family="default" color="gray" size="9" weight="normal">'
305 '{}</font>').format(self.app_name)) # Custom Gui 1
306
307 str6 = (('<font style="normal" family="default" color="White" size="8" weight="normal">'
308 'Right clic or Esc for Exit</font>'))
309
310 #------------
311
312 # Return main image size.
313 bw, bh = self.bmp.GetWidth(), self.bmp.GetHeight()
314
315 # Draw text.
316 # Need width to calculate x position of str1.
317 tw, th = fancytext.GetExtent(str1, dc)
318 # Centered text.
319 fancytext.RenderToDC(str1, dc, (bw-tw)/2, 50)
320
321 #------------
322
323 # Need width to calculate x position of str2.
324 tw, th = fancytext.GetExtent(str2, dc)
325 # Centered text.
326 fancytext.RenderToDC(str2, dc, (bw-tw)/2, 70)
327
328 #------------
329
330 # Need width to calculate x position of str3.
331 tw, th = fancytext.GetExtent(str3, dc)
332 # Centered text.
333 fancytext.RenderToDC(str3, dc, (bw-tw)/2, 90)
334
335 #------------
336
337 # Need width to calculate x position of str4.
338 tw, th = fancytext.GetExtent(str4, dc)
339 # Centered text.
340 fancytext.RenderToDC(str4, dc, (bw-tw)/2, 110)
341
342 #------------
343
344 # Need width to calculate x position of str5.
345 tw, th = fancytext.GetExtent(str5, dc)
346 # Centered text.
347 fancytext.RenderToDC(str5, dc, (bw-tw)/2, 150)
348
349 #------------
350
351 # Need width to calculate x position of str6.
352 tw, th = fancytext.GetExtent(str6, dc)
353 # Centered text.
354 fancytext.RenderToDC(str6, dc, (bw-tw)/2, 185)
355
356
357 def OnKeyUp(self, event):
358 """
359 ...
360 """
361
362 if event.GetKeyCode() == wx.WXK_ESCAPE:
363 self.OnCloseWindow(event)
364
365 event.Skip()
366
367
368 def OnCloseWindow(self, event):
369 """
370 ...
371 """
372
373 self.GetParent().Enable(True)
374 self.eventLoop.Exit()
375 #self.Destroy()
376 self.OnTimerOut(self)
377
378 #-------------------------------------------------------------------------------
379
380 class MyWindow(wx.Control):
381 """
382 Thanks to Cody Precord.
383 """
384 def __init__(self, parent, label,
385 foreground, background,
386 normal, pressed=None, disabled=None):
387 super(MyWindow, self).__init__(parent, -1,
388 style=wx.BORDER_NONE)
389
390 #------------
391
392 # Attributes.
393 self.label = label
394 self.foreground = foreground
395 self.background = background
396
397 if wx.Platform == "__WXGTK__":
398 self.color = "#9e9d9d"
399
400 else:
401 self.color = "#b1b1b0"
402
403 self.normal = normal
404 self.pressed = pressed
405 self.disabled = disabled
406
407 self._clicked = False
408
409 #------------
410
411 self.region = wx.Region(normal, wx.Colour(0, 0, 0, 0))
412
413 #------------
414
415 # Simplified init method.
416 self.SetProperties(label, foreground, background)
417 self.BindEvents()
418
419 #---------------------------------------------------------------------------
420
421 def SetProperties(self, label, foreground, background):
422 """
423 ...
424 """
425
426 self.label = label
427 self.foreground = foreground
428 self.background = background
429 self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
430
431
432 def BindEvents(self):
433 """
434 Bind some events to an events handler.
435 """
436
437 self.Bind(wx.EVT_SET_FOCUS, self.OnSetFocus)
438 self.Bind(wx.EVT_KILL_FOCUS, self.OnKillFocus)
439 self.Bind(wx.EVT_PAINT, self.OnPaint)
440 self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
441 self.Bind(wx.EVT_LEFT_DCLICK, self.OnLeftDclick)
442 self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
443 self.Bind(wx.EVT_MOTION, self.OnMotion)
444 self.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeave)
445 self.Bind(wx.EVT_KEY_UP, self.OnKeyUp)
446
447
448 def SetLabel(self, label):
449 """
450 ...
451 """
452
453 self.label = label
454 self.Refresh()
455
456
457 def DoGetBestSize(self):
458 """
459 ...
460 """
461
462 return self.normal.GetSize()
463
464
465 def GetLabel(self):
466 """
467 ...
468 """
469
470 return self.label
471
472
473 def GetLabelColor(self):
474 """
475 ...
476 """
477
478 return self.foreground
479
480
481 def Enable(self, *args, **kwargs):
482 """
483 ...
484 """
485
486 super(MyWindow, self).Enable(*args, **kwargs)
487 self.Refresh()
488
489
490 def Disable(self, *args, **kwargs):
491 """
492 ...
493 """
494
495 super(MyWindow, self).Disable(*args, **kwargs)
496 self.Refresh()
497
498
499 def PostEvent(self):
500 """
501 ...
502 """
503
504 event = wx.CommandEvent()
505 event.SetEventObject(self)
506 event.SetEventType(wx.EVT_BUTTON.typeId)
507 wx.PostEvent(self, event)
508
509
510 def OnSize(self, event):
511 """
512 ...
513 """
514
515 event.Skip()
516 self.Refresh()
517
518
519 def Getbackground(self):
520 """
521 ...
522 """
523
524 return self.background
525
526
527 def OnPaint(self, event):
528 """
529 ...
530 """
531
532 dc = wx.BufferedPaintDC(self)
533 dc.Clear()
534 gcdc = wx.GCDC(dc)
535
536 # Set the background color.
537 if wx.Platform == "__WXGTK__":
538 gcdc.SetBackground(wx.Brush("grey55"))
539 else:
540 gcdc.SetBackground(wx.Brush(self.background))
541
542 gcdc.Clear()
543
544 # Get the working rectangle we can draw in.
545 rect = self.GetClientRect()
546
547 # Font size and style.
548 fontSize = self.GetFont().GetPointSize()
549
550 if wx.Platform == "__WXGTK__":
551 boldFont = wx.Font(fontSize-1, wx.DEFAULT,
552 wx.NORMAL, wx.NORMAL, False, "")
553 else:
554 boldFont = wx.Font(fontSize+2, wx.DEFAULT,
555 wx.NORMAL, wx.BOLD, False, "")
556
557 if wx.Platform == "__WXMSW__":
558 pen = wx.Pen(self.color, 1, wx.SOLID)
559
560 else:
561 pen = wx.Pen(self.color, 1, wx.SOLID)
562
563 gcdc.SetPen(pen)
564
565 x, y = self.GetSize()
566 # x, y , width, height, radius
567 gcdc.DrawRoundedRectangle (0, 0, 71, 25, 3)
568
569 bitmap = self.normal
570
571 w, h = bitmap.GetWidth(), bitmap.GetHeight()
572
573 if self.clicked:
574 bitmap = self.pressed or bitmap
575 if not self.IsEnabled():
576 bitmap = self.normal or bitmap
577
578 # Draw a bitmap with an alpha channel.
579 # image, x, y, transparency.
580 dc.DrawBitmap(bitmap, 0, 0, True)
581
582 if wx.Platform == "__WXGTK__":
583 # Add the Caption.
584 # White text - Shadow.
585 rect = wx.Rect(rect.x, rect.y+3,
586 rect.width, 22)
587
588 else:
589 rect = wx.Rect(rect.x, rect.y+3,
590 rect.width, 20)
591
592 dc.SetFont(boldFont)
593 dc.SetTextForeground(wx.WHITE)
594 dc.DrawLabel(self.label, rect, wx.ALIGN_CENTER)
595
596 if wx.Platform == "__WXGTK__":
597 # Add the Caption.
598 # Black text.
599 rect = wx.Rect(rect.x, rect.y,
600 rect.width, 21)
601
602 else:
603 rect = wx.Rect(rect.x, rect.y,
604 rect.width, 19)
605
606 gcdc.SetFont(boldFont)
607 # Get the text color.
608 dc.SetTextForeground(self.foreground)
609 dc.DrawLabel(self.label, rect, wx.ALIGN_CENTER)
610
611
612 def SetClicked(self, clicked):
613 """
614 ...
615 """
616
617 if clicked != self._clicked:
618 self._clicked = clicked
619 self.Refresh()
620
621
622 def GetClicked(self):
623 """
624 ...
625 """
626
627 return self._clicked
628
629
630 clicked = property(GetClicked, SetClicked)
631 def OnLeftDown(self, event):
632 """
633 ...
634 """
635
636 x, y = event.GetPosition()
637 if self.region.Contains(x, y):
638 self.clicked = True
639 self.SetFocus()
640
641
642 def OnLeftDclick(self, event):
643 """
644 ...
645 """
646
647 self.OnLeftDown(event)
648
649
650 def OnLeftUp(self, event):
651 """
652 ...
653 """
654
655 if self.clicked:
656 x, y = event.GetPosition()
657 if self.region.Contains(x, y):
658 self.PostEvent()
659 self.clicked = False
660
661
662 def OnMotion(self, event):
663 """
664 ...
665 """
666
667 if self.clicked:
668 x, y = event.GetPosition()
669 if not self.region.Contains(x, y):
670 self.clicked = False
671
672
673 def OnLeave(self, event):
674 """
675 ...
676 """
677
678 self.clicked = False
679
680
681 def OnSetFocus(self, event):
682 """
683 ...
684 """
685
686 self.color = "white"
687 self.Refresh()
688
689
690 def OnKillFocus(self, event):
691 """
692 ...
693 """
694
695 if wx.Platform == "__WXGTK__":
696 self.color = "#9e9d9d"
697
698 else:
699 self.color = "#b1b1b0"
700
701 self.Refresh()
702
703
704 def OnKeyUp(self, event):
705 """
706 ...
707 """
708
709 if event.GetKeyCode() == wx.WXK_SPACE:
710 self.PostEvent()
711 return
712
713 elif event.GetKeyCode() == wx.WXK_ESCAPE:
714 self.GetTopLevelParent().OnCloseWindow(True)
715
716 event.Skip()
717
718 #-------------------------------------------------------------------------------
719
720 class MyButtonBox(wx.Panel):
721 """
722 Thanks to Cody Precord.
723 """
724 def __init__(self, parent, caption):
725 super(MyButtonBox, self).__init__(parent,
726 style=wx.NO_BORDER |
727 wx.TAB_TRAVERSAL)
728
729 #------------
730
731 # Attributes.
732 self._caption = caption
733
734 #------------
735
736 # Simplified init method.
737 self.DoLayout()
738
739 #---------------------------------------------------------------------------
740
741 def DoLayout(self):
742 """
743 ...
744 """
745
746 self._csizer = wx.BoxSizer(wx.VERTICAL)
747 msizer = wx.BoxSizer(wx.HORIZONTAL)
748 msizer.Add(self._csizer, 0 )
749 self.SetSizer(msizer)
750
751
752 def DoGetBestSize(self):
753 """
754 ...
755 """
756
757 size = super(MyButtonBox, self).DoGetBestSize()
758
759 # Compensate for wide caption labels.
760 tw = self.GetTextExtent(self._caption)[0]
761 size.SetWidth(max(size.width, size.height))
762 return size
763
764
765 def AddItem(self, item):
766 """
767 Add a window or sizer item to the MyButtonBox.
768 """
769
770 self._csizer.Add(item, 0 )
771
772 #-------------------------------------------------------------------------------
773
774 class MyPanel(wx.Panel):
775 """
776 Thanks to Cody Precord.
777 """
778 def __init__(self, parent):
779 wx.Panel.__init__(self, parent)
780
781 #------------
782
783 # Return bitmaps folder.
784 self.bitmaps_dir = wx.GetApp().GetBitmapsDir()
785
786 #------------
787
788 # Create a timer.
789 self.timer = wx.Timer(self)
790 self.timer.Start(1000)
791 self.Bind(wx.EVT_TIMER, self.OnTimer, self.timer)
792
793 #------------
794
795 # Simplified init method.
796 self.SetProperties()
797 self.CreateCtrls()
798 self.BindEvents()
799
800 #---------------------------------------------------------------------------
801
802 def SetProperties(self):
803 """
804 ...
805 """
806
807 self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
808
809
810 def CreateCtrls(self):
811 """
812 ...
813 """
814
815 # Load an background bitmap.
816 self.bitmap = wx.Bitmap(os.path.join(self.bitmaps_dir,
817 "skin_main_1.png"),
818 type=wx.BITMAP_TYPE_PNG)
819
820 #------------
821
822 # Buttons box.
823 self.box1 = MyButtonBox(self, "") # Button About.
824 self.box2 = MyButtonBox(self, "") # Button Quit.
825
826 #------------
827
828 # Buttons bitmap.
829 bmp1 = wx.Bitmap(os.path.join(self.bitmaps_dir,
830 "btn_exit_normal.png"),
831 type=wx.BITMAP_TYPE_PNG)
832
833 bmp2 = wx.Bitmap(os.path.join(self.bitmaps_dir,
834 "btn_exit_pressed.png"),
835 type=wx.BITMAP_TYPE_PNG)
836
837 bmp3 = wx.Bitmap(os.path.join(self.bitmaps_dir,
838 "btn_exit_disabled.png"),
839 type=wx.BITMAP_TYPE_PNG)
840
841 bmpA = wx.Bitmap(os.path.join(self.bitmaps_dir,
842 "btn_about_normal.png"),
843 type=wx.BITMAP_TYPE_PNG)
844
845 bmpB = wx.Bitmap(os.path.join(self.bitmaps_dir,
846 "btn_about_pressed.png"),
847 type=wx.BITMAP_TYPE_PNG)
848
849 bmpC = wx.Bitmap(os.path.join(self.bitmaps_dir,
850 "btn_about_disabled.png"),
851 type=wx.BITMAP_TYPE_PNG)
852
853 # Buttons panel.
854 self.btn1 = MyWindow(self.box1, "", "black", "#9e9d9d", bmpA, bmpB, bmpC)
855 self.btn1.SetToolTip("This is a customized button.")
856 self.btn1.Bind(wx.EVT_BUTTON, self.OnBtnAbout)
857 self.btn1.SetFocus() # Necessary for Linux.
858
859 self.btn2 = MyWindow(self.box2, "", "black", "#9e9d9d", bmp1, bmp2, bmp3)
860 self.btn2.SetToolTip("This is a customized button.")
861 self.btn2.Bind(wx.EVT_BUTTON, self.OnBtnClose)
862 # self.btn2.Enable(False)
863
864 # Return main image size.
865 bw, bh = self.bitmap.GetWidth(), self.bitmap.GetHeight()
866
867 self.box1.AddItem(self.btn1)
868 self.box2.AddItem(self.btn2)
869
870 self.box1.SetPosition((int((bw-21+170)/2), int(50)))
871 self.box1.SetSize((21, 21))
872
873 self.box2.SetPosition((int((bw-50)/2), int(415)))
874 self.box2.SetSize((50, 50))
875
876
877 def BindEvents(self):
878 """
879 Bind some events to an events handler.
880 """
881
882 self.Bind(wx.EVT_PAINT, self.OnPaint)
883 self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)
884
885
886 def OnEraseBackground(self, event):
887 """
888 ...
889 """
890
891 dc = event.GetDC()
892 if not dc:
893 dc = wx.ClientDC(self)
894 rect = self.GetUpdateRegion().GetBox()
895 dc.SetClippingRect(rect)
896
897
898 def OnBtnAbout(self, event):
899 """
900 ...
901 """
902
903 self.GetParent().OnAbout(True)
904
905 print("About button was clicked.")
906
907
908 def OnBtnClose(self, event):
909 """
910 ...
911 """
912
913 self.GetParent().OnCloseWindow(self)
914
915 print("Close button was clicked.")
916
917
918 def Draw(self, dc):
919 """
920 ...
921 """
922
923 # Draw a bitmap with an alpha channel
924 # on top of the last group.
925 # image, x, y, transparence
926 dc.DrawBitmap(self.bitmap, 0, 0, True)
927
928 #------------
929
930 fontSize = self.GetFont().GetPointSize()
931
932 # wx.Font(pointSize, family, style, weight, underline, faceName)
933 if wx.Platform == "__WXMAC__":
934 self.normalBoldFont = wx.Font(fontSize-1,
935 wx.DEFAULT, wx.NORMAL,
936 wx.NORMAL, False, "")
937 self.normalFont = wx.Font(fontSize-2,
938 wx.DEFAULT, wx.NORMAL,
939 wx.NORMAL, False, "")
940
941 elif wx.Platform == "__WXGTK__":
942 self.normalBoldFont = wx.Font(fontSize-1,
943 wx.DEFAULT, wx.NORMAL,
944 wx.NORMAL, False, "")
945 self.normalFont = wx.Font(fontSize-2,
946 wx.DEFAULT, wx.NORMAL,
947 wx.NORMAL, False, "")
948
949 else:
950 self.normalBoldFont = wx.Font(fontSize+23,
951 wx.DEFAULT, wx.NORMAL,
952 wx.NORMAL, False, "")
953 self.normalFont = wx.Font(fontSize+1,
954 wx.DEFAULT, wx.NORMAL,
955 wx.NORMAL, False, "")
956
957 dc.SetFont(self.normalFont)
958 dc.SetFont(self.normalBoldFont)
959
960 #------------
961
962 # Return main image size.
963 bw, bh = self.bitmap.GetWidth(), self.bitmap.GetHeight()
964
965 # Draw text.
966 dc.SetTextForeground("#8e8e8e")
967 dc.SetFont(self.normalFont)
968 date = time.strftime("%A %d %B %Y")
969 tw, th = dc.GetTextExtent(date)
970 dc.DrawText(date, (int((bw-tw)/2), int(143)))
971
972 dc.SetTextForeground(wx.WHITE)
973 dc.SetFont(self.normalBoldFont)
974 hour = time.strftime("%H:%M:%S") # "%I:%M:%S %p"
975 tw, th = dc.GetTextExtent(hour)
976 dc.DrawText(hour, (int((bw-tw)/2), int(100)))
977
978
979 def OnTimer(self, event):
980 """
981 ...
982 """
983
984 dc = wx.BufferedDC(wx.ClientDC(self))
985 self.Draw(dc)
986 self.Refresh() # Mac
987
988
989 def OnPaint(self, event):
990 """
991 ...
992 """
993
994 dc = wx.BufferedPaintDC(self)
995 dc.Clear()
996
997 self.Draw(dc)
998
999 #-------------------------------------------------------------------------------
1000
1001 class MyFrame(wx.Frame):
1002 """
1003 Thanks to Robin Dunn.
1004 """
1005 def __init__(self):
1006 style = (wx.CLIP_CHILDREN | wx.CLOSE_BOX |
1007 wx.MINIMIZE_BOX | wx.SYSTEM_MENU |
1008 wx.NO_BORDER | wx.FRAME_SHAPED |
1009 wx.NO_FULL_REPAINT_ON_RESIZE)
1010 wx.Frame.__init__(self, None, -1, title="", style=style)
1011
1012 #------------
1013
1014 # Attributes.
1015 self.SetTransparent(0)
1016 self.opacity_in = 0
1017 self.opacity_out = 250
1018 self.deltaN = -5
1019 self.hasShape = False
1020 self.delta = wx.Point(0,0)
1021
1022 #------------
1023
1024 # Return application name.
1025 self.app_name = wx.GetApp().GetAppName()
1026 # Return bitmaps folder.
1027 self.bitmaps_dir = wx.GetApp().GetBitmapsDir()
1028 # Return icons folder.
1029 self.icons_dir = wx.GetApp().GetIconsDir()
1030
1031 #------------
1032
1033 # Simplified init method.
1034 self.SetProperties()
1035 self.OnTimerIn(self)
1036 self.CreateCtrls()
1037 self.BindEvents()
1038 self.DoLayout()
1039
1040 #------------
1041
1042 self.CenterOnScreen(wx.BOTH)
1043
1044 #------------
1045
1046 self.Show(True)
1047
1048 #---------------------------------------------------------------------------
1049
1050 def OnTimerIn(self, evt):
1051 """
1052 Thanks to Pascal Faut.
1053 """
1054
1055 self.timer1 = wx.Timer(self, -1)
1056 self.timer1.Start(1)
1057 self.Bind(wx.EVT_TIMER, self.AlphaCycle1, self.timer1)
1058
1059 print("Fade-in was launched.")
1060
1061
1062 def OnTimerOut(self, evt):
1063 """
1064 Thanks to Pascal Faut.
1065 """
1066
1067 self.timer2 = wx.Timer(self, -1)
1068 self.timer2.Start(1)
1069 self.Bind(wx.EVT_TIMER, self.AlphaCycle2, self.timer2)
1070
1071 print("Fade-out was launched.")
1072
1073
1074 def AlphaCycle1(self, *args):
1075 """
1076 Thanks to Pascal Faut.
1077 """
1078
1079 self.opacity_in += self.deltaN
1080 if self.opacity_in <= 0:
1081 self.deltaN = -self.deltaN
1082 self.opacity_in = 0
1083
1084 if self.opacity_in >= 250:
1085 self.deltaN = -self.deltaN
1086 self.opacity_in = 250
1087
1088 self.timer1.Stop()
1089
1090 self.SetTransparent(self.opacity_in)
1091
1092 print("Fade in = {}/255".format(self.opacity_in))
1093
1094
1095 def AlphaCycle2(self, *args):
1096 """
1097 Thanks to Pascal Faut.
1098 """
1099
1100 self.opacity_out += self.deltaN
1101 if self.opacity_out >= 250:
1102 self.deltaN = -self.deltaN
1103 self.opacity_out = 250
1104
1105 if self.opacity_out <= 0:
1106 self.deltaN = -self.deltaN
1107 self.opacity_out = 0
1108
1109 self.timer2.Stop()
1110 wx.CallAfter(self.Destroy)
1111 wx.Exit()
1112
1113 self.SetTransparent(self.opacity_out)
1114
1115 print("Fade out = {}/255".format(self.opacity_out))
1116
1117
1118 def SetProperties(self):
1119 """
1120 ...
1121 """
1122
1123 self.SetTitle(self.app_name)
1124 self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
1125
1126 frameIcon = wx.Icon(os.path.join(self.icons_dir,
1127 "icon_wxWidgets.ico"),
1128 type=wx.BITMAP_TYPE_ICO)
1129 self.SetIcon(frameIcon)
1130
1131
1132 def CreateCtrls(self):
1133 """
1134 ...
1135 """
1136
1137 self.panel = MyPanel(self)
1138
1139 #------------
1140
1141 # Load a background bitmap.
1142 self.bmp = wx.Bitmap(os.path.join(self.bitmaps_dir,
1143 "skin_main_1.png"),
1144 type=wx.BITMAP_TYPE_PNG)
1145 mask = wx.Mask(self.bmp, wx.RED)
1146 self.bmp.SetMask(mask)
1147
1148 self.SetClientSize((self.bmp.GetWidth(), self.bmp.GetHeight()))
1149
1150 #------------
1151
1152 if wx.Platform == "__WXGTK__":
1153 # wxGTK requires that the window be created before you can
1154 # set its shape, so delay the call to SetWindowShape until
1155 # this event.
1156 self.Bind(wx.EVT_WINDOW_CREATE, self.SetWindowShape)
1157 else:
1158 # On wxMSW and wxMac the window has
1159 # already been created, so go for it.
1160 self.SetWindowShape()
1161
1162 # Create an accelerator table.
1163 self.accel_tbl = wx.AcceleratorTable([(wx.ACCEL_CTRL, ord('X'), wx.ID_EXIT),
1164 (wx.ACCEL_CTRL, ord('A'), wx.ID_ABOUT)
1165 ])
1166 self.SetAcceleratorTable(self.accel_tbl)
1167
1168
1169 def BindEvents(self):
1170 """
1171 Bind some events to an events handle.
1172 """
1173
1174 self.panel.Bind(wx.EVT_LEFT_DCLICK, self.OnDoubleClick) # View mask.
1175 self.panel.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
1176 self.panel.Bind(wx.EVT_RIGHT_UP, self.OnCloseWindow) # Panel right clic.
1177
1178 self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)
1179 self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
1180 self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
1181 self.Bind(wx.EVT_MOTION, self.OnMouseMove)
1182
1183 self.Bind(wx.EVT_MENU, self.OnCloseWindow, id=wx.ID_EXIT) # Ctrl+X.
1184 self.Bind(wx.EVT_MENU, self.OnAbout, id=wx.ID_ABOUT)
1185
1186
1187 def DoLayout(self):
1188 """
1189 ...
1190 """
1191
1192 sizer = wx.BoxSizer(wx.VERTICAL)
1193 sizer.Add(self.panel, 1, wx.EXPAND)
1194 self.SetSizer(sizer)
1195
1196
1197 def OnAbout(self, event):
1198 """
1199 ...
1200 """
1201
1202 self.dialog = MyAboutDlg(self)
1203
1204
1205 def SetWindowShape(self, *evt):
1206 """
1207 ...
1208 """
1209
1210 # Use the bitmap's mask to determine the region.
1211 r = wx.Region(self.bmp)
1212 self.hasShape = self.SetShape(r)
1213
1214
1215 def OnEraseBackground(self, event):
1216 """
1217 ...
1218 """
1219
1220 dc = event.GetDC()
1221 if not dc:
1222 dc = wx.ClientDC(self)
1223 rect = self.GetUpdateRegion().GetBox()
1224 dc.SetClippingRect(rect)
1225
1226
1227 def OnDoubleClick(self, event):
1228 """
1229 ...
1230 """
1231
1232 if self.hasShape:
1233 self.SetShape(wx.Region())
1234 self.hasShape = False
1235 else:
1236 self.SetWindowShape()
1237
1238
1239 def OnLeftDown(self, event):
1240 """
1241 ...
1242 """
1243
1244 self.CaptureMouse()
1245 x, y = self.ClientToScreen(event.GetPosition())
1246 originx, originy = self.GetPosition()
1247 dx = x - originx
1248 dy = y - originy
1249 self.delta = ((dx, dy))
1250
1251
1252 def OnLeftUp(self, evt):
1253 """
1254 ...
1255 """
1256
1257 if self.HasCapture():
1258 self.ReleaseMouse()
1259
1260
1261 def OnMouseMove(self, event):
1262 """
1263 ...
1264 """
1265
1266 if event.Dragging() and event.LeftIsDown():
1267 x, y = self.ClientToScreen(event.GetPosition())
1268 fp = (x - self.delta[0], y - self.delta[1])
1269 self.Move(fp)
1270
1271
1272 def OnIconize(self, event):
1273 """
1274 ...
1275 """
1276
1277 self.Iconize()
1278
1279
1280 def OnCloseWindow(self, event):
1281 """
1282 Quit this application.
1283 """
1284
1285 # self.Destroy()
1286 self.OnTimerOut(self)
1287
1288 print("Exit application.")
1289
1290 #-------------------------------------------------------------------------------
1291
1292 class MyApp(wx.App):
1293 """
1294 Thanks to Andrea Gavana.
1295 """
1296 def OnInit(self):
1297
1298 #------------
1299
1300 self.locale = wx.Locale(wx.LANGUAGE_FRENCH)
1301
1302 #------------
1303
1304 self.SetAppName("Custom Gui 1")
1305
1306 #------------
1307
1308 self.installDir = os.path.split(os.path.abspath(sys.argv[0]))[0]
1309
1310 #------------
1311
1312 frame = MyFrame()
1313 self.SetTopWindow(frame)
1314 frame.Show(True)
1315
1316 return True
1317
1318 #---------------------------------------------------------------------------
1319
1320 def GetInstallDir(self):
1321 """
1322 Returns the installation directory for my application.
1323 """
1324
1325 return self.installDir
1326
1327
1328 def GetIconsDir(self):
1329 """
1330 Returns the icons directory for my application.
1331 """
1332
1333 icons_dir = os.path.join(self.installDir, "icons")
1334 return icons_dir
1335
1336
1337 def GetBitmapsDir(self):
1338 """
1339 Returns the bitmaps directory for my application.
1340 """
1341
1342 bitmaps_dir = os.path.join(self.installDir, "bitmaps")
1343 return bitmaps_dir
1344
1345 #-------------------------------------------------------------------------------
1346
1347 def main():
1348 app = MyApp(False)
1349 app.MainLoop()
1350
1351 #-------------------------------------------------------------------------------
1352
1353 if __name__ == "__main__" :
1354 main()
Second example
1 # sample_two.py
2
3 import sys
4 import os
5 import platform
6 import time
7 import wx
8 import wx.adv
9 import wx.lib.fancytext as fancytext
10
11 # class MyTitleBar
12 # class MyAboutDlg
13 # class MyPopupMenu
14 # class MyWindow
15 # class MyButtonBox
16 # class MyPanel
17 # class MyFrame
18 # class MyApp
19
20 #-------------------------------------------------------------------------------
21
22 class MyTitleBar(wx.Control):
23 """
24 Thanks to Cody Precord.
25 """
26 def __init__(self, parent, label, size):
27 super(MyTitleBar, self).__init__(parent, style=wx.BORDER_SIMPLE)
28
29 #------------
30
31 # Attributes.
32 self.parent = parent
33 self.label = label
34 self.size = size
35
36 #------------
37
38 # Simplified init method.
39 self.SetBackground()
40 self.SetProperties(label, size)
41 self.BindEvents()
42
43 #-----------------------------------------------------------------------
44
45 def SetBackground(self):
46 """
47 ...
48 """
49
50 self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
51
52
53 def SetProperties(self, label, size):
54 """
55 ...
56 """
57
58 self.label = label
59 self.size = size
60
61 self.label_font = self.GetFont()
62 self.label_font.SetFamily(wx.SWISS)
63 self.label_font.SetPointSize(size)
64 self.label_font.SetWeight(wx.BOLD)
65 self.SetFont(self.label_font)
66
67
68 def BindEvents(self):
69 """
70 Bind some events to an events handler.
71 """
72
73 self.Bind(wx.EVT_PAINT, self.OnPaint)
74 self.Bind(wx.EVT_LEFT_DCLICK, self.OnDoubleClick) # View mask.
75 self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
76 self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
77
78
79 def OnLeftDown(self, event):
80 """
81 ...
82 """
83
84 self.GetTopLevelParent().OnLeftDown(event)
85
86
87 def OnLeftUp(self, event):
88 """
89 ...
90 """
91
92 self.GetTopLevelParent().OnLeftUp(event)
93
94
95 def OnDoubleClick(self, event):
96 """
97 ...
98 """
99
100 self.GetTopLevelParent().OnDoubleClick(event)
101
102
103 def SetLabel(self, label):
104 """
105 ...
106 """
107
108 self.label = label
109 self.Refresh()
110
111
112 def DoGetBestSize(self):
113 """
114 ...
115 """
116
117 dc = wx.ClientDC(self)
118 dc.SetFont(self.GetFont())
119
120 textWidth, textHeight = dc.GetTextExtent(self.label)
121 spacing = 10
122 totalWidth = textWidth + (spacing)
123 totalHeight = textHeight + (spacing)
124
125 best = wx.Size(totalWidth, totalHeight)
126 self.CacheBestSize(best)
127
128 return best
129
130
131 def GetLabel(self):
132 """
133 ...
134 """
135
136 return self.label
137
138
139 def GetLabelColor(self):
140 """
141 ...
142 """
143
144 return self.foreground
145
146
147 def GetLabelSize(self):
148 """
149 ...
150 """
151
152 return self.size
153
154
155 def SetLabelColour(self, colour):
156 """
157 ...
158 """
159
160 self.labelColour = colour
161
162
163 def OnPaint(self, event):
164 """
165 ...
166 """
167
168 dc = wx.BufferedPaintDC(self)
169 gcdc = wx.GCDC(dc)
170
171 gcdc.Clear()
172
173 # Setup the GraphicsContext.
174 gc = gcdc.GetGraphicsContext()
175
176 # Get the working size we can draw in.
177 width, height = self.GetSize()
178
179 # Use the GCDC to draw the text.
180 gcdc.GradientFillLinear((0, 0, width, height+70), "#3D3D3D",
181 wx.SystemSettings.GetColour(wx.SYS_COLOUR_MENU),
182 wx.NORTH)
183
184 # Get the system font.
185 gcdc.SetFont(self.GetFont())
186
187 textWidth, textHeight = gcdc.GetTextExtent(self.label)
188 tposx, tposy = ((width/2)-(textWidth/2), (height/3)-(textHeight/3))
189
190 tposx += 0
191 tposy += 0
192
193 # Set position and text color.
194 gcdc.SetTextForeground("white")
195 gcdc.DrawText(self.label, int(tposx-25), int(tposy+1))
196
197 gcdc.SetTextForeground(self.labelColour)
198 gcdc.DrawText(self.label, int(tposx-25), int(tposy))
199
200 #-------------------------------------------------------------------------------
201
202 class MyAboutDlg(wx.Frame):
203 """
204 Thanks to Robin Dunn.
205 """
206 def __init__(self, parent):
207 style = (wx.FRAME_SHAPED | wx.NO_BORDER |
208 wx.CLIP_CHILDREN | wx.STAY_ON_TOP |
209 wx.SYSTEM_MENU | wx.CLOSE_BOX |
210 wx.NO_FULL_REPAINT_ON_RESIZE)
211 wx.Frame.__init__(self,
212 parent,
213 id=-1,
214 title="About...",
215 style=style)
216
217 #------------
218
219 # Attributes.
220 self.SetTransparent(0)
221 self.opacity_in = 0
222 self.opacity_out = 255
223 self.deltaN = -70
224 self.hasShape = False
225 self.delta = wx.Point(0,0)
226
227 #------------
228
229 # Return application name.
230 self.app_name = wx.GetApp().GetAppName()
231 # Return bitmaps folder.
232 self.bitmaps_dir = wx.GetApp().GetBitmapsDir()
233 # Return icons folder.
234 self.icons_dir = wx.GetApp().GetIconsDir()
235
236 #------------
237
238 # Simplified init method.
239 self.SetProperties()
240 self.OnTimerIn(self)
241 self.CreateCtrls()
242 self.BindEvents()
243
244 #------------
245
246 self.CenterOnParent(wx.BOTH)
247 self.GetParent().Enable(False)
248
249 #------------
250
251 self.Show(True)
252
253 #------------
254
255 self.eventLoop = wx.GUIEventLoop()
256 self.eventLoop.Run()
257
258 #---------------------------------------------------------------------------
259
260 def SetProperties(self):
261 """
262 Set the dialog properties (title, icon, transparency...).
263 """
264
265 frameIcon = wx.Icon(os.path.join(self.icons_dir,
266 "icon_wxWidgets.ico"),
267 type=wx.BITMAP_TYPE_ICO)
268 self.SetIcon(frameIcon)
269
270
271 def OnTimerIn(self, evt):
272 """
273 Thanks to Pascal Faut.
274 """
275
276 self.timer1 = wx.Timer(self, -1)
277 self.timer1.Start(1)
278 self.Bind(wx.EVT_TIMER, self.AlphaCycle1, self.timer1)
279
280 print("Fade-in was launched.")
281
282
283 def OnTimerOut(self, evt):
284 """
285 Thanks to Pascal Faut.
286 """
287
288 self.timer2 = wx.Timer(self, -1)
289 self.timer2.Start(1)
290 self.Bind(wx.EVT_TIMER, self.AlphaCycle2, self.timer2)
291
292 print("Fade-out was launched.")
293
294
295 def AlphaCycle1(self, *args):
296 """
297 Thanks to Pascal Faut.
298 """
299
300 self.opacity_in += self.deltaN
301 if self.opacity_in <= 0:
302 self.deltaN = -self.deltaN
303 self.opacity_in = 0
304
305 if self.opacity_in >= 255:
306 self.deltaN = -self.deltaN
307 self.opacity_in = 255
308
309 self.timer1.Stop()
310
311 self.SetTransparent(self.opacity_in)
312
313 print("Fade in = {}/255".format(self.opacity_in))
314
315
316 def AlphaCycle2(self, *args):
317 """
318 Thanks to Pascal Faut.
319 """
320
321 self.opacity_out += self.deltaN
322 if self.opacity_out >= 255:
323 self.deltaN = -self.deltaN
324 self.opacity_out = 255
325
326 if self.opacity_out <= 0:
327 self.deltaN = -self.deltaN
328 self.opacity_out = 0
329
330 self.timer2.Stop()
331
332 wx.CallAfter(self.Destroy)
333
334 self.SetTransparent(self.opacity_out)
335
336 print("Fade out = {}/255".format(self.opacity_out))
337
338
339 def CreateCtrls(self):
340 """
341 Make widgets for my dialog.
342 """
343
344 # Load a background bitmap.
345 self.bmp = wx.Bitmap(os.path.join(self.bitmaps_dir,
346 "skin_about.png"),
347 type=wx.BITMAP_TYPE_PNG)
348 mask = wx.Mask(self.bmp, wx.RED)
349 self.bmp.SetMask(mask)
350
351 #------------
352
353 self.SetClientSize((self.bmp.GetWidth(), self.bmp.GetHeight()))
354
355 #------------
356
357 if wx.Platform == "__WXGTK__":
358 # wxGTK requires that the window be created before you can
359 # set its shape, so delay the call to SetWindowShape until
360 # this event.
361 self.Bind(wx.EVT_WINDOW_CREATE, self.SetWindowShape)
362 else:
363 # On wxMSW and wxMac the window has already
364 # been created, so go for it.
365 self.SetWindowShape()
366
367
368 def BindEvents(self):
369 """
370 Bind all the events related to my dialog.
371 """
372
373 # Bind some events to an events handler.
374 self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
375 self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
376 self.Bind(wx.EVT_RIGHT_UP, self.OnCloseWindow) # Panel right clic.
377 self.Bind(wx.EVT_LEFT_DCLICK, self.OnDoubleClick) # View mask.
378 self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)
379 self.Bind(wx.EVT_WINDOW_CREATE, self.SetWindowShape)
380 self.Bind(wx.EVT_MOTION, self.OnMouseMove)
381 self.Bind(wx.EVT_KEY_UP, self.OnKeyUp)
382 self.Bind(wx.EVT_PAINT, self.OnPaint)
383 self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
384
385
386 def SetWindowShape(self, event=None):
387 """
388 ...
389 """
390
391 # Use the bitmap's mask to determine the region.
392 r = wx.Region(self.bmp)
393 self.hasShape = self.SetShape(r)
394
395
396 def OnEraseBackground(self, event):
397 """
398 ...
399 """
400
401 dc = event.GetDC()
402 if not dc:
403 dc = wx.ClientDC(self)
404 rect = self.GetUpdateRegion().GetBox()
405 dc.SetClippingRect(rect)
406
407
408 def OnDoubleClick(self, event):
409 """
410 ...
411 """
412
413 if self.hasShape:
414 self.SetShape(wx.Region())
415 self.hasShape = False
416 else:
417 self.SetWindowShape()
418
419
420 def OnLeftDown(self, event):
421 """
422 ...
423 """
424
425 self.CaptureMouse()
426 x, y = self.ClientToScreen(event.GetPosition())
427 originx, originy = self.GetPosition()
428 dx = x - originx
429 dy = y - originy
430 self.delta = ((dx, dy))
431
432
433 def OnLeftUp(self, evt):
434 """
435 ...
436 """
437
438 if self.HasCapture():
439 self.ReleaseMouse()
440
441
442 def OnMouseMove(self, event):
443 """
444 ...
445 """
446
447 if event.Dragging() and event.LeftIsDown():
448 x, y = self.ClientToScreen(event.GetPosition())
449 fp = (x - self.delta[0], y - self.delta[1])
450 self.Move(fp)
451
452
453 def OnPaint(self, event):
454 """
455 ...
456 """
457
458 dc = wx.AutoBufferedPaintDCFactory(self)
459 dc.DrawBitmap(self.bmp, 0, 0, True)
460
461 #------------
462
463 # These are strings.
464 py_version = sys.version.split()[0]
465
466 str1 = (('<font style="normal" family="default" color="yellow" size="10" weight="bold">'
467 'Programming : </font>'
468 '<font style="normal" family="default" color="black" size="10" weight="normal">'
469 'Python {}</font>').format(py_version)) # Python 3.6.5
470
471 str2 = (('<font style="normal" family="default" color="red" size="10" weight="bold">'
472 'GUI toolkit : </font>'
473 '<font style="normal" family="default" color="black" size="10" weight="normal">'
474 'wxPython {}</font>').format(wx.VERSION_STRING)) # wxPython 4.0.2
475
476 str3 = (('<font style="normal" family="default" color="brown" size="10" weight="bold">'
477 'Library : </font>'
478 '<font style="normal" family="default" color="black" size="10" weight="normal">'
479 '{}</font>').format(wx.GetLibraryVersionInfo().VersionString)) # wxWidgets 3.0.5
480
481 str4 = (('<font style="normal" family="default" color="blue" size="10" weight="bold">'
482 'Operating system : </font>'
483 '<font style="normal" family="default" color="black" size="10" weight="normal">'
484 '{}</font>').format(platform.system())) # Windows
485
486 str5 = (('<font style="normal" family="default" color="white" size="9" weight="normal">'
487 '{}</font>').format(self.app_name)) # Custom Gui 2
488
489 str6 = (('<font style="normal" family="default" color="dark blue" size="8" weight="normal">'
490 'Right clic or Esc for Exit</font>'))
491
492 #------------
493
494 # Return image size.
495 bw, bh = self.bmp.GetWidth(), self.bmp.GetHeight()
496
497 # Draw text.
498 # Need width to calculate x position of str1.
499 tw, th = fancytext.GetExtent(str1, dc)
500 # Centered text.
501 fancytext.RenderToDC(str1, dc, (bw-tw)/2, 30)
502
503 #------------
504
505 # Need width to calculate x position of str2.
506 tw, th = fancytext.GetExtent(str2, dc)
507 # Centered text.
508 fancytext.RenderToDC(str2, dc, (bw-tw)/2, 50)
509
510 #------------
511
512 # Need width to calculate x position of str3.
513 tw, th = fancytext.GetExtent(str3, dc)
514 # Centered text.
515 fancytext.RenderToDC(str3, dc, (bw-tw)/2, 70)
516
517 #------------
518
519 # Need width to calculate x position of str4.
520 tw, th = fancytext.GetExtent(str4, dc)
521 # Centered text.
522 fancytext.RenderToDC(str4, dc, (bw-tw)/2, 90)
523
524 #------------
525
526 # Need width to calculate x position of str5.
527 tw, th = fancytext.GetExtent(str5, dc)
528 # Centered text.
529 fancytext.RenderToDC(str5, dc, (bw-tw)/2, 130)
530
531 #------------
532
533 # Need width to calculate x position of str6.
534 tw, th = fancytext.GetExtent(str6, dc)
535 # Centered text.
536 fancytext.RenderToDC(str6, dc, (bw-tw)/2, 195)
537
538
539 def OnKeyUp(self, event):
540 """
541 ...
542 """
543
544 if event.GetKeyCode() == wx.WXK_ESCAPE:
545 self.OnCloseWindow(event)
546
547 event.Skip()
548
549
550 def OnCloseWindow(self, event):
551 """
552 ...
553 """
554
555 self.GetParent().Enable(True)
556 self.eventLoop.Exit()
557 #self.Destroy()
558 self.OnTimerOut(self)
559
560 #-------------------------------------------------------------------------------
561
562 class MyPopupMenu(wx.Menu):
563 """
564 Thanks to Robin Dunn.
565 """
566 def __init__(self, parent):
567 wx.Menu.__init__(self)
568
569 #------------
570
571 # Attributes.
572 self.parent = parent
573
574 #------------
575
576 # Simplified init method.
577 self.CreatePopupMenu()
578 self.BindEvents()
579
580 #---------------------------------------------------------------------------
581
582 def CreatePopupMenu(self, event=None):
583 """
584 This method is called by the base class when it needs to popup
585 the menu for the default EVT_RIGHT_DOWN event. Just create
586 the menu how you want it and return it from this function,
587 the base class takes care of the rest.
588 """
589
590 # Returns bitmaps folder.
591 bitmaps_dir = wx.GetApp().GetBitmapsDir()
592
593 #------------
594
595 bmp = wx.Bitmap(os.path.join(bitmaps_dir,
596 "item_about.png"),
597 type=wx.BITMAP_TYPE_PNG)
598
599 item = wx.MenuItem(self, id=wx.ID_ABOUT, text=" About")
600 item.SetBitmap(bmp)
601 self.Append(item)
602 self.AppendSeparator()
603
604 #------------
605
606 bmp = wx.Bitmap(os.path.join(bitmaps_dir,
607 "item_exit.png"),
608 type=wx.BITMAP_TYPE_PNG)
609
610 if True or "__WXMSW__" in wx.PlatformInfo:
611 font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)
612 font.SetWeight(wx.BOLD)
613
614 item = wx.MenuItem(self, id=wx.ID_EXIT, text=" Exit")
615 item.SetBitmap(bmp)
616 item.SetFont(font)
617 self.Append(item)
618
619 return self
620
621
622 def BindEvents(self):
623 """
624 Bind some events to an events handler.
625 """
626
627 # Bind the menu events to an events handler.
628 self.Bind(wx.EVT_MENU, self.OnAbout, id=wx.ID_ABOUT)
629 self.Bind(wx.EVT_MENU, self.OnClose, id=wx.ID_EXIT)
630
631
632 def OnAbout(self, event):
633 """
634 ...
635 """
636
637 self.mainFrame = wx.GetApp().GetTopWindow()
638 self.mainFrame.OnAbout(self)
639
640 print("About icon was clicked.")
641
642
643 def OnClose(self, event):
644 """
645 ...
646 """
647
648 self.mainFrame = wx.GetApp().GetTopWindow()
649 self.mainFrame.OnTimerOut(self)
650
651 print("Close icon was clicked.")
652
653 #-------------------------------------------------------------------------------
654
655 class MyWindow(wx.Control):
656 """
657 Thanks to Cody Precord.
658 """
659 def __init__(self, parent, label,
660 foreground, background,
661 normal, pressed=None):
662 super(MyWindow, self).__init__(parent, -1,
663 style=wx.BORDER_NONE)
664
665 #------------
666
667 # Attributes.
668 self.label = label
669 self.foreground = foreground
670 self.background = background
671
672 if wx.Platform == "__WXGTK__":
673 self.color = "#9e9d9d"
674
675 else:
676 self.color = "#b1b1b0"
677
678 self.normal = normal
679 self.pressed = pressed
680
681 self._clicked = False
682
683 #------------
684
685 self.region = wx.Region(normal, wx.Colour(0, 0, 0, 0))
686
687 #------------
688
689 # Simplified init method.
690 self.SetProperties(label, foreground, background)
691 self.BindEvents()
692
693 #---------------------------------------------------------------------------
694
695 def SetProperties(self, label, foreground, background):
696 """
697 ...
698 """
699
700 self.label = label
701 self.foreground = foreground
702 self.background = background
703 self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
704
705
706 def BindEvents(self):
707 """
708 Bind some events to an events handler.
709 """
710
711 self.Bind(wx.EVT_SET_FOCUS, self.OnSetFocus)
712 self.Bind(wx.EVT_KILL_FOCUS, self.OnKillFocus)
713 self.Bind(wx.EVT_PAINT, self.OnPaint)
714 self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
715 self.Bind(wx.EVT_LEFT_DCLICK, self.OnLeftDclick)
716 self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
717 self.Bind(wx.EVT_MOTION, self.OnMotion)
718 self.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeave)
719 self.Bind(wx.EVT_KEY_UP, self.OnKeyUp)
720
721
722 def SetLabel(self, label):
723 """
724 ...
725 """
726
727 self.label = label
728 self.Refresh()
729
730
731 def DoGetBestSize(self):
732 """
733 ...
734 """
735
736 return self.normal.GetSize()
737
738
739 def GetLabel(self):
740 """
741 ...
742 """
743
744 return self.label
745
746
747 def GetLabelColor(self):
748 """
749 ...
750 """
751
752 return self.foreground
753
754
755 def Enable(self, *args, **kwargs):
756 """
757 ...
758 """
759
760 super(MyWindow, self).Enable(*args, **kwargs)
761 self.Refresh()
762
763
764 def Disable(self, *args, **kwargs):
765 """
766 ...
767 """
768
769 super(MyWindow, self).Disable(*args, **kwargs)
770 self.Refresh()
771
772
773 def PostEvent(self):
774 """
775 ...
776 """
777
778 event = wx.CommandEvent()
779 event.SetEventObject(self)
780 event.SetEventType(wx.EVT_BUTTON.typeId)
781 wx.PostEvent(self, event)
782
783
784 def OnSize(self, event):
785 """
786 ...
787 """
788
789 event.Skip()
790 self.Refresh()
791
792
793 def Getbackground(self):
794 """
795 ...
796 """
797
798 return self.background
799
800
801 def OnPaint(self, event):
802 """
803 ...
804 """
805
806 dc = wx.BufferedPaintDC(self)
807 dc.Clear()
808 gcdc = wx.GCDC(dc)
809
810 # Set the background color.
811 if wx.Platform == "__WXGTK__":
812 gcdc.SetBackground(wx.Brush("grey55"))
813 else:
814 gcdc.SetBackground(wx.Brush(self.background))
815
816 gcdc.Clear()
817
818 # Get the working rectangle we can draw in.
819 rect = self.GetClientRect()
820
821 # Font size and style.
822 fontSize = self.GetFont().GetPointSize()
823
824 if wx.Platform == "__WXGTK__":
825 boldFont = wx.Font(fontSize-1, wx.DEFAULT,
826 wx.NORMAL, wx.NORMAL, False, "")
827 else:
828 boldFont = wx.Font(fontSize+2, wx.DEFAULT,
829 wx.NORMAL, wx.BOLD, False, "")
830
831 if wx.Platform == "__WXMSW__":
832 pen = wx.Pen(self.color, 1, wx.SOLID)
833
834 else:
835 pen = wx.Pen(self.color, 1, wx.SOLID)
836
837 gcdc.SetPen(pen)
838
839 x, y = self.GetSize()
840 # x, y , width, height, radius
841 gcdc.DrawRoundedRectangle (0, 0, 71, 25, 3)
842
843 bitmap = self.normal
844
845 w, h = bitmap.GetWidth(), bitmap.GetHeight()
846
847 if self.clicked:
848 bitmap = self.pressed or bitmap
849 if not self.IsEnabled():
850 bitmap = self.normal or bitmap
851
852 # Draw a bitmap with an alpha channel.
853 # image, x, y, transparency.
854 dc.DrawBitmap(bitmap, 0, 0, True)
855
856 if wx.Platform == "__WXGTK__":
857 # Add the Caption.
858 # White text - Shadow.
859 rect = wx.Rect(rect.x, rect.y+3,
860 rect.width, 22)
861
862 else:
863 rect = wx.Rect(rect.x, rect.y+3,
864 rect.width, 20)
865
866 dc.SetFont(boldFont)
867 dc.SetTextForeground(wx.WHITE)
868 dc.DrawLabel(self.label, rect, wx.ALIGN_CENTER)
869
870 if wx.Platform == "__WXGTK__":
871 # Add the Caption.
872 # Black text.
873 rect = wx.Rect(rect.x, rect.y,
874 rect.width, 21)
875
876 else:
877 rect = wx.Rect(rect.x, rect.y,
878 rect.width, 19)
879
880 gcdc.SetFont(boldFont)
881 # Get the text color.
882 dc.SetTextForeground(self.foreground)
883 dc.DrawLabel(self.label, rect, wx.ALIGN_CENTER)
884
885
886 def SetClicked(self, clicked):
887 """
888 ...
889 """
890
891 if clicked != self._clicked:
892 self._clicked = clicked
893 self.Refresh()
894
895
896 def GetClicked(self):
897 """
898 ...
899 """
900
901 return self._clicked
902
903
904 clicked = property(GetClicked, SetClicked)
905 def OnLeftDown(self, event):
906 """
907 ...
908 """
909
910 x, y = event.GetPosition()
911 if self.region.Contains(x, y):
912 self.clicked = True
913 self.SetFocus()
914
915
916 def OnLeftDclick(self, event):
917 """
918 ...
919 """
920
921 self.OnLeftDown(event)
922
923
924 def OnLeftUp(self, event):
925 """
926 ...
927 """
928
929 if self.clicked:
930 x, y = event.GetPosition()
931 if self.region.Contains(x, y):
932 self.PostEvent()
933 self.clicked = False
934
935
936 def OnMotion(self, event):
937 """
938 ...
939 """
940
941 if self.clicked:
942 x, y = event.GetPosition()
943 if not self.region.Contains(x, y):
944 self.clicked = False
945
946
947 def OnLeave(self, event):
948 """
949 ...
950 """
951
952 self.clicked = False
953
954
955 def OnSetFocus(self, event):
956 """
957 ...
958 """
959
960 self.color = "white"
961 self.Refresh()
962
963
964 def OnKillFocus(self, event):
965 """
966 ...
967 """
968
969 if wx.Platform == "__WXGTK__":
970 self.color = "#9e9d9d"
971
972 else:
973 self.color = "#b1b1b0"
974
975 self.Refresh()
976
977
978 def OnKeyUp(self, event):
979 """
980 ...
981 """
982
983 if event.GetKeyCode() == wx.WXK_SPACE:
984 self.PostEvent()
985 return
986
987 elif event.GetKeyCode() == wx.WXK_ESCAPE:
988 self.GetTopLevelParent().OnCloseWindow(True)
989
990 event.Skip()
991
992 #-------------------------------------------------------------------------------
993
994 class MyButtonBox(wx.Panel):
995 """
996 Thanks to Cody Precord.
997 """
998 def __init__(self, parent, caption):
999 super(MyButtonBox, self).__init__(parent,
1000 style=wx.NO_BORDER |
1001 wx.TAB_TRAVERSAL)
1002
1003 #------------
1004
1005 # Attributes.
1006 self._caption = caption
1007
1008 #------------
1009
1010 # Simplified init method.
1011 self.DoLayout()
1012
1013 #---------------------------------------------------------------------------
1014
1015 def DoLayout(self):
1016 """
1017 ...
1018 """
1019
1020 self._csizer = wx.BoxSizer(wx.VERTICAL)
1021 msizer = wx.BoxSizer(wx.HORIZONTAL)
1022 msizer.Add(self._csizer, 0 )
1023 self.SetSizer(msizer)
1024
1025
1026 def DoGetBestSize(self):
1027 """
1028 ...
1029 """
1030
1031 size = super(MyButtonBox, self).DoGetBestSize()
1032
1033 # Compensate for wide caption labels.
1034 tw = self.GetTextExtent(self._caption)[0]
1035 size.SetWidth(max(size.width, size.height))
1036 return size
1037
1038
1039 def AddItem(self, item):
1040 """
1041 Add a window or sizer item to the MyButtonBox.
1042 """
1043
1044 self._csizer.Add(item, 0 )
1045
1046 #-------------------------------------------------------------------------------
1047
1048 class MyPanel(wx.Panel):
1049 """
1050 Thanks to Cody Precord.
1051 """
1052 def __init__(self, parent):
1053 wx.Panel.__init__(self, parent)
1054
1055 #------------
1056
1057 # Return application name.
1058 self.app_name = wx.GetApp().GetAppName()
1059 # Return bitmaps folder.
1060 self.bitmaps_dir = wx.GetApp().GetBitmapsDir()
1061
1062 #------------
1063
1064 # Create a timer.
1065 self.timer = wx.Timer(self)
1066 self.timer.Start(1000)
1067 self.Bind(wx.EVT_TIMER, self.OnTimer, self.timer)
1068
1069 #------------
1070
1071 # Simplified init method.
1072 self.SetProperties()
1073 self.CreateCtrls()
1074 self.BindEvents()
1075
1076 #---------------------------------------------------------------------------
1077
1078 def SetProperties(self):
1079 """
1080 ...
1081 """
1082
1083 self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
1084
1085
1086 def CreateCtrls(self):
1087 """
1088 ...
1089 """
1090
1091 # Load a background bitmap.
1092 self.bitmap = wx.Bitmap(os.path.join(self.bitmaps_dir,
1093 "skin_main.png"),
1094 type=wx.BITMAP_TYPE_PNG)
1095
1096 #------------
1097
1098 # Add titleBar.
1099 self.titleBar = MyTitleBar(self,
1100 label=self.app_name,
1101 size=10)
1102 self.titleBar.SetPosition((1, 1))
1103 self.titleBar.SetSize((258, 24))
1104 self.titleBar.SetLabelColour(wx.BLACK)
1105 self.titleBar.SetToolTip("This is a customized title bar.")
1106
1107 #------------
1108
1109 # Load an icon bitmap for titlebar.
1110 self.icon = wx.Bitmap(os.path.join(self.bitmaps_dir,
1111 "icon_app_2.png"),
1112 type=wx.BITMAP_TYPE_PNG)
1113
1114 self.ico = wx.StaticBitmap(self.titleBar, -1, self.icon)
1115 self.ico.SetPosition((5, 2))
1116 self.ico.SetToolTip("This is a customized icon.")
1117
1118 self.ico.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown)
1119 self.ico.Bind(wx.EVT_LEFT_DOWN, self.OnRightDown)
1120
1121 #------------
1122 #------------
1123
1124 # Load a bitmap.
1125 self.logo = wx.Bitmap(os.path.join(self.bitmaps_dir,
1126 "logo.png"),
1127 type=wx.BITMAP_TYPE_PNG)
1128
1129 #------------
1130
1131 # Aluminium Buttons box (main).
1132 self.box1 = MyButtonBox(self, "") # Button About.
1133 self.box2 = MyButtonBox(self, "") # Button Quit.
1134
1135 # Gloss Buttons box (titleBar).
1136 self.box3 = MyButtonBox(self.titleBar, "") # Button Exit.
1137 self.box4 = MyButtonBox(self.titleBar, "") # Button Reduce.
1138
1139 #------------
1140
1141 # Aluminium Buttons bitmap.
1142 bmp1 = wx.Bitmap(os.path.join(self.bitmaps_dir,
1143 "btn_alu_normal.png"),
1144 type=wx.BITMAP_TYPE_PNG)
1145
1146 bmp2 = wx.Bitmap(os.path.join(self.bitmaps_dir,
1147 "btn_alu_pressed.png"),
1148 type=wx.BITMAP_TYPE_PNG)
1149
1150 bmpa = wx.Bitmap(os.path.join(self.bitmaps_dir,
1151 "btn_alu_exit_normal.png"),
1152 type=wx.BITMAP_TYPE_PNG)
1153
1154 bmpb = wx.Bitmap(os.path.join(self.bitmaps_dir,
1155 "btn_alu_exit_selected.png"),
1156 type=wx.BITMAP_TYPE_PNG)
1157
1158
1159 bmpc = wx.Bitmap(os.path.join(self.bitmaps_dir,
1160 "btn_alu_roll_normal.png"),
1161 type=wx.BITMAP_TYPE_PNG)
1162
1163 bmpd = wx.Bitmap(os.path.join(self.bitmaps_dir,
1164 "btn_alu_roll_selected.png"),
1165 type=wx.BITMAP_TYPE_PNG)
1166
1167 # Buttons panel.
1168 self.btn1 = MyWindow(self.box1, "About", "black", "#9e9d9d", bmp1, bmp2)
1169 self.btn1.SetToolTip("This is a customized aluminium button.")
1170 self.btn1.Bind(wx.EVT_BUTTON, self.OnBtnAbout)
1171 self.btn1.SetFocus() # Necessary for Linux.
1172
1173 self.btn2 = MyWindow(self.box2, "Exit", "black", "#9e9d9d", bmp1, bmp2)
1174 self.btn2.SetToolTip("This is a customized aluminium button.")
1175 self.btn2.Bind(wx.EVT_BUTTON, self.OnBtnClose)
1176
1177 self.btn3 = MyWindow(self.box3, "", "black", "#9e9d9d", bmpa, bmpb)
1178 self.btn3.SetToolTip("This is a customized gloss button.")
1179 self.btn3.Bind(wx.EVT_BUTTON, self.OnBtnClose)
1180
1181 self.btn4 = MyWindow(self.box4, "", "black", "#9e9d9d", bmpc, bmpd)
1182 self.btn4.SetToolTip("This is a customized gloss button.")
1183 self.btn4.Bind(wx.EVT_BUTTON, self.OnBtnRoll)
1184
1185 self.box1.AddItem(self.btn1)
1186 self.box2.AddItem(self.btn2)
1187 self.box3.AddItem(self.btn3)
1188 self.box4.AddItem(self.btn4)
1189
1190 self.box1.SetPosition((20, 138))
1191 self.box1.SetSize((71, 25))
1192
1193 self.box2.SetPosition((20, 173))
1194 self.box2.SetSize((71, 25))
1195
1196 self.box3.SetPosition((214, 2))
1197 self.box3.SetSize((40, 19))
1198
1199 self.box4.SetPosition((189, 2))
1200 self.box4.SetSize((25, 19))
1201
1202
1203 def BindEvents(self):
1204 """
1205 Bind some events to an events handler.
1206 """
1207
1208 self.Bind(wx.EVT_PAINT, self.OnPaint)
1209 self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)
1210
1211
1212 def OnLeftDown(self, evt):
1213 """
1214 ...
1215 """
1216
1217 print("Left down.")
1218
1219
1220 def OnRightDown(self, event):
1221 """
1222 ...
1223 """
1224
1225 self.PopupMenu(MyPopupMenu(self), event.GetPosition())
1226
1227 print("Right down.")
1228
1229
1230 def OnEraseBackground(self, event):
1231 """
1232 ...
1233 """
1234
1235 dc = event.GetDC()
1236 if not dc:
1237 dc = wx.ClientDC(self)
1238 rect = self.GetUpdateRegion().GetBox()
1239 dc.SetClippingRect(rect)
1240
1241
1242 def OnBtnRoll(self, event):
1243 """
1244 ...
1245 """
1246
1247 self.GetParent().OnRoll(True)
1248
1249 print("Roll/unRoll button was clicked.")
1250
1251
1252 def OnBtnAbout(self, event):
1253 """
1254 ...
1255 """
1256
1257 self.GetParent().OnAbout(True)
1258
1259 print("About button was clicked.")
1260
1261
1262 def OnBtnClose(self, event):
1263 """
1264 ...
1265 """
1266
1267 self.GetParent().OnCloseWindow(self)
1268
1269 print("Close button was clicked.")
1270
1271
1272 def Draw(self, dc):
1273 """
1274 ...
1275 """
1276
1277 # Draw a bitmap with an alpha channel
1278 # on top of the last group.
1279 # image, x, y, transparence
1280 dc.DrawBitmap(self.bitmap, 0, 0, True)
1281
1282 #------------
1283
1284 fontSize = self.GetFont().GetPointSize()
1285
1286 # wx.Font(pointSize, family, style, weight, underline, faceName)
1287 if wx.Platform == "__WXGTK__":
1288 self.titleBoldFont = wx.Font(fontSize-2,
1289 wx.DEFAULT, wx.NORMAL,
1290 wx.BOLD, False, "")
1291 self.normalBoldFont = wx.Font(fontSize+18,
1292 wx.DEFAULT, wx.NORMAL,
1293 wx.NORMAL, False, "")
1294 self.normalFont = wx.Font(fontSize-2,
1295 wx.DEFAULT, wx.NORMAL,
1296 wx.NORMAL, False, "")
1297
1298 else:
1299 self.titleBoldFont = wx.Font(fontSize+1,
1300 wx.DEFAULT, wx.NORMAL,
1301 wx.BOLD, False, "")
1302 self.normalBoldFont = wx.Font(fontSize+23,
1303 wx.DEFAULT, wx.NORMAL,
1304 wx.NORMAL, False, "")
1305 self.normalFont = wx.Font(fontSize+1,
1306 wx.DEFAULT, wx.NORMAL,
1307 wx.NORMAL, False, "")
1308
1309 dc.SetFont(self.normalFont)
1310 dc.SetFont(self.normalBoldFont)
1311
1312 #------------
1313
1314 # Draw a bitmap with an alpha channel.
1315 # image, x, y, transparence
1316 dc.DrawBitmap(self.logo, 150, 165, True)
1317
1318 #------------
1319
1320 # Return image size.
1321 bw, bh = self.bitmap.GetWidth(), self.bitmap.GetHeight()
1322
1323 # Draw line.
1324 dc.SetPen(wx.Pen("#c5c4c4"))
1325 # x, y, x, y
1326 dc.DrawLine(2, 25, 258, 25)
1327
1328 # Draw text.
1329 dc.SetTextForeground("#494848")
1330 dc.SetFont(self.normalFont)
1331 date = time.strftime("%A %d %B %Y")
1332 tw, th = dc.GetTextExtent(date)
1333 dc.DrawText(date, int((bw-tw)/2), int(100))
1334
1335 dc.SetTextForeground("#e3dbdb")
1336 dc.SetFont(self.normalBoldFont)
1337 hour = time.strftime("%H:%M:%S") # "%I:%M:%S %p"
1338 tw, th = dc.GetTextExtent(hour)
1339 dc.DrawText(hour, int((bw-tw)/2), int(40))
1340
1341
1342 def OnTimer(self, event):
1343 """
1344 ...
1345 """
1346
1347 dc = wx.BufferedDC(wx.ClientDC(self))
1348 self.Draw(dc)
1349 self.Refresh() # Mac
1350
1351
1352 def OnPaint(self, event):
1353 """
1354 ...
1355 """
1356
1357 dc = wx.BufferedPaintDC(self)
1358 dc.Clear()
1359
1360 self.Draw(dc)
1361
1362 #-------------------------------------------------------------------------------
1363
1364 class MyFrame(wx.Frame):
1365 """
1366 Thanks to Robin Dunn.
1367 """
1368 def __init__(self):
1369 style = (wx.CLIP_CHILDREN | wx.CLOSE_BOX |
1370 wx.MINIMIZE_BOX | wx.SYSTEM_MENU |
1371 wx.NO_BORDER | wx.FRAME_SHAPED |
1372 wx.NO_FULL_REPAINT_ON_RESIZE)
1373 wx.Frame.__init__(self, None, -1, title="", style=style)
1374
1375 #------------
1376
1377 # Attributes.
1378 self.SetTransparent(0)
1379 self.opacity_in = 0
1380 self.opacity_out = 250
1381 self.deltaN = -3
1382 self.hasShape = False
1383 self.delta = wx.Point(0,0)
1384
1385 #------------
1386
1387 # Return application name.
1388 self.app_name = wx.GetApp().GetAppName()
1389 # Return bitmaps folder.
1390 self.bitmaps_dir = wx.GetApp().GetBitmapsDir()
1391 # Return icons folder.
1392 self.icons_dir = wx.GetApp().GetIconsDir()
1393
1394 #------------
1395
1396 # Simplified init method.
1397 self.SetProperties()
1398 self.OnTimerIn(self)
1399 self.CreateCtrls()
1400 self.BindEvents()
1401 self.DoLayout()
1402
1403 #------------
1404
1405 # Thanks to Ray Pasco.
1406 # Initialize to the current state.
1407 self.unrolledFrameClientSize_size = self.GetClientSize()
1408 self.isRolled = False
1409
1410 #------------
1411
1412 self.CenterOnScreen(wx.BOTH)
1413
1414 #------------
1415
1416 self.Show(True)
1417
1418 #---------------------------------------------------------------------------
1419
1420 def OnTimerIn(self, evt):
1421 """
1422 Thanks to Pascal Faut.
1423 """
1424
1425 self.timer1 = wx.Timer(self, -1)
1426 self.timer1.Start(1)
1427 self.Bind(wx.EVT_TIMER, self.AlphaCycle1, self.timer1)
1428
1429 print("Fade-in was launched.")
1430
1431
1432 def OnTimerOut(self, evt):
1433 """
1434 Thanks to Pascal Faut.
1435 """
1436
1437 self.timer2 = wx.Timer(self, -1)
1438 self.timer2.Start(1)
1439 self.Bind(wx.EVT_TIMER, self.AlphaCycle2, self.timer2)
1440
1441 print("Fade-out was launched.")
1442
1443
1444 def AlphaCycle1(self, *args):
1445 """
1446 Thanks to Pascal Faut.
1447 """
1448
1449 self.opacity_in += self.deltaN
1450 if self.opacity_in <= 0:
1451 self.deltaN = -self.deltaN
1452 self.opacity_in = 0
1453
1454 if self.opacity_in >= 250:
1455 self.deltaN = -self.deltaN
1456 self.opacity_in = 250
1457
1458 self.timer1.Stop()
1459
1460 self.SetTransparent(self.opacity_in)
1461
1462 print("Fade in = {}/255".format(self.opacity_in))
1463
1464
1465 def AlphaCycle2(self, *args):
1466 """
1467 Thanks to Pascal Faut.
1468 """
1469
1470 self.opacity_out += self.deltaN
1471 if self.opacity_out >= 250:
1472 self.deltaN = -self.deltaN
1473 self.opacity_out = 250
1474
1475 if self.opacity_out <= 0:
1476 self.deltaN = -self.deltaN
1477 self.opacity_out = 0
1478
1479 self.timer2.Stop()
1480 wx.CallAfter(self.Destroy)
1481 wx.Exit()
1482
1483 self.SetTransparent(self.opacity_out)
1484
1485 print("Fade out = {}/255".format(self.opacity_out))
1486
1487
1488 def SetProperties(self):
1489 """
1490 ...
1491 """
1492
1493 self.SetTitle(self.app_name)
1494 self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
1495
1496 frameIcon = wx.Icon(os.path.join(self.icons_dir,
1497 "icon_wxWidgets.ico"),
1498 type=wx.BITMAP_TYPE_ICO)
1499 self.SetIcon(frameIcon)
1500
1501
1502 def CreateCtrls(self):
1503 """
1504 ...
1505 """
1506
1507 self.panel = MyPanel(self)
1508
1509 #------------
1510
1511 # Load a background bitmap.
1512 self.bmp = wx.Bitmap(os.path.join(self.bitmaps_dir,
1513 "skin_main.png"),
1514 type=wx.BITMAP_TYPE_PNG)
1515 mask = wx.Mask(self.bmp, wx.RED)
1516 self.bmp.SetMask(mask)
1517
1518 self.SetClientSize((self.bmp.GetWidth(), self.bmp.GetHeight()))
1519
1520 #------------
1521
1522 if wx.Platform == "__WXGTK__":
1523 # wxGTK requires that the window be created before you can
1524 # set its shape, so delay the call to SetWindowShape until
1525 # this event.
1526 self.Bind(wx.EVT_WINDOW_CREATE, self.SetWindowShape)
1527 else:
1528 # On wxMSW and wxMac the window has
1529 # already been created, so go for it.
1530 self.SetWindowShape()
1531
1532 # Create an accelerator table.
1533 self.accel_tbl = wx.AcceleratorTable([(wx.ACCEL_CTRL, ord('X'), wx.ID_EXIT),
1534 (wx.ACCEL_CTRL, ord('A'), wx.ID_ABOUT)
1535 ])
1536 self.SetAcceleratorTable(self.accel_tbl)
1537
1538
1539 def BindEvents(self):
1540 """
1541 Bind some events to an events handler.
1542 """
1543
1544 self.panel.Bind(wx.EVT_LEFT_DCLICK, self.OnDoubleClick) # View mask.
1545 self.panel.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
1546 self.panel.Bind(wx.EVT_RIGHT_UP, self.OnCloseWindow) # Panel right clic.
1547
1548 self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)
1549 self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
1550 self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
1551 self.Bind(wx.EVT_MOTION, self.OnMouseMove)
1552
1553 self.Bind(wx.EVT_MENU, self.OnCloseWindow, id=wx.ID_EXIT) # Ctrl+X.
1554 self.Bind(wx.EVT_MENU, self.OnAbout, id=wx.ID_ABOUT)
1555
1556
1557 def DoLayout(self):
1558 """
1559 ...
1560 """
1561
1562 sizer = wx.BoxSizer(wx.VERTICAL)
1563 sizer.Add(self.panel, 1, wx.EXPAND)
1564 self.SetSizer(sizer)
1565
1566
1567 def OnRoll(self, event) :
1568 """
1569 Thanks to Ray Pasco.
1570 """
1571
1572 if not bool(self.isRolled) :
1573 # Set the flag to the state we want regardless of whether
1574 # or not it's in currently in the opposite state.
1575 self.RollUnRoll(wantToRoll=True)
1576
1577 elif self.isRolled : # UnRoll.
1578 # Set the flag to the state we want regardless of whether
1579 # or not it's in currently in the opposite state.
1580 self.RollUnRoll(wantToRoll=False)
1581
1582
1583 def RollUnRoll(self, wantToRoll) :
1584 """
1585 Thanks to Ray Pasco.
1586 """
1587
1588 # Thanks to Ray Pasco.
1589 # Save the current size only if the Frame is not rolled up.
1590 if not bool(self.isRolled) :
1591 self.unrolledFrameClientSize_size = self.GetClientSize()
1592
1593 if bool(wantToRoll) : # UnRoll.
1594 # Set size (25)
1595 self.SetClientSize((self.unrolledFrameClientSize_size[0], 25))
1596 # Set to match this new state.
1597 self.isRolled = True
1598
1599 else : # Roll
1600 self.SetClientSize(self.unrolledFrameClientSize_size)
1601 # Set to match this new state.
1602 self.isRolled = False
1603
1604
1605 def OnAbout(self, event):
1606 """
1607 ...
1608 """
1609
1610 self.dialog = MyAboutDlg(self)
1611
1612
1613 def SetWindowShape(self, *evt):
1614 """
1615 ...
1616 """
1617
1618 # Use the bitmap's mask to determine the region.
1619 r = wx.Region(self.bmp)
1620 self.hasShape = self.SetShape(r)
1621
1622
1623 def OnEraseBackground(self, event):
1624 """
1625 ...
1626 """
1627
1628 dc = event.GetDC()
1629 if not dc:
1630 dc = wx.ClientDC(self)
1631 rect = self.GetUpdateRegion().GetBox()
1632 dc.SetClippingRect(rect)
1633
1634
1635 def OnDoubleClick(self, event):
1636 """
1637 ...
1638 """
1639
1640 if self.hasShape:
1641 self.SetShape(wx.Region())
1642 self.hasShape = False
1643 else:
1644 self.SetWindowShape()
1645
1646
1647 def OnLeftDown(self, event):
1648 """
1649 ...
1650 """
1651
1652 self.CaptureMouse()
1653 x, y = self.ClientToScreen(event.GetPosition())
1654 originx, originy = self.GetPosition()
1655 dx = x - originx
1656 dy = y - originy
1657 self.delta = ((dx, dy))
1658
1659
1660 def OnLeftUp(self, evt):
1661 """
1662 ...
1663 """
1664
1665 if self.HasCapture():
1666 self.ReleaseMouse()
1667
1668
1669 def OnMouseMove(self, event):
1670 """
1671 ...
1672 """
1673
1674 if event.Dragging() and event.LeftIsDown():
1675 x, y = self.ClientToScreen(event.GetPosition())
1676 fp = (x - self.delta[0], y - self.delta[1])
1677 self.Move(fp)
1678
1679
1680 def OnIconize(self, event):
1681 """
1682 ...
1683 """
1684
1685 self.Iconize()
1686
1687
1688 def OnCloseWindow(self, event):
1689 """
1690 Quit this application.
1691 """
1692
1693 # self.Destroy()
1694 self.OnTimerOut(self)
1695
1696 print("Exit application.")
1697
1698 #-------------------------------------------------------------------------------
1699
1700 class MyApp(wx.App):
1701 """
1702 Thanks to Andrea Gavana.
1703 """
1704 def OnInit(self):
1705
1706 #------------
1707
1708 self.locale = wx.Locale(wx.LANGUAGE_FRENCH)
1709
1710 #------------
1711
1712 self.SetAppName("Custom Gui 2")
1713
1714 #------------
1715
1716 self.installDir = os.path.split(os.path.abspath(sys.argv[0]))[0]
1717
1718 #------------
1719
1720 frame = MyFrame()
1721 self.SetTopWindow(frame)
1722 frame.Show(True)
1723
1724 return True
1725
1726 #---------------------------------------------------------------------------
1727
1728 def GetInstallDir(self):
1729 """
1730 Returns the installation directory for my application.
1731 """
1732
1733 return self.installDir
1734
1735
1736 def GetIconsDir(self):
1737 """
1738 Returns the icons directory for my application.
1739 """
1740
1741 icons_dir = os.path.join(self.installDir, "icons")
1742 return icons_dir
1743
1744
1745 def GetBitmapsDir(self):
1746 """
1747 Returns the bitmaps directory for my application.
1748 """
1749
1750 bitmaps_dir = os.path.join(self.installDir, "bitmaps")
1751 return bitmaps_dir
1752
1753 #-------------------------------------------------------------------------------
1754
1755 def main():
1756 app = MyApp(False)
1757 app.MainLoop()
1758
1759 #-------------------------------------------------------------------------------
1760
1761 if __name__ == "__main__" :
1762 main()
Download source
Additional Information
Link :
https://hasenj.wordpress.com/2009/04/14/making-a-fancy-window-in-wxpython/
https://fooobar.com/questions/15910813/wxpython-change-the-headers-color
https://stackoverflow.com/questions/12087140/custom-window-frame-and-window-appearance-with-wxpython
https://github.com/Metallicow/MCOW
https://github.com/Eseeme/wxpython-custom-button
- - - - -
https://wiki.wxpython.org/TitleIndex
Thanks to
Robin Dunn, Cody Precord, Andrea Gavana, Metallicow, Mike Driscoll, Ray Pasco, Pascal Faut., Vegaseat (DaniWeb), Jan Bodnar (ZetCode), Alain Delgrange, Daniel Ramos, ActiveState, the wxPython community...
Thanks also to all known contributors or anonymous that I forgot.
And finally, congratulations to the many forums and blogs for all the available examples and the help which is the strength of wxPython.
About this page
Date (d/m/y) Person (bot) Comments :
10/10/18 - Ecco (Created page for wxPython Phoenix).
Comments
- blah, blah, blah....