13.6 Kontextmenü – TrayIcon

Die Komponente gb.gui.trayicon mit den beiden Klassen TrayIcon und TrayIcons wird im Kapitel 19.2 beschrieben. Im diesem Kapitel geht es darum, einem Tray-Icon ein Kontext-Menü zuzuweisen, das in der Task-Leiste über dem Tray-Icon mit der rechten Maustaste aufgerufen werden kann.

Wenn Sie ein Gambas-Programm im Hintergrund laufen lassen wollen, dann bietet sich für den Zugriff auf das Programm über ein Icon in der Task-Leiste die Klasse TrayIcon an. Das hat den Vorteil, dass Sie einerseits stets Zugriff auf die Programmoberfläche haben oder alternativ ausgewählte Teil-Programme in einem dem Tray-Icon zugewiesenen Kontext-Menü aufrufen können. Das Menü wird in vorgestellten Projekt in einem Modul deklariert. Sie können es aber auch mit dem Menü-Editor anlegen, dessen Beschreibung Sie im Kapitel 13.2 Menü-Editor nachlesen können.

Da nicht jeder Leser über ein USB-Interface zur Temperatur-Messung verfügt und die Klasse TrayIcon vor Allem für Programme interessant ist, die lange Zeit versteckt arbeiten und ihre Anwesenheit nur durch ein Icon in der Taskleiste signalisieren, wird Ihnen ein Simulationsprojekt vorgestellt. Die Temperaturwerte werden zufällig in einem vorgegebenen Temperaturbereich erzeugt und angezeigt. Außerdem werden die Temperaturwerte in einer Log-Datei protokolliert:

MESS-PROTOKOLL 
DATUM:  14. Februar 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 

Der Programmteil, der sich dem Kontext-Menü für das Tray-Icon widmet, wurde in einem Modul gespeichert. In diesem Modul werden

Der Quelltext zum Modul MTI (Modul TrayIcon) birgt keine Überraschungen:

[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

Das vollständige Projekt zur Simulation einer Langzeit-Temperaturmessung finden Sie im Projektarchiv long.time.experiment.tar.gz im Downloadbereich. Den Quelltext für das Hauptprogramm finden Sie auch am Ende des Kapitels.

B1

Abbildung 13.6.1: GUI des Simulationsprojektes

Hinweise:

B2

Abbildung 13.6.2: Inhalt Kontext-Menü für das Tray-Icon

Im folgenden Quelltext sind wichtige Abschnitte farbig hervorgehoben:

' 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 

Download