The component gb. gui. trayicon with the two classes TrayIcon and TrayIcons is described in chapter 19.2. This chapter deals with assigning a context menu to a tray icon, which can be called up with the right mouse button in the task bar above the tray icon. If you want to run a Gambas program in the background, you can use the class TrayIcon to access the program via an icon in the task bar. This has the advantage that you always have access to the program interface, or alternatively you can call up selected subprograms in a context menu assigned to the tray icon. The menu is declared in a module in the presented project. You can also create it with the menu editor, whose description can be found in Chapter 13.2 Menu Editor.
Since not every reader has a USB interface for temperature measurement and the class TrayIcon is especially interesting for programs that work hidden for a long time and signal their presence only by an icon in the taskbar, a simulation project is presented to you. The temperature values are generated and displayed randomly in a specified temperature range. The temperature values are also logged in a log file:
MEASUREMENT PROTOCOL DATE: 14. February 2018 ---------------------------- > 09:47:56 | T = 22,3 °C > 09:47:57 | T = 22,1 °C > 09:47:58 | T = 21,8 °C > 09:47:59 | T = 21,0 °C > 09:48:00 | T = 21,5 °C > 09:48:01 | T = 20,3 °C > 09:48:02 | T = 19,9 °C
The program section dedicated to the tray icon context menu has been saved in a module. In this module, the
The source code for the module MTI (module TrayIcon) does not come as a surprise:
[1] ' Gambas module file [2] [3] Public M10MainMenu As Menu [4] Public M11ProgramHideShow As Menu [5] Public M12ShowData As Menu [6] Public M13CloseExperiment As Menu [7] [8] Public Sub CreateMenu() [9] [10] ' True -> The menu is NOT displayed in the main program! [11] M10MainMenu = New Menu(FMain, True) As "Menu" [12] M10MainMenu.Text = ("Caption") [13] [14] ' This property is required for the assignment as pop-up menu of the tray icon! [15] M10MainMenu.Name = "M10MainMenu" [16] [17] M11ProgramHideShow = New Menu(M10MainMenu) As "M11ProgramHideShowShow" [18] M11ProgramHideShow.Text = ("Hide program") [19] M11ProgramHideShow.Picture = Picture["icon:/16/down"] [20] [21] M12ShowData = New Menu(M10MainMenu) As "M12ViewData" [22] M12ShowData.Text = ("Display data") [23] M12ShowData.Picture = Picture["icon:/16/view-icon"] [24] [25] M13CloseExperiment = New Menu(M10MainMenu) As "M13CloseExperiment" [26] M13CloseExperiment.Text = ("Close experiment") [27] M13CloseExperiment.Picture = Picture["icon:/16/quit"] [28] [29] End [30] [31] Public Sub M11ProgramHideShowShow_Click() [32] If M11ProgramHideShow.Text = ("Hide program") Then [33] FMain.Visible = False [34] M11ProgramHideShow.Text = ("Show program") [35] M11ProgramHideShow.Picture = Picture["icon:/16/up"] [36] Else [37] FMain.Visible = True [38] M11ProgramHideShow.Text = ("Hide program") [39] M11ProgramHideShow.Picture = Picture["icon:/16/down"] [40] Endif [41] End [42] [43] Public Sub M12ViewData_Click() [44] Message.Info(("Measurement data are displayed ...")) [45] End ' M12ViewData [46] [47] Public Sub M13CloseExperiment_Click() [48] FMain.Close() [49] End
The complete project for the simulation of a long-term temperature measurement can be found in the long. time. experiment. tar. gz repository in the download area. The source code for the main program can also be found at the end of the chapter.
Figure 13.6.1: GUI of the simulation project
Hints:
Figure 13.6.2: Contents of the context menu for the tray icon
In the following source code, important sections are highlighted in color:
' Gambas class file Public timerDataLog As Timer Public timerReadData As Timer Public timerSimulation As Timer Public fTemperature As Float Public hTrayIcon As TrayIcon Public Sub Form_Open() FMain.Resizable = False FMain.Height = 160 expRX_TX.Hidden = True expRX_TX.Animated = True SetRS232Parameters() timerSimulation = New Timer As "timerSimulation" ' Generate a random temperature value from the specified interval every 100 ms timerSimulation.Delay = 100 timerReadData = New Timer As "timerReadData" ' The current temperature value is read out every 1000 ms timerReadData.Delay = 1000 timerDataLog = New Timer As "timerDataLog" ' Time interval of data storage in a log file timerDataLog.Delay = 3000 * 1 SetLEDColor(picStatus, "red") btnExperimentStop.Enabled = False hTrayIcon = New TrayIcon As "hTrayIcon" hTrayIcon.Icon = Picture["Symbols/experiment.png"] hTrayIcon.Tooltip = ("Long time experiment") hTrayIcon.Visible = False MTI.CreateMenu() ' The menu declared in the module MTI.module is assigned to the tray icon as a context menu. hTrayIcon.PopupMenu = MTI.M10MainMenu.Name End Public Sub btnExperimentStart_Click() GetRS232Parameters() If Exist(Application.Path &/ "rs232.log") Then If Message.Question(("Should the last measurement log be deleted?"), ("Yes"), ("No")) = 1 Then Try Kill Application.Path &/ "rs232.log" AddTextToFile(("Log of measurement data") & gb.NewLine) AddTextToFile(("Date") & ": " & Format(Now, "dd. mmmm yyyy")) AddTextToFile("------------------------------") Endif Else AddTextToFile(("Log of measurement data")) AddTextToFile(("Date") & ": " & Format(Now, "dd. mmmm yyyy")) AddTextToFile("-------------------------------") Endif btnExperimentStart.Enabled = False btnExperimentStop.Enabled = True SetLEDColor(picStatus, "green") lblTemperaturAnzeige.Text = "--- °C" timerSimulation.Start() timerSimulation.Trigger() timerReadData.Start() timerReadData.Trigger() timerDataLog.Start() timerDataLog.Trigger() expRX_TX.Hidden = True MTI.M11ProgramHideShow.Text = ("Show measuring program") MTI.M11ProgramHideShow.Picture = Picture["icon:/16/up"] FMain.Hide() hTrayIcon.Show() End Public Sub btnExperimentStop_Click() timerSimulation.Stop() timerReadData.Stop() timerDataLog.Stop() btnExperimentStart.Enabled = True btnExperimentStop.Enabled = False SetLEDColor(picStatus, "red") lblTemperaturAnzeige.Text = "--- °C" End Public Sub TimerSimulation_Timer() Dim aRange As Float[] = [19.0, 22.0] Randomize fTemperature = Round(Rnd(aRange[0], aRange[1]), -1) End Public Sub timerReadData_Timer() lblTemperaturAnzeige.Text = Str(fTemperature) & " °C" End Public Sub timerDataLog_Timer() AddTextToFile("> " & Format(Now, "hh:nn:ss") & " | " & "T = " & Str(fTemperature) & " °C") End Public Sub expRX_TX_Hide() FMain.Height = 160 expRX_TX.Hidden = True End Public Sub expRX_TX_Show() FMain.Height = 430 expRX_TX.Hidden = False End Public Sub AddTextToFile(Text As String) Dim hFile As File Dim FilePath As String FilePath = Application.Path &/ "rs232.log" Try hFile = Open FilePath For Append If Error Then Message.Error(("File error")) Return Endif Print #hFile, Text Close #hFile End Public Sub hTrayIcon_Click() Message.Info(("I am the little program help...")) End Public Sub hTrayIcon_MiddleClick() FMain.Close() End Public Sub hTrayIcon_Scroll(Delta As Float, Orientation As Integer) If Orientation = TrayIcon.Vertical Then Print "VERTICAL" Print Delta End Private Sub SetRS232Parameters() Dim aDataFlow As New String[] aDataFlow.Add("None") aDataFlow.Add("XON/XOFF") aDataFlow.Add("RFR/CTS") aDataFlow.Add("RFR/CTS + XON/XOFF") cmbFlow.List = aDataFlow cmbRS232Port.List = [("/dev/ttyUSB0.virtual")] cmbSpeed.List = ["4800", "9600", "2400"] cmbParity.Add("None") cmbParity.Add("Even") cmbParity.Add("Odd") cmbDataBits.List = ["8", "7", "6", "5"] cmbStopBits.List = ["1", "2"] End Private Sub GetRS232Parameters() RS232.PortName = cmbRS232Port.Text ' Setting the transmission parameters RS232.Speed = cmbSpeed.Text RS232.Parity = cmbParity.Index RS232.DataBits = cmbDataBits.Text RS232.StopBits = cmbStopBits.Text RS232.FlowControl = cmbFlow.Index End Private Sub SetLEDColor(picBox As PictureBox, sLEDColor As String) picBox.Picture = Picture["LED/led_" & sLEDColor & ".svg"] End Public Sub Form_Close() If Message.Question(("Finish this experiment?"), ("Yes"), ("No")) = 1 Then hTrayIcon.Hide() FMain.Close() Endif End