While most functions are implemented 1:1 with the official Qt C++ API, there are key differences in how types, memory, and events are handled in Go:
Container Types
Qt containers are projected as native Go types:
QByteArray $\rightarrow$ []byteQString $\rightarrow$ string (Must be UTF-8 to avoid corruption)QList<T> / QVector<T> $\rightarrow$ []TQMap<K,V> / QHash<K,V> $\rightarrow$ map[K]V (Note: Iteration order will differ from Qt's QMap)
Memory Management
When Qt returns a C++ object by value (e.g., QSize), MIQT may move it to the heap and represent it as a pointer in Go. A Go finalizer is automatically added to handle deletion.
Events and Signals
- Signals: The C++
connect(source, signal, target, slot) is projected as targetObject.onSourceSignal(func()...). - Virtual Methods: You can override virtual methods (like
PaintEvent) using the same pattern. The callback receives super() as the first argument to call the base class implementation.
Class Pointers and Inheritance
- Inheritance: Qt classes are projected as Go embedded structs. To pass a subclass to a function expecting a base class, use the base class field (e.g.,
myLabel.QWidget). - Shadowing: If a subclass adds an overload, the base class version is shadowed. Access it via the base class field (e.g.,
myQMenu.QWidget.AddAction(QAction*)). - Pointer Equality: Because MIQT pointers wrap Go structs, direct comparison like
QTabWidget.CurrentWidget() == MyTab will fail. Instead, compare raw pointers using .UnsafePointer():
QTabWidget.CurrentWidget().UnsafePointer() == MyTab.UnsafePointer()
Multithreading
MIQT automatically calls runtime.LockOSThread() when qt.NewQApplication is first called to bind the Go runtime to the Qt main thread. When accessing Qt objects from other goroutines, use (qt6/mainthread).Wait() or Start() to ensure execution on the main thread.