= How to create a Tip of the day frame (Phoenix) = '''Keywords :''' Tip of the Day, CreateFileTipProvider, ShowTip, TipProvider, Dialog, Option. <<TableOfContents>> -------- = Introduction = "Tip of the day" is easily implemented with the wxCreateFileTipProvider function and a text file full of tips. Your application will need: * Some sort of persistence to remember whether tips are being shown and which tip will be shown next. For this recipe, I'm just referring to {{{self.Persist}}}, but I am not illustrating how {{{self.Persist}}} is created, saved, or restored. You should also include: * A settings panel that allows the user to turn the tips on/off, or a menu option for showing a tip of the day. Otherwise, if the user turns the tips off, they will not be able to turn them back on again! -------- = The Recipe = First, create a text file ({{{tips.txt}}}) with helpful tips in it. Lines that begin with a "#" will be treated as comments: {{{ # Dental hygene tips: Brush your teeth three times a day. Floss every day. An apple a day keeps the doctor away. }}} In your frame's intialization, create a tip provider: {{{#!python self.TipOfTheDay = wx.CreateFileTipProvider("tips.txt", self.Persist.TipOfTheDayIndex) if self.Persist.ShowTotD: wx.CallAfter(self.ShowTipOfTheDay) }}} Note that I'm doing a {{{wx.CallAfter}}} so that the initialization process doesn't grind to a halt while waiting for the user to dismiss the tip. The {{{ShowTipOfTheDay}}} function is: {{{#!python def ShowTipOfTheDay(self): self.Persist.ShowTotD = wx.ShowTip(self, self.TipOfTheDay, self.Persist.ShowTotD) }}} Finally, when my application is shutting down, I recapture the current tip number so that the tips will pick up from where they left off on the next run. {{{#!python self.Persist.TipOfTheDayIndex = self.TipOfTheDay.CurrentTip }}} That {{{CurrentTip}}} member doesn't appear to be documented in the help files, but it does seem to do the trick. -------- = Demonstrating : = __'''''Tested''' py3.x, wx4.x and Win10. ''__ Are you ready to use some samples ? ;) Test, modify, correct, complete, improve and share your discoveries ! (!) -------- == Here's a complete example of using == {{attachment:img_sample_one.png}} {{{#!python # sample_one.py import sys import os import wx from wx.adv import CreateFileTipProvider from wx.adv import ShowTip from wx.adv import TipProvider # class MyTipOption # class MyFrame # class MyApp app_dir = os.path.split(os.path.abspath(sys.argv[0]))[0] config_file = os.path.join(app_dir, "options.cfg") #----------------------------------------------------- class MyTipOption(wx.Dialog): def __init__(self, parent): wx.Dialog.__init__(self, parent, -1, title="Option tips") self.Bind(wx.EVT_CLOSE, self.on_close_window) #------------------- config = GetConfig() self.checkBox = wx.CheckBox(self, -1, label="Show tips at start up", pos=(20, 20)) self.checkBox.SetValue(config.ReadInt("ShowTips", 0)) content = self.checkBox.GetValue() print("CheckBox = %s" % (content)) self.btnClose = wx.Button(self, -1, label="&Close", pos=(20, 120), size=(100, 30)) self.checkBox.Bind(wx.EVT_CHECKBOX, self.on_check_box) self.Bind(wx.EVT_BUTTON, self.on_close_btn, self.btnClose) #------------------- self.CentreOnParent(wx.BOTH) #------------------- self.btnClose = self.ShowModal() self.Close() #------------------------ def on_check_box(self, event): config = GetConfig() config.WriteInt("ShowTips", self.checkBox.GetValue()) content = self.checkBox.GetValue() print("CheckBox = %s" % (content)) def on_close_btn(self, event): self.Close(True) def on_close_window(self, event): self.Destroy() #----------------------------------------------------- class MyFrame(wx.Frame): def __init__(self, parent, id, title): wx.Frame.__init__(self, parent, -1, title) #------------------- frameicon = wx.Icon("Icons/wxWidgets.ico") self.SetIcon(frameicon) #------------------- self.Bind(wx.EVT_CLOSE, self.on_close_window) #------------------- self.panel = wx.Panel(self, -1) self.btnTip = wx.Button(self.panel, -1, label="Show &tip setting dialog", pos=(20, 20), size=(230, 30)) self.btnClose = wx.Button(self.panel, -1, label="&Quit", pos=(20, 100), size=(100, 30)) self.Bind(wx.EVT_BUTTON, self.on_tip_btn, self.btnTip) self.Bind(wx.EVT_BUTTON, self.on_close_btn, self.btnClose) #------------------- # Simplified init method self.create_menu_bar() #------------------- self.CenterOnScreen() #------------------------ def create_menu_bar(self): menuBar = wx.MenuBar() menuFile = wx.Menu(style=wx.MENU_TEAROFF) item = wx.MenuItem(menuFile, -1, text="&Quit\tCtrl+Q", helpString="Quit application.") menuFile.Append(item) self.Bind(wx.EVT_MENU, self.on_close_btn, item) menuOption = wx.Menu(style=wx.MENU_TEAROFF) item = wx.MenuItem(menuOption, -1, text="&Tip\tCtrl+K", helpString="Show or hide tip at start up.") menuOption.Append(item) self.Bind(wx.EVT_MENU, self.on_tip_btn, item) menuBar.Append(menuFile, title="&File") menuBar.Append(menuOption, title="&Option") self.SetMenuBar(menuBar) def show_tip(self): config = GetConfig() # Tip status (show or hide) showTip = config.ReadInt("ShowTips", 1) if showTip == 1 : print("Show tip = %s" % (True)) elif showTip == 0 : print("Show tip = %s" % (False)) index = config.ReadInt("TipIndex", 0) print("Index = %s" % (index)) if showTip: tipProvider = CreateFileTipProvider("tips.txt", index) showTip = ShowTip(self, tipProvider) index = tipProvider.GetCurrentTip() config.WriteInt("ShowTips", showTip) config.WriteInt("TipIndex", index) def on_tip_btn(self, event): self.tip = MyTipOption(self) def on_close_btn(self, event): self.Close(True) def on_close_window(self, event): self.Destroy() #----------------------------------------------------- class MyApp(wx.App): def OnInit(self): self.SetAppName("Test_Tip") frame = MyFrame(None, -1, "Test show tip at start up") frame.Show(True) self.SetTopWindow(frame) if os.path.exists("tips.txt"): wx.CallAfter(frame.show_tip) return True #----------------------------------------------------- def GetConfig(): config = wx.FileConfig(appName="Test_Tip", localFilename=config_file) return config #----------------------------------------------------- if __name__ == "__main__": app = MyApp(False) app.MainLoop() }}} -------- == How change the widget text and internationalization support (i18n) == {{attachment:img_sample_two.png}} {{{#!python # sample_two.py import sys import os import wx from wx.adv import CreateFileTipProvider from wx.adv import ShowTip from wx.adv import TipProvider # class MyTipOption # class MyFrame # class MyApp app_dir = os.path.split(os.path.abspath(sys.argv[0]))[0] config_file = os.path.join(app_dir, "options.cfg") # Define a translation string _ = wx.GetTranslation #----------------------------------------------------- class MyTipOption(wx.Dialog): def __init__(self, parent): wx.Dialog.__init__(self, parent, -1, title=_("Option")) self.Bind(wx.EVT_CLOSE, self.on_close_window) #------------------- config = GetConfig() self.checkBox = wx.CheckBox(self, -1, label=_("Show tips at start up"), pos=(20, 20)) self.checkBox.SetValue(config.ReadInt("ShowTips", 0)) content = self.checkBox.GetValue() print("CheckBox = %s" % (content)) self.text = wx.StaticText(self, -1, label=_("Language :"), pos=(20, 68)) self.language = wx.Choice(self, -1, choices=[_("English"), _("French")], pos=(100, 65), size=(100, -1)) self.btnClose = wx.Button(self, -1, label=_("&Close"), pos=(20, 120), size=(100, 30)) self.checkBox.Bind(wx.EVT_CHECKBOX, self.on_check_box) self.Bind(wx.EVT_CHOICE, self.on_language) self.Bind(wx.EVT_BUTTON, self.on_close_btn, self.btnClose) #------------------- self.CentreOnParent(wx.BOTH) #------------------- self.btnClose = self.ShowModal() self.Close() #------------------------ def on_language(self, event): choice = self.language.GetSelection() print("Selection = %s" % (choice)) config = GetConfig() if choice == 0: val = "LANGUAGE_ENGLISH" else: val = "LANGUAGE_FRENCH" print("Language = %s" % (val)) config.Write("Language", val) def on_check_box(self, event): config = GetConfig() config.WriteInt("ShowTips", self.checkBox.GetValue()) content = self.checkBox.GetValue() print("CheckBox = %s" % (content)) def on_close_btn(self, event): self.Close(True) def on_close_window(self, event): self.Destroy() #----------------------------------------------------- class MyFrame(wx.Frame): def __init__(self, parent, id, title): wx.Frame.__init__(self, parent, -1, title) #------------------- frameicon = wx.Icon("Icons/wxWidgets.ico") self.SetIcon(frameicon) #------------------- self.Bind(wx.EVT_CLOSE, self.on_close_window) #------------------- self.panel = wx.Panel(self, -1) self.btnTip = wx.Button(self.panel, -1, label=_("Show &tip setting dialog"), pos=(20, 20), size=(230, 30)) self.btnClose = wx.Button(self.panel, -1, label=_("&Quit"), pos=(20, 100), size=(100, 30)) self.Bind(wx.EVT_BUTTON, self.on_tip_btn, self.btnTip) self.Bind(wx.EVT_BUTTON, self.on_close_btn, self.btnClose) #------------------- # Simplified init method self.create_menu_bar() #------------------- self.CenterOnScreen() #------------------------ def create_menu_bar(self): menuBar = wx.MenuBar() menuFile = wx.Menu(style=wx.MENU_TEAROFF) item = wx.MenuItem(menuFile, -1, text=_("&Quit\tCtrl+Q"), helpString=_("Quit application.")) menuFile.Append(item) self.Bind(wx.EVT_MENU, self.on_close_btn, item) menuOption = wx.Menu(style=wx.MENU_TEAROFF) item = wx.MenuItem(menuOption, -1, text=_("&Setting\tCtrl+K"), helpString=_("Setting language and tip.")) menuOption.Append(item) self.Bind(wx.EVT_MENU, self.on_tip_btn, item) menuBar.Append(menuFile, title=_("&File")) menuBar.Append(menuOption, title=_("&Option")) self.SetMenuBar(menuBar) def show_tip(self): config = GetConfig() # Tip status (show or hide) showTip = config.ReadInt("ShowTips", 1) if showTip == 1 : print("Show tip = %s" % (True)) elif showTip == 0 : print("Show tip = %s" % (False)) index = config.ReadInt("TipIndex", 0) print("Index = %s" % (index)) if showTip: tipProvider = CreateFileTipProvider("tips.txt", index) showTip = ShowTip(self, tipProvider) index = tipProvider.GetCurrentTip() config.WriteInt("ShowTips", showTip) config.WriteInt("TipIndex", index) def on_tip_btn(self, event): self.tip = MyTipOption(self) def on_close_btn(self, event): self.Close(True) def on_close_window(self, event): self.Destroy() #----------------------------------------------------- class MyApp(wx.App): def OnInit(self): self.SetAppName("Test_Tip_i18n") # Retrieve the user configuration language config = GetConfig() language = config.Read("Language", "LANGUAGE_DEFAULT") # Setup the locale self.locale = wx.Locale(getattr(wx, language)) path = os.path.abspath("./locale") + os.path.sep self.locale.AddCatalogLookupPathPrefix(path) self.locale.AddCatalog(self.GetAppName()) frame = MyFrame(None, -1, _("Test show tip at start up - i18n")) frame.Show(True) self.SetTopWindow(frame) if os.path.exists("tips.txt"): wx.CallAfter(frame.show_tip) return True #----------------------------------------------------- def GetConfig(): config = wx.FileConfig(appName="Test_Tip_i18n", localFilename=config_file) return config #----------------------------------------------------- if __name__ == "__main__": app = MyApp(False) app.MainLoop() }}} -------- = Download source = [[attachment:source.zip]] -------- = Additional Information = For the non-ascii characters, save the text file with an utf-8 encoding. For the translation or editing, you can use Poedit application. It exist some version for Windows, Mac and Linux. '''Link :''' https://en.wikipedia.org/wiki/Poedit https://fr.wikipedia.org/wiki/Poedit https://wiki.wxpython.org/WikiTipOfTheDay - - - - - https://wiki.wxpython.org/TitleIndex https://docs.wxpython.org/ -------- = Thanks to = Robin Dunn, Cody Precord, the wxPython community... Thanks also to all known contributors or anonymous that I forgot. -------- = About this page = Date (d/m/y) Person (bot) Comments : 10/10/18 - Ecco (Created page for wxPython Phoenix). -------- = Comments = - blah, blah, blah....