Use Qt from Swift. This package exposes every installed
Qt 6 module to Swift so you can import QtCore, import QtWidgets,
or import QtQuick and call Qt's C++ APIs directly from Swift code.
Shipped with Xcode, or installed via swiftly.
Important
This project heavily exercises the Swift C++ interoperability machinery and
experimentalCGen build tool feature, and you may hit sharp corners. If possible,
use a nightly Swift toolchain, to ensure the smoothest ride.
Installed from the Qt Online Installer,
system package manager (Homebrew, apt, etc), or your own
local build.
Tip
If Qt has been installed outside of the system pkg-config location you
can point the build to it via swift build --pkg-config-path <…> or by opening
Xcode with a custom PKG_CONFIG_PATH set: open --env PKG_CONFIG_PATH=<…> -a Xcode
The package has been tested on and
Add the package to the dependencies in your Package.swift:
dependencies: [
.package(url: "https://github.com/torarnv/qt-swift.git", branch: "main")
]Then depend on the Qt modules you need, and turn on C++ interoperability in every target that imports Qt:
.executableTarget(
name: "MyApp",
dependencies: [
.product(name: "QtWidgets", package: "qt-swift")
],
swiftSettings: [
.interoperabilityMode(.Cxx),
.enableExperimentalFeature("ImportCxxMembersLazily")
]
)Choose File → Add Package Dependencies, enter https://github.com/torarnv/qt-swift.git,
and add the Qt modules you need to your app target.
Then turn on the same Swift settings as above, using a configuration file.
Choose File → New → File from Template, pick Configuration Settings File,
and name it Qt.xcconfig:
SWIFT_OBJC_INTEROP_MODE = objcxx
OTHER_SWIFT_FLAGS = $(inherited) -enable-experimental-feature ImportCxxMembersLazily
Select the project in the navigator, open the Info tab, and under
Configurations set Qt as the configuration file of your app target,
for both Debug and Release.
Conform your @main type to QtApplication. The package creates the Qt
application object, calls your init() to set up the UI, and then runs the
event loop until the application quits.
import QtWidgets
@main
struct HelloWidgets: QtApplication {
init() {
// ...
}
}QString and Swift String convert in both directions, and QString accepts
string literals and interpolation:
window.setTitle("Hello 🌍 from Qt \(QLibraryInfo.version())")
print(window.title())swift buildruns the module generator plugin on every target in Qt, regardless of which products the application depends on (swift-package-manager#10590)- The module generator tool itself is not run, but the plugin invocations alone add about 6 seconds to every build (even clean incremental ones)
- To work around this, limit the products reported by the Qt for Swift package
to those you depend on, via
QT_SWIFT_MODULES="QtQuick" swift build - This is not an issue in Xcode, where the build plan prunes unused products before running build tool plugins
- Swift's C++ importer eagerly imports members, resulting in import cycles
- For Swift 6.5 the default has been changed to import members lazily
- Ealier toolchains need to explicitly set
.enableExperimentalFeature("ImportCxxMembersLazily")
- Swift 6.4 does not import constructors with optional arguments in reference types
(swift#92685)
- These are very common in Qt, due to the default parent of e.g.
QObject(QObject *parent = nullptr) - The fix is in Swift main snapshots, so please use a recent snapshot if possible
- These are very common in Qt, due to the default parent of e.g.
- Swift 6.4 cannot upcast a derived reference type to its base class, e.g.
QWidgettoQObject(swift#80231)- This makes APIs taking a base class pointer unreachable from a subclass-typed value
- The fix is in Swift main snapshots, so please use a recent snapshot if possible
- As a workaround for 6.4 you can use
unsafeBitCast(widget, to: QObject.self)for the primary base
- Swift 6.4 can crash the compiler when calling an inherited method with an unnamed parameter, e.g.
quickView.setTitle("...")- The fix is in Swift main snapshots, so please use a recent snapshot if possible
- As a workaround for 6.4 you can call the method on the base type, e.g.
unsafeBitCast(quickView, to: QWindow.self).setTitle("Hello")
The Examples directory holds small projects you can build and run:
HelloCoreprints the Qt versionHelloWidgetsshows a window using Qt WidgetsHelloQuickshows a Qt Quick scene
Qt for Swift is available under the terms of the GNU Lesser General Public
License v3 (LGPL-3.0-only), or under a commercial Qt license. See the
LICENSES directory for the full texts.