1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199
|
// Package qml offers graphical QML application support for the Go language.
//
// Attention
//
// This package is in an alpha stage, and still in heavy development. APIs may
// change, and things may break.
//
// At this time contributors and developers that are interested in tracking the
// development closely are encouraged to use it. If you'd prefer a more stable
// release, please hold on a bit and subscribe to the mailing list for news. It's
// in a pretty good state, so it shall not take too long.
//
// See http://github.com/go-qml/qml for details.
//
//
// Introduction
//
// The qml package enables Go programs to display and manipulate graphical content
// using Qt's QML framework. QML uses a declarative language to express structure
// and style, and supports JavaScript for in-place manipulation of the described
// content. When using the Go qml package, such QML content can also interact with
// Go values, making use of its exported fields and methods, and even explicitly
// creating new instances of registered Go types.
//
// A simple Go application that integrates with QML may perform the following steps
// for offering a graphical interface:
//
// * Call qml.Run from function main providing a function with the logic below
// * Create an engine for loading and running QML content (see NewEngine)
// * Make Go values and types available to QML (see Context.SetVar and RegisterType)
// * Load QML content (see Engine.LoadString and Engine.LoadFile)
// * Create a new window for the content (see Component.CreateWindow)
// * Show the window and wait for it to be closed (see Window.Show and Window.Wait)
//
// Some of these topics are covered below, and may also be observed in practice
// in the following examples:
//
// https://github.com/go-qml/qml/tree/v1/examples
//
//
// Simple example
//
// The following logic demonstrates loading a QML file into a window:
//
// func main() {
// err := qml.Run(run)
// ...
// }
//
// func run() error {
// engine := qml.NewEngine()
// component, err := engine.LoadFile("file.qml")
// if err != nil {
// return err
// }
// win := component.CreateWindow(nil)
// win.Show()
// win.Wait()
// return nil
// }
//
// Handling QML objects in Go
//
// Any QML object may be manipulated by Go via the Object interface. That
// interface is implemented both by dynamic QML values obtained from a running
// engine, and by Go types in the qml package that represent QML values, such as
// Window, Context, and Engine.
//
// For example, the following logic creates a window and prints its width
// whenever it's made visible:
//
// win := component.CreateWindow(nil)
// win.On("visibleChanged", func(visible bool) {
// if (visible) {
// fmt.Println("Width:", win.Int("width"))
// }
// })
//
// Information about the methods, properties, and signals that are available for QML
// objects may be obtained in the Qt documentation. As a reference, the "visibleChanged"
// signal and the "width" property used in the example above are described at:
//
// http://qt-project.org/doc/qt-5.0/qtgui/qwindow.html
//
// When in doubt about what type is being manipulated, the Object.TypeName method
// provides the type name of the underlying value.
//
//
// Publishing Go values to QML
//
// The simplest way of making a Go value available to QML code is setting it
// as a variable of the engine's root context, as in:
//
// context := engine.Context()
// context.SetVar("person", &Person{Name: "Ale"})
//
// This logic would enable the following QML code to successfully run:
//
// import QtQuick 2.0
// Item {
// Component.onCompleted: console.log("Name is", person.name)
// }
//
//
// Publishing Go types to QML
//
// While registering an individual Go value as described above is a quick way to get
// started, it is also fairly limited. For more flexibility, a Go type may be
// registered so that QML code can natively create new instances in an arbitrary
// position of the structure. This may be achieved via the RegisterType function, as
// the following example demonstrates:
//
// qml.RegisterTypes("GoExtensions", 1, 0, []qml.TypeSpec{{
// Init: func(p *Person, obj qml.Object) { p.Name = "<none>" },
// }})
//
// With this logic in place, QML code can create new instances of Person by itself:
//
// import QtQuick 2.0
// import GoExtensions 1.0
// Item{
// Person {
// id: person
// name: "Ale"
// }
// Component.onCompleted: console.log("Name is", person.name)
// }
//
//
// Lowercasing of names
//
// Independently from the mechanism used to publish a Go value to QML code, its methods
// and fields are available to QML logic as methods and properties of the
// respective QML object representing it. As required by QML, though, the Go
// method and field names are lowercased according to the following scheme when
// being accesed from QML:
//
// value.Name => value.name
// value.UPPERName => value.upperName
// value.UPPER => value.upper
//
//
// Setters and getters
//
// While QML code can directly read and write exported fields of Go values, as described
// above, a Go type can also intercept writes to specific fields by declaring a setter
// method according to common Go conventions. This is often useful for updating the
// internal state or the visible content of a Go-defined type.
//
// For example:
//
// type Person struct {
// Name string
// }
//
// func (p *Person) SetName(name string) {
// fmt.Println("Old name is", p.Name)
// p.Name = name
// fmt.Println("New name is", p.Name)
// }
//
// In the example above, whenever QML code attempts to update the Person.Name field
// via any means (direct assignment, object declarations, etc) the SetName method
// is invoked with the provided value instead.
//
// A setter method may also be used in conjunction with a getter method rather
// than a real type field. A method is only considered a getter in the presence
// of the respective setter, and according to common Go conventions it must not
// have the Get prefix.
//
// Inside QML logic, the getter and setter pair is seen as a single object property.
//
//
// Painting
//
// Custom types implemented in Go may have displayable content by defining
// a Paint method such as:
//
// func (p *Person) Paint(painter *qml.Painter) {
// // ... OpenGL calls with the github.com/ubports/ciborium/qml.v1/gl/<VERSION> package ...
// }
//
// A simple example is available at:
//
// https://github.com/go-qml/qml/tree/v1/examples/painting
//
//
// Packing resources into the Go qml binary
//
// Resource files (qml code, images, etc) may be packed into the Go qml application
// binary to simplify its handling and distribution. This is done with the genqrc tool:
//
// http://github.com/ubports/ciborium/qml.v1/cmd/genqrc#usage
//
// The following blog post provides more details:
//
// http://blog.labix.org/2014/09/26/packing-resources-into-go-qml-binaries
//
package qml
|