The supported release targets are .NET 10 with Qt 6.12.0 on Windows x64 and Linux x64/glibc.
- Windows x64 and Linux x64 (glibc), Qt 6.12.0 only — the model is extracted from the MSVC kit, and the Linux build compiles the same generated C++ with g++. ARM64 and musl are not packaged.
- The addon
.Qt6packages have no separate Linux payload. On Linux the baseQtSharp.Qt6package deploys the whole Qt tree (lib/+plugins/+qt.conf, addon modules included), because every addon package depends on it anyway; the addon packages still carry the addon's native glue for both RIDs. - Single-file publish is not supported on Linux. The deployment relies on
$ORIGINrpaths between the application directory,lib/andplugins/; a single-file bundle extracts the native libraries elsewhere and breaks that layout. QtSharp.Toolsis Windows x64 only — itsrcc/uic/lrelease/lupdatepayload is the MSVC build. On Linux use the tools from the Qt kit directly.QtSharp.WebViewis Windows x64 only — it hosts Microsoft Edge WebView2, which has no Linux implementation. The machine also needs the Evergreen WebView2 Runtime (preinstalled on Windows 11 and most updated Windows 10 systems);WebView2Widget.IsRuntimeAvailablereports whether it is present.- QtMultimedia on Linux needs the distribution's FFmpeg runtime. Qt's ffmpeg backend plugin
links
libavcodec/libavformat/libavutil/libswresample/libswscale; install the ffmpeg runtime packages that match the kit's build (on Ubuntu 24.04, thelibavcodec60family). The binding and the plugin load without them, butQMediaPlayerreports no media.
long-typed Qt APIs stay 32-bit on Linux. The model comes from the MSVC headers, wherelongis 32 bits, so the C ABI pins it toint/uinton both platforms and the wrapper converts at the Qt call. That keeps one C# API across platforms, butQByteArray.toLong,QLocale.toLong, theQEventPointtimestamps and theQThread/QWaitConditiontimeout parameters truncate to 32 bits on Linux (the timestamps wrap after ~49.7 days of uptime). Use theQByteArray::toLongLong/QLocale::toLongLongoverloads when the full range matters. Permanent for the 1.0 line: one C# surface that behaves the same on both platforms is worth more than a per-platformlong, and every affected API has a 64-bit sibling.- Windows-only Qt members are not bound.
QProcess.nativeArguments/setNativeArgumentsare declared by Qt only on Windows; the generator filters them out so one API surface compiles on both platforms. UseProcessStartInfo.Argumentsinstead. QAudioFormathas no constructor overloads in the binding. Qt 6.12 declares none beyond the implicit default (the AST does not list it), so there is noQAudioFormat(...); as a struct its default (new QAudioFormat()/default) is Qt's default format, and the setters fill it in. Permanent: there is nothing in the headers to bind.QAudioDevice.PreferredFormat()is still the useful starting point.- An optional parameter whose C++ default is a bare enumerator that is not an enumerator of the
parameter's type still truncates the overload (the C# default would be 0, which Qt often
reserves for "invalid"). A boxed-value default is fine now: the parameter defaults to
nulland the native glue substitutes the declared expression, which is what unlockedQPixmap.fill(QColor),QWidget.grab(QRect),QComboBox.addItem(QString, QVariant)andQTcpServer.listen(address, port). The remaining bare-enumerator case is permanent: C# has no spelling for "the default is this enumerator of another type". - A
const uchar *return is dropped (there is no length to go with it), soQResource.data()andQImage.bits()are absent;QResource.uncompressedData(),QByteArrayand thebyte[]parameters cover the same ground. Nested classes (QFont::Tag,QTextOption::Tab) are not bound either — the model publishes top-level classes and enums only, which is permanent for 1.0; their top-level equivalents (QFont,QTextOption) carry the usable surface. Both are stable limitations, not pending work. - Managed types have no Qt metatype. A
[QtSignal]parameter and a queued connection carry Qt types; a managed object travels as aQVariantopaque payload (new QVariant(anyObject)andQVariant.Value<T>(), covered bytest-variantobject). Qt's metatype registry is keyed by C++ type, and a C# class has none, soQMetaType.FromType<T>()cannot produce an id for it. A single wrapper metatype would make every managed type one id, which is not type identity; per-type registration needs a generated C++ shell per managed type and is not planned for 1.0. Documented so callers do not expect a managed object to survive a queued connection on its own.
- Intentionally omitted: QtXml, QtSql and QtWebSockets use .NET alternatives; see module scope and .NET integration.
- Not currently bound: QtQml/QtQuick, QtPdf, QtWebEngine and QtWebView. The measured cost of
the web view modules is in web view options;
QtSharp.WebViewis the managed WebView2 substitute for the Windows case. - Not ported: the RHI examples (they need
QRhiand prebuilt shaders) and Window Embedding. PDF output works throughQPrinter(seetest-docformats); PDF reading needs the QtPdf module, which is not bound.
QtSharp.WebViewhas airspace limits. WebView2 renders into a native child window, so Qt-painted content cannot cover it: child widgets, stylesheet backgrounds and translucent overlays above it are hidden. Menus, tooltips and dialogs are separate top-level windows and work normally. The widget is also UI-thread bound; useRunOnUiThreadafter background work.QtSharp.Sqlmaterializes a whole result set. Qt'sQSqlTableModelfetches in 256-row batches; the substitute loads everything up front, so page very large tables withWHERE/LIMIT. Its per-cellData()also crosses the managed/native boundary (a per-call cost for visible cells).- Native window teardown needs the windows to be gone first.
test-windowflagsused to crash insideqwindows.dllabout a quarter of the time while the runtime tore the application down with a shown window still alive. Hiding the windows, flushing the posted events and disposing them before returning fixes it (0 crashes in 40 runs), and that is what the test does. Application code that shows its own windows should letQApplication.exec()return normally; a process that exits with windows still shown keeps the same hazard.