Of course, GUI development is more complicated to create than a command line application. Fyne chose Fyne for the time being because he said he would use Go's excellent design to make building a GUI simple and quick. Eventually, I want to be able to use Go-made shiny. So, I want to migrate the following programs to GUI.
CSV file summary Go program for Resona IB Go program to manage save data of minecraft
With that said, I didn't plan to participate in the Advent calendar, but I decided to post it in a hurry because there was a frame. (Although it's in the vacancy, I don't like the feeling of being delayed ... I think I forgot to post ... sad)
You can use it with the following commands.
console
go get fyne.io/fyne
The above command completes the environment construction. Below are the demo settings
console
go get fyne.io/fyne/cmd/fyne_demo
fyne_demo
The following is the screen immediately after starting the demo.
You can try most objects.
fyne_demo
directly in my environment, a command error occurred. Therefore, I hit it directly to start it, but the Path setting may not be working properly.Hello World First of all, the basics.
Sample code
package main
import (
"fyne.io/fyne/app"
"fyne.io/fyne/widget"
)
func main() {
myApp := app.New()
myWindow := myApp.NewWindow("Hello") //Window title
myWindow.SetContent(widget.NewLabel("Hello World!")) //Place text labels on window content
myWindow.ShowAndRun() //Run application(Show & Run)
//If the process is described after this point, it will not be executed until the application finishes executing.
}
The packages are separated according to the type of type.
fyne.io/fyne Providing a basic definition common to all Fyne codes. Includes data types and interfaces.
fyne.io/fyne/app Provide an API to launch a new application. Normally, you only need app.New ().
fyne.io/fyne/canvas Provides all drawing APIs in Fyne. The complete Fyne toolkit consists of these basic graphical types (simple canvas).
fyne.io/fyne/dialog Dialog windows such as confirmations and errors are handled by this package.
fyne.io/fyne/layout Provides a variety of layout implementations. Containers are available.
fyne.io/fyne/test This package makes it easier to test your application.
fyne.io/fyne/widget This package provides a variety of widget collections. Interactions with widgets are also provided in this package.
I'm not sure, but I'll give you a glimpse of what I think I understood.
Icons and metadata are associated with each OS, and the format required for those environments is required. The finy command can handle the complicated environment if the OS is supported by the toolkit.
By executing "fyne package", will applications with different installation formats be generated for each OS ... (I don't understand).
In the case of WindowsOS, an exe file with an icon is created. For MacOS, generate an app bundle. For Linux, create a tar.xz file.
console
go get fyne.io/fyne/cmd/fyne
go build
fyne package -icon mylogo.png
Unfortunately I couldn't do it in my environment (maybe I need to go through Path).
In order for the GUI to start up, a run loop (Runloop / event loop) that handles drawing events is essential.
In Fyne, use Window.ShowAndRun ()
or App.Run ()
.
It also needs to be called at the end of the main () function (see sample code).
Note that if you call it in the middle of processing, the subsequent processing will not be executed until the window is closed.
This runloop can only be run once within an application, so multiple runs will result in an error (one call is required).
Sample code
func main() {
myApp := app.New()
myWindow := myApp.NewWindow("Hello")
myWindow.SetContent(widget.NewLabel("Hello"))
myWindow.Show() //Window display
myApp.Run() //Window execution
tidyUp() //Executed after the window is closed.
}
func tidyUp() {
//A function that is called after the GUI window is closed.
fmt.Println("Exited")
}
You can terminate the application by executing App.Quit ()
on the code.
However, it is necessary to use it in the call from the user (the usual x button at the top of the window) because an unexpected event occurs by issuing the end instruction directly from the source code.
The window is created using App.NewWindow () and displayed by the Show () function.
Excerpt
myApp := app.New()
myWindow := myApp.NewWindow("Hello") //Window generation
・
・
・
myWindow.Show() //Window display
myApp.Run() //Window execution
As shown in the sample code above, the ShowAndRun () function can be used to execute both Show and Run. This ShowAndRun function is one of the helper methods in fine.Window.
Excerpt
myApp := app.New()
myWindow := myApp.NewWindow("Hello") //Window generation
・
・
・
myWindow.ShowAndRun() //Window display and execution
If you want to create a child window, you only need to call the Show () function (which you can do with the Goroutine function callee).
The following explanations require knowledge of goroutine (concurrency).
In Fyne, Canvas is where the application is drawn. Each window is drawn with Window.Canvas (), but it can be omitted. In the first place, anything that can be drawn with Fyne is a type of CanvasObject.
Sample code
func main() {
myApp := app.New()
myWindow := myApp.NewWindow("Canvas") //Window title
myCanvas := myWindow.Canvas() //Canvas generation
text := canvas.NewText("Text", color.Black) //Black letters ready on canvas
text.TextStyle.Bold = true //Bold
myCanvas.SetContent(text) //Text drawing above
go changeContent(myApp, myCanvas) //Goroutine function call
myWindow.Resize(fyne.NewSize(200, 100))
myWindow.ShowAndRun()
}
func changeContent(a fyne.App, c fyne.Canvas) {
time.Sleep(time.Second * 2)
c.SetContent(canvas.NewRectangle(color.Black)) //Fill the canvas with black(Rectangle fixed)。
time.Sleep(time.Second * 2)
c.SetContent(canvas.NewLine(color.Gray{0x66})) //Draw a line on the canvas
win := a.NewWindow("Child window")
win.SetContent(widget.NewLabel("5 seconds later"))
win.Resize(fyne.NewSize(200, 200))
circle := canvas.NewCircle(color.Black) //Circular on canvas(Fill with black)
circle.StrokeWidth = 8
circle.StrokeColor = color.RGBA{0x00, 0x00, 0xFF, 0x00} //The circular line is blue
win.SetContent(circle)
win.Show() //Child window display
time.Sleep(time.Second * 2)
win.Hide() //Hide child window
time.Sleep(time.Second * 2)
c.SetContent(canvas.NewImageFromResource(theme.FyneLogo())) //Logo display
}
It seems that it can be redrawn?
canvas.Refresh(circle)
However, I could not tell the difference before and after use.
canvas.NewLine
draws a line from top left to bottom right by default.
I'm worried that the process of displaying the child window is correct. Also, external packages introduced from github do not complement and are very inconvenient.
I think it is unique to MSCode, but I want you to eliminate it.
Only one of the above was used. However, that is not enough for actual operation. To use multiple canvases, use containers together.
Sample code
func main() {
myApp := app.New()
myWindow := myApp.NewWindow("Container")
text1 := canvas.NewText("Hello", color.Black) //Creating a text object
text2 := canvas.NewText("There", color.Black) //Creating a text object
text2.Move(fyne.NewPos(20, 20)) //Moving the second text object
text3 := canvas.NewText("World", color.Black) //Creating a text object
container := fyne.NewContainer(text1, text2, text3) //Place three text objects in a container.
myWindow.SetContent(container) //Set the above container as content in the window
myWindow.ShowAndRun() //Display and execute windows.
}
Of course, the container is also part of the canvas object, so it can be set as the canvas content. procedure
It becomes a flow to say.
I'm moving objects because I'm not using a layout set. In short, text1 and text3 that have not been moved are covered. Below is the grid layout.
container := fyne.NewContainerWithLayout(layout.NewGridLayout(2), text1, text2, text3)
Below is the grid wrap layout.
layout.NewGridWrapLayout(fyne.NewSize(50, 50))
Below is the borderline layout. The four arguments are the location. Specify nil if it is not required.
layout.NewBorderLayout(top, bottom, left, right)
fyne.Layout implements methods for organizing items in a container. Modify the container to use a two-column grid layout. By resizing the window, you can see that the text changes depending on the layout. Also make sure that the manually modified code in text2 is ignored.
fyne.Widget becomes a special type of container (it seems to have additional logic associated with it, but it doesn't make sense). (It seems to be called Widget Renderer). I'm not sure, but widgets are also part of the canvas object.
Add widget.Entry to the window content (only one example below). To add multiple widgets, use a set of widgets instead of a container.
Sample code
func main() {
myApp := app.New()
myWindow := myApp.NewWindow("Widget")
myWindow.SetContent(widget.NewEntry())
myWindow.ShowAndRun()
}
In this widget, it is a box where you can enter characters, but you cannot enter multiple bytes.
However, if it is a solid writing in the source code, it can be displayed. I wonder if I'm in trouble for now ...
For the time being, it seems that Japanese can be displayed by specifying the font in the environment variable FYNE_FONT
.
Oomoto (?) Fyne site package fyne Cross-platform GUI application development starting with Go UI toolkit Fyne
It seems that 1.4 is used this time.
that's all.
Recommended Posts