Creating a desktop application using Golang and Fyne

Today we will develop a desktop application on Golang


Developing a golang desktop application is not a typical task for a golang programmer. There are not so many ready-made open source libraries for Google to solve it at the request of golang desktop, examples of what were found:

  1. gotk
  2. Fyne
  3. Gxui

Fyne was chosen because the github repository of this project contains the largest number of stars, and it also supports the notorious Material design.

Let's see what options for displaying the interface it provides us.

The following widgets are available from the box:

  • Button.
  • A container (for grouping child widgets and directing them horizontally or vertically).
  • Checkbox, fields for entering text or password.
  • Forms and groups.
  • Hyperlink.
  • The icon.
  • The label.
  • Progress Bar.
  • A scrollable container.
  • Switch.
  • Select
  • Tabs.
  • Toolbar.

In the event that among the interface elements the necessary was not found, it is possible to implement custom widgets using a simple API.

Let's try to write a golang gui application for displaying weather forecasts for the next few days using Fyne. The full application code can be found on the link on github.

First of all, create an empty project on Golang and install Fyne.

go get fyne.io/fyne

Since the application will display weather information, you need to get this information. To do this, turn to the Open Weather Map API.

func getWeatherForecast(result interface{}) error {
  var url = fmt.Sprintf("https://api.openweathermap.org/data/2.5/forecast?q=Voronezh&cnt=4&units=metric&appid=%s", openWeatherMapApiKey) //    
  response, err := http.Get(url)
  if err != nil {
     fmt.Print(err)
  }
  defer response.Body.Close()
  return json.NewDecoder(response.Body).Decode(result)
}

To store data, you can use the following structure (in it I left only some of the fields that the API returns), it is worth paying attention to the fact that all fields of the structure are capitalized, but in the API response they are described with a small one.

type WeatherInfo struct {
  List []WeatherListItem `json:list`
}

type WeatherListItem struct {
  Dt      int           `json:dt`
  Main    WeatherMain   `json:main`
  Weather []WeatherType `json:weather`
}

type WeatherMain struct {
  Temp      float32 `json:temp`
  FeelsLike float32 `json:feels_like`
  Humidity  int     `json:humidity`
}

type WeatherType struct {
  Icon string `json:icon`
}

Now we can receive weather data in the form of a structure. It remains to implement the golang desktop application interface.

func setupUi(weatherInfo WeatherInfo) {
  app := app.New()

  w := app.NewWindow("   ")

  var vBox = widget.NewVBox() //        

  for i := 0; i < len(weatherInfo.List); i++ {
     var weatherForDay = weatherInfo.List[i] //     
     var weatherMainGroup = widget.NewVBox(
        widget.NewLabel(fmt.Sprintf(": %.2f °C", weatherForDay.Main.Temp)),
        widget.NewLabel(fmt.Sprintf(" : %.2f °C", weatherForDay.Main.FeelsLike)),
        widget.NewLabel(fmt.Sprintf(": %d%%", weatherForDay.Main.Humidity)),
     ) //  3    

     var weatherTypeGroup = widget.NewVBox()
     for weatherTypeI := 0; weatherTypeI < len(weatherForDay.Weather); weatherTypeI++ {
        var resource, _ = fyne.LoadResourceFromURLString(fmt.Sprintf("http://openweathermap.org/img/wn/%s.png", weatherForDay.Weather[weatherTypeI].Icon)) //   ,   
        var icon = widget.NewIcon(resource)
        weatherTypeGroup.Append(icon)
     }

     var time = time2.Unix(int64(weatherInfo.List[i].Dt), 0).String()
     vBox.Append(widget.NewGroup(time)) 
     vBox.Append(widget.NewHBox(weatherMainGroup, weatherTypeGroup))
  }
  vBox.Append(widget.NewButton("", func() {
     app.Quit()
  }))

  w.SetContent(vBox) //    

  w.ShowAndRun() //   
}

Here we create our widgets, fill them with data and collect them into groups to organize the order in which they are displayed.

Done.

It remains only to run the application and see how it looks. Since the framework is cross-platform, you can run it on both Windows and macOS and Linux.

image
Launched golang mac os application

image
And it looks like a golang windows application

As a result, it turned out to create a simple cross-platform golang desktop application, and try Fyne in action. Unfortunately, go is hardly worth considering as a suitable language for developing modern desktop applications, however, it is always interesting to touch something new and unusual in practice.

Thank you all for your attention.

All Articles