How to add a menu bar in the title bar (Phoenix)
Keywords : Menu bar, Shaped frame, Customized frame, Customized button, Transparency, Roll, Unroll, Fade in, Fade out, Shape, Region, BufferedPaintDC, BufferedDC, ClientDC, GCDC, AutoBufferedPaintDCFactory, AcceleratorTable.
Contents
Demonstrating (only Windows) :
Tested py3.x, wx4.x and Win10.
Are you ready to use some samples ?
Test, modify, correct, complete, improve and share your discoveries !
Frame with resize border, buttons, menu bar and dragging :
First example
1 # sample_one.py
2
3 import sys
4 import os
5 import platform
6 import wx
7 import wx.lib.fancytext as fancytext
8 import wx.lib.agw.flatmenu as FM
9 from wx.lib.agw.artmanager import ArtManager, RendererBase, DCSaver
10 from wx.lib.agw.fmresources import ControlFocus, ControlPressed
11 import wx.lib.mixins.listctrl as listmix
12 import wx.dataview as dv
13 import rectshapedbitmapbuttonTwo as SBBTwo
14 import data
15
16 musicdata = sorted(data.musicdata.items())
17 musicdata = [[str(k)] + list(v) for k,v in musicdata]
18
19 # def SwitchRGBtoBGR
20 # def CreateBackgroundBitmap
21 # class MyMenuRenderer
22 # class MyMenuBar
23 # class MyListCtrlPnl
24 # class MyStatusBar
25 # class MyTitleBar
26 # class MyAboutDlg
27 # class MyPopupMenu
28 # class MyTitleBarPnl
29 # class MyMainPnl
30 # class MyFrame
31 # class MyApp
32
33 ID_FULLSCREEN = wx.NewIdRef()
34 ID_MAIN_PNL = wx.NewIdRef()
35 ID_BTN_FULLSCREEN = wx.NewIdRef()
36 ID_BTN_ABOUT = wx.NewIdRef()
37 ID_BTN_QUIT = wx.NewIdRef()
38 ID_HELLO = wx.NewIdRef()
39
40 #---------------------------------------------------------------------------
41
42 def SwitchRGBtoBGR(colour):
43 """
44 ...
45 """
46
47 return wx.Colour(colour.Blue(), colour.Green(), colour.Red())
48
49 #---------------------------------------------------------------------------
50
51 def CreateBackgroundBitmap():
52 """
53 ...
54 """
55
56 mem_dc = wx.MemoryDC()
57 bmp = wx.Bitmap(121, 300)
58 mem_dc.SelectObject(bmp)
59
60 mem_dc.Clear()
61
62 # Colour the menu face with background colour.
63 mem_dc.SetPen(wx.Pen("#a0a0a0", 0))
64 mem_dc.SetBrush(wx.Brush("#fec54c"))
65 mem_dc.DrawRectangle(0, 15, 122, 300)
66 mem_dc.DrawLine(0, 0, 300, 0)
67
68 mem_dc.SelectObject(wx.NullBitmap)
69 return bmp
70
71 #---------------------------------------------------------------------------
72
73 class MyMenuRenderer(FM.FMRenderer):
74 """
75 Thanks to Andrea Gavana.
76 A custom renderer class for FlatMenu.
77 """
78 def __init__(self):
79 FM.FMRenderer.__init__(self)
80
81 #-----------------------------------------------------------------------
82
83 def DrawMenuButton(self, dc, rect, state):
84 """
85 Draws the highlight on a FlatMenu.
86 """
87
88 self.DrawButton(dc, rect, state)
89
90
91 def DrawMenuBarButton(self, dc, rect, state):
92 """
93 Draws the highlight on a FlatMenuBar.
94 """
95
96 self.DrawButton(dc, rect, state)
97
98
99 def DrawButton(self, dc, rect, state, colour=None):
100 """
101 ...
102 """
103
104 if state == ControlFocus:
105 penColour = SwitchRGBtoBGR(ArtManager.Get().FrameColour())
106 brushColour = SwitchRGBtoBGR(ArtManager.Get().BackgroundColour())
107 elif state == ControlPressed:
108 penColour = SwitchRGBtoBGR(ArtManager.Get().FrameColour())
109 brushColour = SwitchRGBtoBGR(ArtManager.Get().HighlightBackgroundColour())
110 else: # ControlNormal, ControlDisabled, default.
111 penColour = SwitchRGBtoBGR(ArtManager.Get().FrameColour())
112 brushColour = SwitchRGBtoBGR(ArtManager.Get().BackgroundColour())
113
114 # Draw the button borders.
115 dc = wx.GCDC(dc)
116 dc.SetPen(wx.Pen(penColour))
117 dc.SetBrush(wx.Brush(brushColour))
118 dc.DrawRoundedRectangle(rect.x, rect.y, rect.width, rect.height-3, 4)
119
120
121 def DrawMenuBarBackground(self, dc, rect):
122 """
123 ...
124 """
125
126 # For office style, we simple draw a rectangle
127 # with a gradient colouring.
128 vertical = ArtManager.Get().GetMBVerticalGradient()
129
130 dcsaver = DCSaver(dc)
131
132 # Fill with gradient.
133 startColour = self.menuBarFaceColour
134 endColour = ArtManager.Get().LightColour(startColour, 0)
135
136 dc.SetPen(wx.Pen(endColour))
137 dc.SetBrush(wx.Brush(endColour))
138 dc.DrawRectangle(rect)
139
140
141 def DrawToolBarBg(self, dc, rect):
142 """
143 ...
144 """
145
146 if not ArtManager.Get().GetRaiseToolbar():
147 return
148
149 # Fill with gradient.
150 startColour = self.menuBarFaceColour()
151 dc.SetPen(wx.Pen(startColour))
152 dc.SetBrush(wx.Brush(startColour))
153 dc.DrawRectangle(0, 0, rect.GetWidth(), rect.GetHeight())
154
155 #---------------------------------------------------------------------------
156
157 class MyMenuBar(FM.FlatMenuBar):
158 """
159 A custom renderer class for FlatMenu.
160 """
161 def __init__(self, parent):
162 FM.FlatMenuBar.__init__(self, parent,
163 id=wx.ID_ANY,
164 iconSize=32,
165 spacer=3,
166 options=FM.FM_OPT_IS_LCD)
167
168 #------------
169
170 # Return bitmaps folder.
171 self.bitmaps_dir = wx.GetApp().GetBitmapsDir()
172
173 #------------
174
175 self.parent = parent
176
177 #------------
178
179 # FM.StyleDefault or FM.Style2007
180 # FM.StyleXP or FM.StyleVista
181 self.newMyTheme = self.GetRendererManager().AddRenderer(MyMenuRenderer())
182 self.GetRendererManager().SetTheme(self.newMyTheme)
183
184 #------------
185
186 # Set an icon to the exit/help menu item.
187 exitImg = wx.Bitmap(os.path.join(self.bitmaps_dir,
188 "item_exit.png"),
189 type=wx.BITMAP_TYPE_PNG)
190
191 helpImg = wx.Bitmap(os.path.join(self.bitmaps_dir,
192 "item_about.png"),
193 type=wx.BITMAP_TYPE_PNG)
194
195 #------------
196 #------------
197
198 # File Menu.
199 self.file_menu = FM.FlatMenu()
200
201 # Create the menu items.
202 item = FM.FlatMenuItem(self.file_menu,
203 ID_FULLSCREEN,
204 "&Fullscreen\tCtrl+F",
205 "Fullscreen",
206 wx.ITEM_NORMAL,
207 None)
208 item.SetTextColour("black")
209 self.file_menu.AppendItem(item)
210 self.file_menu.AppendSeparator()
211
212
213 item = FM.FlatMenuItem(self.file_menu,
214 wx.ID_EXIT,
215 "&Quit\tCtrl+Q",
216 "Quit the program",
217 wx.ITEM_NORMAL,
218 None,
219 exitImg)
220 # Demonstrate how to set custom font
221 # and text colour to a FlatMenuItem.
222 item.SetFont(wx.Font(-1, wx.FONTFAMILY_DEFAULT,
223 wx.FONTSTYLE_NORMAL,
224 wx.FONTWEIGHT_BOLD,
225 False, ""))
226 item.SetTextColour("#d34725")
227
228 self.file_menu.AppendItem(item)
229
230 #------------
231
232 # Add Create background bitmap.
233 self.file_menu.SetBackgroundBitmap(CreateBackgroundBitmap())
234
235 #------------
236 #------------
237
238 # Help Menu.
239 self.help_menu = FM.FlatMenu()
240
241 # Create the menu items.
242 item = FM.FlatMenuItem(self.help_menu,
243 wx.ID_ABOUT,
244 "&About\tCtrl+A",
245 "About",
246 wx.ITEM_NORMAL,
247 None,
248 helpImg)
249 item.SetTextColour("black")
250 self.help_menu.AppendItem(item)
251 self.help_menu.AppendSeparator()
252
253 item = FM.FlatMenuItem(self.help_menu,
254 ID_HELLO,
255 "Hello !",
256 "Hello !",
257 wx.ITEM_NORMAL,
258 None)
259 item.SetTextColour("black")
260 self.help_menu.AppendItem(item)
261
262 #------------
263
264 # Add Create background bitmap.
265 self.help_menu.SetBackgroundBitmap(CreateBackgroundBitmap())
266
267 #------------
268 #------------
269
270 # Menu background color.
271 self.SetBackgroundColour(wx.Colour(wx.WHITE))
272
273 # Add menu to the menu bar.
274 self.Append(self.file_menu, "&File")
275 self.Append(self.help_menu, "&Help")
276
277 #------------
278
279 # Simplified init method.
280 self.SetProperties()
281
282 #-----------------------------------------------------------------------
283
284 def SetProperties(self):
285 """
286 ...
287 """
288
289 self.SetMaxSize((91, 20))
290
291 #---------------------------------------------------------------------------
292
293 class MyListCtrlPnl(wx.Panel):
294 """
295 Thanks to Robin Dunn.
296 """
297 def __init__(self, parent):
298 wx.Panel.__init__(self, parent, -1)
299
300 # Create the listctrl.
301 self.dvlc = dv.DataViewListCtrl(self,
302 style=dv.DV_ROW_LINES|
303 dv.DV_HORIZ_RULES|
304 dv.DV_VERT_RULES)
305
306 # Give it some columns.
307 # The ID col we'll customize a bit :
308 self.dvlc.AppendTextColumn("Id", width=40)
309 self.dvlc.AppendTextColumn("Artist", width=170)
310 self.dvlc.AppendTextColumn("Title", width=260)
311 self.dvlc.AppendTextColumn("Genre", width=80)
312
313 # Load the data. Each item (row) is added as a sequence
314 # of values whose order matches the columns.
315 for itemvalues in musicdata:
316 self.dvlc.AppendItem(itemvalues)
317
318 self.dvlc.SetBackgroundColour("#c9f72b")
319 self.dvlc.SetForegroundColour("black")
320
321 # Set the layout so the listctrl fills the panel.
322 self.Sizer = wx.BoxSizer()
323 self.Sizer.Add(self.dvlc, 1, wx.EXPAND)
324
325 #---------------------------------------------------------------------------
326
327 class MyStatusBar(wx.StatusBar) :
328 """
329 Thanks to ???.
330 Simple custom colorized StatusBar.
331 """
332 def __init__(self, parent, id) :
333 wx.StatusBar.__init__(self, parent, id)
334
335 #------------
336
337 # Simplified init method.
338 self.SetProperties()
339 self.BindEvents()
340
341 #-----------------------------------------------------------------------
342
343 def SetProperties(self):
344 """
345 ...
346 """
347
348 if wx.Platform == "__WXMSW__":
349 self.SetDoubleBuffered(True)
350
351
352 def BindEvents(self):
353 """
354 Bind some events to an events handler.
355 """
356
357 self.Bind(wx.EVT_PAINT, self.OnPaint)
358
359
360 def OnPaint(self, event) :
361 """
362 ...
363 """
364
365 dc = wx.BufferedPaintDC(self)
366 self.Draw(dc)
367
368
369 def Draw(self, dc) :
370 """
371 ...
372 """
373
374 dc.SetBackground(wx.Brush(wx.WHITE))
375 dc.Clear()
376
377 textVertOffset = 3 # Perfect for MSW.
378 textHorzOffset = 5 # Arbitrary - looks nicer.
379
380 dc.SetTextForeground("gray")
381 dc.DrawText(self.GetStatusText(), textHorzOffset, textVertOffset)
382
383 #---------------------------------------------------------------------------
384
385 class MyTitleBar(wx.Control):
386 """
387 Thanks to Cody Precord.
388 """
389 def __init__(self, parent, label, size):
390 style = (wx.BORDER_NONE)
391 super(MyTitleBar, self).__init__(parent,
392 style=style)
393
394 #------------
395
396 # Return bitmaps folder.
397 self.bitmaps_dir = wx.GetApp().GetBitmapsDir()
398
399 #------------
400
401 # Attributes.
402 self.parent = parent
403 self.label = label
404 self.size = size
405
406 #------------
407
408 # Simplified init method.
409 self.SetBackground()
410 self.SetProperties(label, size)
411 self.CreateMenu()
412 self.CreateCtrls()
413 self.BindEvents()
414 self.DoLayout()
415
416 #-----------------------------------------------------------------------
417
418 def SetBackground(self):
419 """
420 ...
421 """
422
423 self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
424 self.SetBackgroundColour(wx.WHITE)
425
426
427 def SetProperties(self, label, size):
428 """
429 ...
430 """
431
432 self.label = label
433 self.size = size
434
435 self.label_font = self.GetFont()
436 self.label_font.SetFamily(wx.SWISS)
437 self.label_font.SetPointSize(size)
438 self.label_font.SetWeight(wx.BOLD)
439 self.SetFont(self.label_font)
440
441
442 def CreateMenu(self):
443 """
444 ...
445 """
446
447 self.menuBar = MyMenuBar(self)
448
449
450 def CreateCtrls(self):
451 """
452 ...
453 """
454
455 w, h = self.GetSize()
456 w1, h1 = self.GetClientSize()
457
458 #------------
459
460 # Load an icon bitmap for titlebar.
461 # bmp = wx.Bitmap(os.path.join(self.bitmaps_dir,
462 # "icon_app.png"),
463 # type=wx.BITMAP_TYPE_PNG)
464
465 # self.ico = wx.StaticBitmap(self, -1, bmp)
466 # self.ico.SetBackgroundColour(wx.Colour(wx.WHITE))
467 # self.ico.SetPosition((300, 1))
468 # self.ico.SetToolTip("This is a customized icon.")
469 # self.ico.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
470
471 #------------
472
473 # Button Exit.
474 self.btn3 = SBBTwo.ShapedBitmapButton(self, -1,
475 bitmap=wx.Bitmap(os.path.join(self.bitmaps_dir,
476 "btn_gloss_exit_normal_1.png"),
477 type=wx.BITMAP_TYPE_PNG),
478
479 pressedBmp=wx.Bitmap(os.path.join(self.bitmaps_dir,
480 "btn_gloss_exit_selected_1.png"),
481 type=wx.BITMAP_TYPE_PNG),
482
483 hoverBmp=wx.Bitmap(os.path.join(self.bitmaps_dir,
484 "btn_gloss_exit_normal_1.png"),
485 type=wx.BITMAP_TYPE_PNG),
486
487 disabledBmp=wx.Bitmap(os.path.join(self.bitmaps_dir,
488 "btn_gloss_exit_normal_1.png"),
489 type=wx.BITMAP_TYPE_PNG),
490
491 label="",
492 labelForeColour=wx.WHITE,
493 labelFont=wx.Font(9,
494 wx.FONTFAMILY_DEFAULT,
495 wx.FONTSTYLE_NORMAL,
496 wx.FONTWEIGHT_BOLD),
497 style=wx.BORDER_NONE)
498
499 #------------
500
501 # Button Maximize.
502 self.btn4 = SBBTwo.ShapedBitmapButton(self, -1,
503 bitmap=wx.Bitmap(os.path.join(self.bitmaps_dir,
504 "btn_gloss_maximize_normal_1.png"),
505 type=wx.BITMAP_TYPE_PNG),
506
507 pressedBmp=wx.Bitmap(os.path.join(self.bitmaps_dir,
508 "btn_gloss_maximize_selected_1.png"),
509 type=wx.BITMAP_TYPE_PNG),
510
511 hoverBmp=wx.Bitmap(os.path.join(self.bitmaps_dir,
512 "btn_gloss_maximize_normal_1.png"),
513 type=wx.BITMAP_TYPE_PNG),
514
515 disabledBmp=wx.Bitmap(os.path.join(self.bitmaps_dir,
516 "btn_gloss_maximize_normal_1.png"),
517 type=wx.BITMAP_TYPE_PNG),
518
519 label="",
520 labelForeColour=wx.WHITE,
521 labelFont=wx.Font(9,
522 wx.FONTFAMILY_DEFAULT,
523 wx.FONTSTYLE_NORMAL,
524 wx.FONTWEIGHT_BOLD),
525 style=wx.BORDER_NONE)
526
527 #------------
528
529 # Thanks to MCOW.
530 # Button Reduce.
531 self.btn5 = SBBTwo.ShapedBitmapButton(self, -1,
532 bitmap=wx.Bitmap(os.path.join(self.bitmaps_dir,
533 "btn_gloss_reduce_normal_1.png"),
534 type=wx.BITMAP_TYPE_PNG),
535
536 pressedBmp=wx.Bitmap(os.path.join(self.bitmaps_dir,
537 "btn_gloss_reduce_selected_1.png"),
538 type=wx.BITMAP_TYPE_PNG),
539
540 hoverBmp=wx.Bitmap(os.path.join(self.bitmaps_dir,
541 "btn_gloss_reduce_normal_1.png"),
542 type=wx.BITMAP_TYPE_PNG),
543
544 disabledBmp=wx.Bitmap(os.path.join(self.bitmaps_dir,
545 "btn_gloss_reduce_normal_1.png"),
546 type=wx.BITMAP_TYPE_PNG),
547
548 label="",
549 labelForeColour=wx.WHITE,
550 labelFont=wx.Font(9,
551 wx.FONTFAMILY_DEFAULT,
552 wx.FONTSTYLE_NORMAL,
553 wx.FONTWEIGHT_BOLD),
554 style=wx.BORDER_NONE)
555
556 #------------
557
558 # Button Roll.
559 self.btn6 = SBBTwo.ShapedBitmapButton(self, -1,
560 bitmap=wx.Bitmap(os.path.join(self.bitmaps_dir,
561 "btn_gloss_roll_normal_1.png"),
562 type=wx.BITMAP_TYPE_PNG),
563
564 pressedBmp=wx.Bitmap(os.path.join(self.bitmaps_dir,
565 "btn_gloss_roll_selected_1.png"),
566 type=wx.BITMAP_TYPE_PNG),
567
568 hoverBmp=wx.Bitmap(os.path.join(self.bitmaps_dir,
569 "btn_gloss_roll_normal_1.png"),
570 type=wx.BITMAP_TYPE_PNG),
571
572 disabledBmp=wx.Bitmap(os.path.join(self.bitmaps_dir,
573 "btn_gloss_roll_normal_1.png"),
574 type=wx.BITMAP_TYPE_PNG),
575
576 label="",
577 labelForeColour=wx.WHITE,
578 labelFont=wx.Font(9,
579 wx.FONTFAMILY_DEFAULT,
580 wx.FONTSTYLE_NORMAL,
581 wx.FONTWEIGHT_BOLD),
582 style=wx.BORDER_NONE)
583
584
585 def BindEvents(self):
586 """
587 Bind some events to an events handler.
588 """
589
590 # self.ico.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown)
591 # self.ico.Bind(wx.EVT_LEFT_DOWN, self.OnRightDown)
592
593 self.Bind(wx.EVT_PAINT, self.OnPaint)
594 self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
595 self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
596
597 self.btn3.Bind(wx.EVT_BUTTON, self.OnBtnClose)
598 self.btn4.Bind(wx.EVT_BUTTON, self.OnFullScreen)
599 self.btn5.Bind(wx.EVT_BUTTON, self.OnIconfiy)
600 self.btn6.Bind(wx.EVT_BUTTON, self.OnRoll)
601
602 self.Bind(wx.EVT_MENU, self.OnFullScreen, id=ID_FULLSCREEN)
603 self.Bind(wx.EVT_MENU, self.OnBtnClose, id=wx.ID_EXIT)
604
605
606 def DoLayout(self):
607 """
608 ...
609 """
610
611
612 mainSizer = wx.BoxSizer(wx.HORIZONTAL)
613
614 #------------
615
616 mainSizer.Add(self.btn3, 0, wx.LEFT, 4)
617 mainSizer.Add(self.btn4, 0, wx.LEFT, 4)
618 mainSizer.Add(self.btn5, 0, wx.LEFT, 4)
619 mainSizer.Add(self.btn6, 0, wx.LEFT, 4)
620 mainSizer.Add((10,1), 0, wx.ALL, 0)
621 mainSizer.Add(self.menuBar, 1)
622 mainSizer.Add((20,1), 0, wx.EXPAND, 0)
623
624 #------------
625
626 self.SetSizer(mainSizer)
627 self.Layout()
628
629
630 def OnLeftDown(self, event):
631 """
632 ...
633 """
634
635 self.GetTopLevelParent().OnLeftDown(event)
636
637
638 def OnLeftUp(self, event):
639 """
640 ...
641 """
642
643 self.GetTopLevelParent().OnLeftUp(event)
644
645
646 def SetLabel(self, label):
647 """
648 ...
649 """
650
651 self.label = label
652 self.Refresh()
653
654
655 def DoGetBestSize(self):
656 """
657 ...
658 """
659
660 dc = wx.ClientDC(self)
661 dc.SetFont(self.GetFont())
662
663 textWidth, textHeight = dc.GetTextExtent(self.label)
664 spacing = 10
665 totalWidth = textWidth + (spacing)
666 totalHeight = textHeight + (spacing)
667
668 best = wx.Size(totalWidth, totalHeight)
669 self.CacheBestSize(best)
670
671 return best
672
673
674 def GetLabel(self):
675 """
676 ...
677 """
678
679 return self.label
680
681
682 def GetLabelColor(self):
683 """
684 ...
685 """
686
687 return self.foreground
688
689
690 def GetLabelSize(self):
691 """
692 ...
693 """
694
695 return self.size
696
697
698 def SetLabelColour(self, colour):
699 """
700 ...
701 """
702
703 self.labelColour = colour
704
705
706 def OnPaint(self, event):
707 """
708 ...
709 """
710
711 dc = wx.BufferedPaintDC(self)
712 gcdc = wx.GCDC(dc)
713
714 gcdc.Clear()
715
716 # Setup the GraphicsContext.
717 gc = gcdc.GetGraphicsContext()
718
719 # Get the working size we can draw in.
720 width, height = self.GetSize()
721
722 # Use the GCDC to draw the text.
723 brush = wx.WHITE
724 gcdc.SetPen(wx.Pen(brush, 1))
725 gcdc.SetBrush(wx.Brush(brush))
726 gcdc.DrawRectangle(0, 0, width, height)
727
728 # Get the system font.
729 gcdc.SetFont(self.GetFont())
730
731 textWidth, textHeight = gcdc.GetTextExtent(self.label)
732 tposx, tposy = ((width/2)-(textWidth/2), (height/3)-(textHeight/3))
733
734 tposx += 0
735 tposy += 0
736
737 # Set position and text color.
738 if tposx <= 100:
739 gcdc.SetTextForeground("white")
740 gcdc.DrawText("", int(tposx), int(tposy+1))
741
742 gcdc.SetTextForeground(self.labelColour)
743 gcdc.DrawText("", int(tposx), int(tposy))
744
745 else:
746 gcdc.SetTextForeground("white")
747 gcdc.DrawText(self.label, int(tposx), int(tposy+1))
748
749 gcdc.SetTextForeground(self.labelColour)
750 gcdc.DrawText(self.label, int(tposx), int(tposy))
751
752
753 def OnRoll(self, event):
754 """
755 ...
756 """
757
758 self.GetTopLevelParent().OnRoll(True)
759
760 print("Roll/unRoll button was clicked.")
761
762
763 def OnIconfiy(self, event):
764 """
765 ...
766 """
767
768 self.GetTopLevelParent().OnIconfiy(self)
769
770 print("Iconfiy button was clicked.")
771
772
773 def OnFullScreen(self, event):
774 """
775 ...
776 """
777
778 self.GetTopLevelParent().OnFullScreen(self)
779
780 print("FullScreen button was clicked.")
781
782
783 def OnBtnClose(self, event):
784 """
785 ...
786 """
787
788 self.GetTopLevelParent().OnCloseWindow(self)
789
790 print("Close button was clicked.")
791
792 #---------------------------------------------------------------------------
793
794 class MyAboutDlg(wx.Frame):
795 """
796 Thanks to Robin Dunn.
797 """
798 def __init__(self, parent):
799 style = (wx.FRAME_SHAPED | wx.NO_BORDER |
800 wx.CLIP_CHILDREN | wx.STAY_ON_TOP |
801 wx.SYSTEM_MENU | wx.CLOSE_BOX |
802 wx.NO_FULL_REPAINT_ON_RESIZE)
803 wx.Frame.__init__(self,
804 parent,
805 id=-1,
806 title="About...",
807 style=style)
808
809 #------------
810
811 # Attributes.
812 self.SetTransparent(0)
813 self.opacity_in = 0
814 self.opacity_out = 255
815 self.deltaN = -70
816 self.hasShape = False
817 self.delta = wx.Point(0,0)
818
819 #------------
820
821 # Return application name.
822 self.app_name = wx.GetApp().GetAppName()
823 # Return bitmaps folder.
824 self.bitmaps_dir = wx.GetApp().GetBitmapsDir()
825 # Return icons folder.
826 self.icons_dir = wx.GetApp().GetIconsDir()
827
828 #------------
829
830 # Simplified init method.
831 self.SetProperties()
832 self.OnTimerIn(self)
833 self.CreateCtrls()
834 self.BindEvents()
835
836 #------------
837
838 self.CenterOnParent(wx.BOTH)
839 self.GetParent().Enable(False)
840
841 #------------
842
843 self.Show(True)
844
845 #------------
846
847 self.eventLoop = wx.GUIEventLoop()
848 self.eventLoop.Run()
849
850 #-----------------------------------------------------------------------
851
852 def SetProperties(self):
853 """
854 Set the dialog properties (title, icon, transparency...).
855 """
856
857 frameIcon = wx.Icon(os.path.join(self.icons_dir,
858 "icon_wxWidgets.ico"),
859 type=wx.BITMAP_TYPE_ICO)
860 self.SetIcon(frameIcon)
861
862
863 def OnTimerIn(self, evt):
864 """
865 Thanks to Pascal Faut.
866 """
867
868 self.timer1 = wx.Timer(self, -1)
869 self.timer1.Start(1)
870 self.Bind(wx.EVT_TIMER, self.AlphaCycle1, self.timer1)
871
872 print("Fade-in was launched.")
873
874
875 def OnTimerOut(self, evt):
876 """
877 Thanks to Pascal Faut.
878 """
879
880 self.timer2 = wx.Timer(self, -1)
881 self.timer2.Start(1)
882 self.Bind(wx.EVT_TIMER, self.AlphaCycle2, self.timer2)
883
884 print("Fade-out was launched.")
885
886
887 def AlphaCycle1(self, *args):
888 """
889 Thanks to Pascal Faut.
890 """
891
892 self.opacity_in += self.deltaN
893 if self.opacity_in <= 0:
894 self.deltaN = -self.deltaN
895 self.opacity_in = 0
896
897 if self.opacity_in >= 255:
898 self.deltaN = -self.deltaN
899 self.opacity_in = 255
900
901 self.timer1.Stop()
902
903 self.SetTransparent(self.opacity_in)
904
905 print("Fade in = {}/255".format(self.opacity_in))
906
907
908 def AlphaCycle2(self, *args):
909 """
910 Thanks to Pascal Faut.
911 """
912
913 self.opacity_out += self.deltaN
914 if self.opacity_out >= 255:
915 self.deltaN = -self.deltaN
916 self.opacity_out = 255
917
918 if self.opacity_out <= 0:
919 self.deltaN = -self.deltaN
920 self.opacity_out = 0
921
922 self.timer2.Stop()
923
924 wx.CallAfter(self.Destroy)
925
926 self.SetTransparent(self.opacity_out)
927
928 print("Fade out = {}/255".format(self.opacity_out))
929
930
931 def CreateCtrls(self):
932 """
933 Make widgets for my dialog.
934 """
935
936 # Load a background bitmap.
937 self.bmp = wx.Bitmap(os.path.join(self.bitmaps_dir,
938 "skin_about.png"),
939 type=wx.BITMAP_TYPE_PNG)
940 mask = wx.Mask(self.bmp, wx.RED)
941 self.bmp.SetMask(mask)
942
943 #------------
944
945 self.SetClientSize((self.bmp.GetWidth(), self.bmp.GetHeight()))
946
947 #------------
948
949 if wx.Platform == "__WXGTK__":
950 # wxGTK requires that the window be created before you can
951 # set its shape, so delay the call to SetWindowShape until
952 # this event.
953 self.Bind(wx.EVT_WINDOW_CREATE, self.SetWindowShape)
954 else:
955 # On wxMSW and wxMac the window has already
956 # been created, so go for it.
957 self.SetWindowShape()
958
959
960 def BindEvents(self):
961 """
962 Bind all the events related to my dialog.
963 """
964
965 # Bind some events to an events handler.
966 self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
967 self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
968 self.Bind(wx.EVT_RIGHT_UP, self.OnCloseWindow) # Panel right clic.
969 self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)
970 self.Bind(wx.EVT_WINDOW_CREATE, self.SetWindowShape)
971 self.Bind(wx.EVT_MOTION, self.OnMouseMove)
972 self.Bind(wx.EVT_KEY_UP, self.OnKeyUp)
973 self.Bind(wx.EVT_PAINT, self.OnPaint)
974 self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
975
976
977 def SetWindowShape(self, event=None):
978 """
979 ...
980 """
981
982 # Use the bitmap's mask to determine the region.
983 r = wx.Region(self.bmp)
984 self.hasShape = self.SetShape(r)
985
986
987 def OnEraseBackground(self, event):
988 """
989 ...
990 """
991
992 dc = event.GetDC()
993 if not dc:
994 dc = wx.ClientDC(self)
995 rect = self.GetUpdateRegion().GetBox()
996 dc.SetClippingRect(rect)
997
998
999 def OnLeftDown(self, event):
1000 """
1001 ...
1002 """
1003
1004 self.CaptureMouse()
1005 x, y = self.ClientToScreen(event.GetPosition())
1006 originx, originy = self.GetPosition()
1007 dx = x - originx
1008 dy = y - originy
1009 self.delta = ((dx, dy))
1010
1011
1012 def OnLeftUp(self, evt):
1013 """
1014 ...
1015 """
1016
1017 if self.HasCapture():
1018 self.ReleaseMouse()
1019
1020
1021 def OnMouseMove(self, event):
1022 """
1023 ...
1024 """
1025
1026 if event.Dragging() and event.LeftIsDown():
1027 x, y = self.ClientToScreen(event.GetPosition())
1028 fp = (x - self.delta[0], y - self.delta[1])
1029 self.Move(fp)
1030
1031
1032 def OnPaint(self, event):
1033 """
1034 ...
1035 """
1036
1037 dc = wx.AutoBufferedPaintDCFactory(self)
1038 dc.DrawBitmap(self.bmp, 0, 0, True)
1039
1040 #------------
1041
1042 # These are strings.
1043 py_version = sys.version.split()[0]
1044
1045 str1 = (('<font style="normal" family="default" color="grey" size="10" weight="bold">'
1046 'Programming : </font>'
1047 '<font style="normal" family="default" color="black" size="10" weight="normal">'
1048 'Python {}</font>').format(py_version)) # Python 3.7.2
1049
1050 str2 = (('<font style="normal" family="default" color="red" size="10" weight="bold">'
1051 'GUI toolkit : </font>'
1052 '<font style="normal" family="default" color="black" size="10" weight="normal">'
1053 'wxPython {}</font>').format(wx.VERSION_STRING)) # wxPython 4.0.4
1054
1055 str3 = (('<font style="normal" family="default" color="brown" size="10" weight="bold">'
1056 'Library : </font>'
1057 '<font style="normal" family="default" color="black" size="10" weight="normal">'
1058 '{}</font>').format(wx.GetLibraryVersionInfo().VersionString)) # wxWidgets 3.0.5
1059
1060 str4 = (('<font style="normal" family="default" color="blue" size="10" weight="bold">'
1061 'Operating system : </font>'
1062 '<font style="normal" family="default" color="black" size="10" weight="normal">'
1063 '{}</font>').format(platform.system())) # Windows
1064
1065 str5 = (('<font style="normal" family="default" color="gray" size="9" weight="normal">'
1066 '{}</font>').format(self.app_name)) # Custom Gui 4
1067
1068 str6 = (('<font style="normal" family="default" color="black" size="8" weight="normal">'
1069 'Right clic or Esc for Exit</font>'))
1070
1071 #------------
1072
1073 # Return image size.
1074 bw, bh = self.bmp.GetWidth(), self.bmp.GetHeight()
1075
1076 # Draw text.
1077 # Need width to calculate x position of str1.
1078 tw, th = fancytext.GetExtent(str1, dc)
1079 # Centered text.
1080 fancytext.RenderToDC(str1, dc, (bw-tw)/2, 30)
1081
1082 #------------
1083
1084 # Need width to calculate x position of str2.
1085 tw, th = fancytext.GetExtent(str2, dc)
1086 # Centered text.
1087 fancytext.RenderToDC(str2, dc, (bw-tw)/2, 50)
1088
1089 #------------
1090
1091 # Need width to calculate x position of str3.
1092 tw, th = fancytext.GetExtent(str3, dc)
1093 # Centered text.
1094 fancytext.RenderToDC(str3, dc, (bw-tw)/2, 70)
1095
1096 #------------
1097
1098 # Need width to calculate x position of str4.
1099 tw, th = fancytext.GetExtent(str4, dc)
1100 # Centered text.
1101 fancytext.RenderToDC(str4, dc, (bw-tw)/2, 90)
1102
1103 #------------
1104
1105 # Need width to calculate x position of str5.
1106 tw, th = fancytext.GetExtent(str5, dc)
1107 # Centered text.
1108 fancytext.RenderToDC(str5, dc, (bw-tw)/2, 130)
1109
1110 #------------
1111
1112 # Need width to calculate x position of str6.
1113 tw, th = fancytext.GetExtent(str6, dc)
1114 # Centered text.
1115 fancytext.RenderToDC(str6, dc, (bw-tw)/2, 195)
1116
1117
1118 def OnKeyUp(self, event):
1119 """
1120 ...
1121 """
1122
1123 if event.GetKeyCode() == wx.WXK_ESCAPE:
1124 self.OnCloseWindow(event)
1125
1126 event.Skip()
1127
1128
1129 def OnCloseWindow(self, event):
1130 """
1131 ...
1132 """
1133
1134 self.GetParent().Enable(True)
1135 self.eventLoop.Exit()
1136 self.Destroy()
1137
1138 #---------------------------------------------------------------------------
1139
1140 class MyPopupMenu(wx.Menu):
1141 """
1142 Thanks to Robin Dunn.
1143 """
1144 def __init__(self, parent):
1145 wx.Menu.__init__(self)
1146
1147 #------------
1148
1149 # Attributes.
1150 self.parent = parent
1151
1152 #------------
1153
1154 # Returns bitmaps folder.
1155 self.bitmaps_dir = wx.GetApp().GetBitmapsDir()
1156
1157 #------------
1158
1159 # Simplified init method.
1160 self.CreatePopupMenu()
1161 self.BindEvents()
1162
1163 #-----------------------------------------------------------------------
1164
1165 def CreatePopupMenu(self, event=None):
1166 """
1167 This method is called by the base class when it needs to popup
1168 the menu for the default EVT_RIGHT_DOWN event. Just create
1169 the menu how you want it and return it from this function,
1170 the base class takes care of the rest.
1171 """
1172
1173 bmp = wx.Bitmap(os.path.join(self.bitmaps_dir,
1174 "item_about.png"),
1175 type=wx.BITMAP_TYPE_PNG)
1176
1177 item = wx.MenuItem(self, id=wx.ID_ABOUT, text=" About")
1178 item.SetBitmap(bmp)
1179 self.Append(item)
1180 self.AppendSeparator()
1181
1182 #------------
1183
1184 bmp = wx.Bitmap(os.path.join(self.bitmaps_dir,
1185 "item_exit.png"),
1186 type=wx.BITMAP_TYPE_PNG)
1187
1188 if True or "__WXMSW__" in wx.PlatformInfo:
1189 font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)
1190 font.SetWeight(wx.BOLD)
1191
1192 item = wx.MenuItem(self, id=wx.ID_EXIT, text=" Exit")
1193 item.SetBitmap(bmp)
1194 item.SetFont(font)
1195 self.Append(item)
1196
1197 return self
1198
1199
1200 def BindEvents(self):
1201 """
1202 Bind some events to an events handler.
1203 """
1204
1205 # Bind the menu events to an events handler.
1206 self.Bind(wx.EVT_MENU, self.OnAbout, id=wx.ID_ABOUT)
1207 self.Bind(wx.EVT_MENU, self.OnClose, id=wx.ID_EXIT)
1208
1209
1210 def OnAbout(self, event):
1211 """
1212 ...
1213 """
1214
1215 self.mainFrame = wx.GetApp().GetTopWindow()
1216 self.mainFrame.OnAbout(self)
1217
1218 print("About icon was clicked.")
1219
1220
1221 def OnClose(self, event):
1222 """
1223 ...
1224 """
1225
1226 self.mainFrame = wx.GetApp().GetTopWindow()
1227 self.mainFrame.OnCloseWindow(self)
1228
1229 print("Close icon was clicked.")
1230
1231 #---------------------------------------------------------------------------
1232
1233 class MyTitleBarPnl(wx.Panel):
1234 """
1235 Thanks to Cody Precord.
1236 """
1237 def __init__(self, parent, id, size):
1238 style = (wx.NO_BORDER)
1239 super(MyTitleBarPnl, self).__init__(parent,
1240 id,
1241 size=size,
1242 style=style)
1243
1244 #------------
1245
1246 # Attributes.
1247 self.parent = parent
1248
1249 #------------
1250
1251 # Return application name.
1252 self.app_name = wx.GetApp().GetAppName()
1253 # Return bitmaps folder.
1254 self.bitmaps_dir = wx.GetApp().GetBitmapsDir()
1255
1256 #------------
1257
1258 # Simplified init method.
1259 self.SetProperties()
1260 self.CreateCtrls()
1261 self.BindEvents()
1262
1263 #-----------------------------------------------------------------------
1264
1265 def SetProperties(self):
1266 """
1267 ...
1268 """
1269
1270 self.SetBackgroundColour(wx.WHITE)
1271
1272
1273 def CreateCtrls(self):
1274 """
1275 ...
1276 """
1277
1278 w, h = self.GetClientSize()
1279 print("MyTitleBarPnl :", self.GetClientSize())
1280
1281 #------------
1282 #------------
1283
1284 # Add titleBar.
1285 self.titleBar = MyTitleBar(self,
1286 label=self.app_name,
1287 size=10)
1288 self.titleBar.SetPosition((0, 0))
1289 self.titleBar.SetSize((w, 24))
1290 self.titleBar.SetLabelColour("black")
1291 self.titleBar.SetToolTip("This is a customized title bar.")
1292
1293
1294 def BindEvents(self):
1295 """
1296 Bind some events to an events handler.
1297 """
1298
1299 self.Bind(wx.EVT_SIZE, self.OnResize)
1300
1301
1302 def OnResize(self, event):
1303 """
1304 ...
1305 """
1306
1307 w, h = self.GetClientSize()
1308 print("MyTitleBarPnl :", self.GetClientSize())
1309
1310 #------------
1311 #------------
1312
1313 self.titleBar.SetSize((w, 24))
1314
1315 #------------
1316
1317 self.Refresh()
1318
1319 print("On resize was clicked.")
1320
1321 #---------------------------------------------------------------------------
1322
1323 class MyMainPnl(wx.Panel):
1324 """
1325 ...
1326 """
1327 def __init__(self, parent, id, size):
1328 style = (wx.NO_BORDER | wx.TAB_TRAVERSAL)
1329 super(MyMainPnl, self).__init__(parent,
1330 id=int(ID_MAIN_PNL),
1331 size=size,
1332 style=style)
1333
1334 #------------
1335
1336 # Attributes.
1337 self.parent = parent
1338
1339 #------------
1340
1341 # Simplified init method.
1342 self.CreateCtrls()
1343 self.BindEvents()
1344 self.DoLayout()
1345
1346 #-----------------------------------------------------------------------
1347
1348 def CreateCtrls(self):
1349 """
1350 ...
1351 """
1352
1353 w, h = self.GetClientSize()
1354 print("MyMainPnl :", self.GetClientSize())
1355
1356 #------------
1357 #------------
1358
1359 font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)
1360 font.SetWeight(wx.BOLD)
1361
1362 #------------
1363 #------------
1364
1365 # Create data view control.
1366 self.list = MyListCtrlPnl(self)
1367
1368 #------------
1369 #------------
1370
1371 self.line = wx.StaticLine(self, -1,
1372 pos=(0, 70),
1373 size=(-1, -1),
1374 style=wx.LI_HORIZONTAL)
1375
1376
1377 def DoLayout(self):
1378 """
1379 ...
1380 """
1381
1382 txtSizer = wx.BoxSizer(wx.VERTICAL)
1383
1384 sizerList = wx.BoxSizer(wx.VERTICAL)
1385 sizerList.Add(self.list, 1,
1386 wx.LEFT|wx.TOP|wx.BOTTOM|
1387 wx.EXPAND|wx.ALIGN_TOP, 0)
1388
1389 sizer = wx.BoxSizer(wx.VERTICAL)
1390 sizer.Add(txtSizer, 0, wx.BOTTOM, 15)
1391 sizer.Add(self.line, 0, wx.EXPAND|wx.ALL, 10)
1392
1393 mainSizer = wx.BoxSizer(wx.HORIZONTAL)
1394 mainSizer.Add(sizerList, 1,
1395 wx.LEFT|wx.TOP|wx.BOTTOM|wx.EXPAND, 0)
1396 mainSizer.Add(sizer, 0, wx.ALIGN_BOTTOM|wx.ALL, 0)
1397
1398 self.SetSizer(mainSizer)
1399 self.Layout()
1400
1401
1402 def BindEvents(self):
1403 """
1404 Bind some events to an events handler.
1405 """
1406
1407 self.Bind(wx.EVT_ENTER_WINDOW, self.OnInfo, id=ID_MAIN_PNL)
1408
1409
1410 def OnInfo(self, event):
1411 """
1412 ...
1413 """
1414
1415 event_id = event.GetId()
1416
1417 if event_id == ID_MAIN_PNL:
1418 self.GetParent().SetStatusText(text="Hello world !")
1419
1420 else:
1421 # Tell the event system to continue
1422 # looking for an event handler, so the
1423 # default handler will get called.
1424 event.Skip()
1425
1426
1427 def OnAbout(self, event):
1428 """
1429 ...
1430 """
1431
1432 self.GetParent().OnAbout(self)
1433
1434 print("FullScreen button was clicked.")
1435
1436
1437 def OnFullScreen(self, event):
1438 """
1439 ...
1440 """
1441
1442 self.GetParent().OnFullScreen(self)
1443
1444 print("FullScreen button was clicked.")
1445
1446
1447 def OnBtnClose(self, event):
1448 """
1449 ...
1450 """
1451
1452 self.GetParent().OnCloseWindow(self)
1453
1454 print("Close button was clicked.")
1455
1456 #---------------------------------------------------------------------------
1457
1458 class MyFrame(wx.Frame):
1459 """
1460 Thanks to Robin Dunn.
1461 """
1462 def __init__(self):
1463 style = (wx.CLIP_CHILDREN | wx.CLOSE_BOX |
1464 wx.MINIMIZE_BOX | wx.SYSTEM_MENU |
1465 wx.RESIZE_BORDER | wx.NO_FULL_REPAINT_ON_RESIZE|
1466 wx.STAY_ON_TOP)
1467 super(MyFrame, self).__init__(None,
1468 -1,
1469 title="",
1470 style=style)
1471
1472 #------------
1473
1474 wx.SystemOptions.SetOption("msw.remap", "0")
1475
1476 #------------
1477
1478 # Attributes.
1479 self.SetTransparent(0)
1480 self.opacity_in = 0
1481 self.opacity_out = 255
1482 self.deltaN = -70
1483 self.delta = wx.Point(0,0)
1484
1485 #------------
1486
1487 # Return application name.
1488 self.app_name = wx.GetApp().GetAppName()
1489 # Return bitmaps folder.
1490 self.bitmaps_dir = wx.GetApp().GetBitmapsDir()
1491 # Return icons folder.
1492 self.icons_dir = wx.GetApp().GetIconsDir()
1493
1494 #------------
1495
1496 # Simplified init method.
1497 self.SetProperties()
1498 self.OnTimerIn(self)
1499 self.AcceleratorTable()
1500 self.CreateStatusBar()
1501 self.CreateCtrls()
1502 self.BindEvents()
1503 self.DoLayout()
1504
1505 #------------
1506
1507 # Thanks to Ray Pasco.
1508 # Initialize to the current state.
1509 self.unrolledFrameClientSize_size = self.GetClientSize()
1510 self.isRolled = False
1511
1512 #------------
1513
1514 self.CenterOnScreen(wx.BOTH)
1515
1516 #------------
1517
1518 self.Show(True)
1519
1520 #-----------------------------------------------------------------------
1521
1522 def SetProperties(self):
1523 """
1524 ...
1525 """
1526
1527 self.SetBackgroundColour(wx.Colour(wx.WHITE))
1528 self.SetTitle(self.app_name)
1529 self.SetClientSize((600, 380))
1530 self.SetMinSize((128, 60))
1531
1532 #------------
1533
1534 frameIcon = wx.Icon(os.path.join(self.icons_dir,
1535 "icon_wxWidgets.ico"),
1536 type=wx.BITMAP_TYPE_ICO)
1537 self.SetIcon(frameIcon)
1538
1539
1540 def OnTimerIn(self, evt):
1541 """
1542 Thanks to Pascal Faut.
1543 """
1544
1545 self.timer1 = wx.Timer(self, -1)
1546 self.timer1.Start(1)
1547 self.Bind(wx.EVT_TIMER, self.AlphaCycle1, self.timer1)
1548
1549 print("Fade-in was launched.")
1550
1551
1552 def OnTimerOut(self, evt):
1553 """
1554 Thanks to Pascal Faut.
1555 """
1556
1557 self.timer2 = wx.Timer(self, -1)
1558 self.timer2.Start(1)
1559 self.Bind(wx.EVT_TIMER, self.AlphaCycle2, self.timer2)
1560
1561 print("Fade-out was launched.")
1562
1563
1564 def AlphaCycle1(self, *args):
1565 """
1566 Thanks to Pascal Faut.
1567 """
1568
1569 self.opacity_in += self.deltaN
1570 if self.opacity_in <= 0:
1571 self.deltaN = -self.deltaN
1572 self.opacity_in = 0
1573
1574 if self.opacity_in >= 255:
1575 self.deltaN = -self.deltaN
1576 self.opacity_in = 255
1577
1578 self.timer1.Stop()
1579
1580 self.SetTransparent(self.opacity_in)
1581
1582 print("Fade in = {}/255".format(self.opacity_in))
1583
1584
1585 def AlphaCycle2(self, *args):
1586 """
1587 Thanks to Pascal Faut.
1588 """
1589
1590 self.opacity_out += self.deltaN
1591 if self.opacity_out >= 255:
1592 self.deltaN = -self.deltaN
1593 self.opacity_out = 255
1594
1595 if self.opacity_out <= 0:
1596 self.deltaN = -self.deltaN
1597 self.opacity_out = 0
1598
1599 self.timer2.Stop()
1600 wx.CallAfter(self.Destroy)
1601 wx.Exit()
1602
1603 self.SetTransparent(self.opacity_out)
1604
1605 print("Fade out = {}/255".format(self.opacity_out))
1606
1607
1608 def AcceleratorTable(self):
1609 """
1610 ...
1611 """
1612
1613 table = wx.AcceleratorTable([(wx.ACCEL_CTRL, ord('F'), ID_FULLSCREEN),
1614 (wx.ACCEL_CTRL, ord('Q'), wx.ID_EXIT),
1615 (wx.ACCEL_CTRL, ord('A'), wx.ID_ABOUT),
1616 ])
1617 self.SetAcceleratorTable(table)
1618
1619
1620 def CreateStatusBar(self):
1621 """
1622 ...
1623 """
1624
1625 self.sb = MyStatusBar(self, -1)
1626 self.sb.SetBackgroundColour(wx.Colour(wx.WHITE))
1627 self.sb.SetStatusText("Hello world !")
1628
1629 self.SetStatusBar(self.sb)
1630
1631
1632 def CreateCtrls(self):
1633 """
1634 ...
1635 """
1636
1637 w, h = self.GetClientSize()
1638 print("MyFrame :", self.GetClientSize())
1639
1640 #------------
1641 #------------
1642
1643 self.titleBarPnl = MyTitleBarPnl(self, -1, (w, 24))
1644 self.titleBarPnl.SetPosition((0, 0))
1645 print("self.titleBarPnl :", self.titleBarPnl.GetSize())
1646
1647 #------------
1648
1649 # self.line = wx.StaticLine(self, -1,
1650 # pos=(0, 70),
1651 # size=(-1, -1),
1652 # style=wx.LI_HORIZONTAL)
1653
1654 #------------
1655
1656 self.mainPnl = MyMainPnl(self, -1, (w, h-25))
1657 self.mainPnl.SetPosition((0, 25))
1658 print("self.mainPnl :", self.mainPnl.GetSize())
1659
1660
1661 def BindEvents(self):
1662 """
1663 ...
1664 """
1665
1666 self.titleBarPnl.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
1667
1668 self.Bind(wx.EVT_SIZE, self.OnResize)
1669 self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
1670 self.Bind(wx.EVT_MOTION, self.OnMouseMove)
1671 self.Bind(wx.EVT_CHAR_HOOK, self.OnKeyUp)
1672 self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
1673
1674 self.Bind(wx.EVT_MENU, self.OnFullScreen, id=ID_FULLSCREEN)
1675 self.Bind(wx.EVT_MENU, self.OnAbout, id=wx.ID_ABOUT)
1676 self.Bind(wx.EVT_MENU, self.OnCloseWindow, id=wx.ID_EXIT)
1677
1678
1679 def DoLayout(self):
1680 """
1681 ...
1682 """
1683
1684 # MainSizer is the top-level one that manages everything.
1685 mainSizer = wx.BoxSizer(wx.VERTICAL)
1686
1687 mainSizer.Add(self.titleBarPnl, 1, wx.EXPAND, 0)
1688 # mainSizer.Add(self.line, 0, wx.EXPAND, 0)
1689 mainSizer.Add(self.mainPnl, 1, wx.EXPAND, 0)
1690
1691 # Finally, tell the panel to use the sizer for layout.
1692 self.SetSizer(mainSizer)
1693 self.Layout()
1694
1695
1696 def OnRoll(self, event) :
1697 """
1698 Thanks to Ray Pasco.
1699 """
1700
1701 if not bool(self.isRolled) :
1702 # Set the flag to the state we want regardless of whether
1703 # or not it's in currently in the opposite state.
1704 self.RollUnRoll(wantToRoll=True)
1705
1706 elif self.isRolled : # UnRoll.
1707 # Set the flag to the state we want regardless of whether
1708 # or not it's in currently in the opposite state.
1709 self.RollUnRoll(wantToRoll=False)
1710
1711 print("OnRoll :", self.GetClientSize())
1712
1713
1714 def RollUnRoll(self, wantToRoll) :
1715 """
1716 Thanks to Ray Pasco.
1717 """
1718
1719 # Save the current size only if the Frame is not rolled up.
1720 if not bool(self.isRolled) :
1721 self.unrolledFrameClientSize_size = self.GetClientSize()
1722
1723 if bool(wantToRoll) : # UnRoll.
1724 # Set size (25).
1725 self.SetClientSize((self.unrolledFrameClientSize_size[0], 25))
1726 # Set to match this new state.
1727 self.isRolled = True
1728
1729 else : # Roll
1730 self.SetClientSize(self.unrolledFrameClientSize_size)
1731 # Set to match this new state.
1732 self.isRolled = False
1733
1734 print("RollUnRoll :", self.GetClientSize())
1735
1736
1737 def OnAbout(self, event):
1738 """
1739 ...
1740 """
1741
1742 self.dialog = MyAboutDlg(self)
1743
1744
1745 def OnLeftDown(self, event):
1746 """
1747 ...
1748 """
1749
1750 self.CaptureMouse()
1751 x, y = self.ClientToScreen(event.GetPosition())
1752 originx, originy = self.GetPosition()
1753 dx = x - originx
1754 dy = y - originy
1755 self.delta = ((dx, dy))
1756
1757
1758 def OnLeftUp(self, evt):
1759 """
1760 ...
1761 """
1762
1763 if self.HasCapture():
1764 self.ReleaseMouse()
1765
1766
1767 def OnMouseMove(self, event):
1768 """
1769 ...
1770 """
1771
1772 if event.Dragging() and event.LeftIsDown():
1773 x, y = self.ClientToScreen(event.GetPosition())
1774 fp = (x - self.delta[0], y - self.delta[1])
1775 self.Move(fp)
1776
1777
1778 def OnIconfiy(self, event):
1779 """
1780 ...
1781 """
1782
1783 self.Iconize()
1784
1785
1786 def OnResize(self, event):
1787 """
1788 ...
1789 """
1790
1791 w, h = self.GetClientSize()
1792 print("self :", self.GetClientSize())
1793
1794 #------------
1795 #------------
1796
1797 self.titleBarPnl.SetSize((w, 24))
1798 # self.line.SetSize((w, -1))
1799 self.mainPnl.SetSize((w, h-25)) # 25
1800
1801 #------------
1802
1803 self.Refresh()
1804
1805
1806 def OnFullScreen(self, event):
1807 """
1808 ...
1809 """
1810
1811 self.ShowFullScreen(not self.IsFullScreen(),
1812 wx.FULLSCREEN_NOCAPTION)
1813
1814
1815 def OnKeyUp(self, event):
1816 """
1817 ...
1818 """
1819
1820 if event.GetKeyCode() == wx.WXK_ESCAPE:
1821 # Close the frame, no action.
1822 self.OnCloseWindow(event)
1823 sys.exit()
1824 event.Skip()
1825
1826
1827 def OnBtnClose(self, event):
1828 """
1829 ...
1830 """
1831
1832 self.Close()
1833
1834
1835 def OnCloseWindow(self, event):
1836 """
1837 Quit this application.
1838 """
1839
1840 # self.Destroy()
1841 self.OnTimerOut(self)
1842
1843 print("Exit application.")
1844
1845 #---------------------------------------------------------------------------
1846
1847 class MyApp(wx.App):
1848 """
1849 Thanks to Andrea Gavana.
1850 """
1851 def OnInit(self):
1852
1853 #------------
1854
1855 self.locale = wx.Locale(wx.LANGUAGE_ENGLISH)
1856
1857 #------------
1858
1859 self.SetAppName("Custom Gui 1")
1860
1861 #------------
1862
1863 self.installDir = os.path.split(os.path.abspath(sys.argv[0]))[0]
1864
1865 #------------
1866
1867 frame = MyFrame()
1868 self.SetTopWindow(frame)
1869 frame.Show(True)
1870
1871 return True
1872
1873 #-----------------------------------------------------------------------
1874
1875 def GetInstallDir(self):
1876 """
1877 Returns the installation directory for my application.
1878 """
1879
1880 return self.installDir
1881
1882
1883 def GetIconsDir(self):
1884 """
1885 Returns the icons directory for my application.
1886 """
1887
1888 icons_dir = os.path.join(self.installDir, "icons")
1889 return icons_dir
1890
1891
1892 def GetBitmapsDir(self):
1893 """
1894 Returns the bitmaps directory for my application.
1895 """
1896
1897 bitmaps_dir = os.path.join(self.installDir, "bitmaps")
1898 return bitmaps_dir
1899
1900 #---------------------------------------------------------------------------
1901
1902 def main():
1903 app = MyApp(False)
1904 app.MainLoop()
1905
1906 #---------------------------------------------------------------------------
1907
1908 if __name__ == "__main__" :
1909 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, 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 :
08/05/21 - Ecco (Created page for wxPython Phoenix).
08/08/22 - Ecco (Updated for Python 3.10.5).
Comments
- blah, blah, blah....