macOS向けQt - 特定の課題
このページでは、QtにおけるmacOSのサポートに関する主な課題について概説します。macOSの用語や具体的な手順については、https://developer.apple.com/ を参照してください。
Aqua
Aquaスタイルは、macOSプラットフォームの重要な要素です。Cocoaと同様に、QtはmacOSの「Human Interface Guidelines」で規定されているものと同様の外観を持つウィジェットを提供しています。なお、Qt Widgetsはルックアンドフィールのために内部でAppKitを使用していますが、個々のQt Widgetsをラップされたネイティブコントロールとして表現しているわけではない点に注意してください。
「Qt Widgets Gallery」ページには、macOSプラットフォームのテーマを採用したアプリケーションのサンプル画像が掲載されています。
macOS 向けの Qt 属性
以下に、macOS上のアプリケーションを微調整するために使用できる便利な属性のセットを挙げます:
- Qt::AA_PluginApplication
- Qt::AA_DontUseNativeMenuBar
- Qt::AA_MacDontSwapCtrlAndMeta
- Qt::WA_MacOpaqueSizeGrip
- Qt::WA_MacShowFocusRect
- Qt::WA_MacNormalSize
- Qt::WA_MacSmallSize
- Qt::WA_MacMiniSize
- Qt::WA_MacAlwaysShowToolWindow
- Qt::Sheet
- Qt::Drawer
- Qt::MacWindowToolBarButtonHint,
- QMainWindow::unifiedTitleAndToolBarOnMac
macOSでは常に画面がダブルバッファ処理されるため、Qt::WA_PaintOnScreen 属性は効果を持ちません。また、ペイントイベントの外側で描画を行うことは不可能なため、Qt::WA_PaintOutsidePaintEventも同様に効果を持ちません。
右クリック
QContextMenuEvent クラスは、macOSアプリケーション向けに右クリックのサポートを提供します。これはコンテキストメニューイベント(たとえば、ポップアップ選択を表示するメニューなど)にマッピングされます。これは右クリックの最も一般的な用途であり、macOSの1ボタンマウスサポートではControlキーを押しながらクリックすることにマッピングされます。
国際化
macOS上のアプリケーションは、アプリケーションのInfo.plist の一部として、サポートする言語を宣言します。 その後、システムはアプリケーションがサポートする言語とユーザーの言語設定を照合し、アプリケーションを起動する際のロケールを決定します。これにより、QLocale::uiLanguages() を通じて反映される言語の順序や、AppKit などのシステムフレームワークがメニュータイトルや文字列などのローカライズされたリソースをどのように取得するかが決定されます。
Qt XML アプリケーションは初期状態では翻訳されていないため、CMake およびqmake プロジェクト用にデフォルトで生成されるInfo.plist では CFBundleAllowMixedLocalizationsYES に設定され、アプリケーション自体でそのローカライズが利用できない場合でも、システムフレームワークがユーザーの言語設定に最も適合するローカライズを選択できるようにします。qt_add_translations を使用してアプリケーションに翻訳を追加すると、 CFBundleAllowMixedLocalizations キーは自動的に削除され、代わりに CFBundleLocalizationsに置き換えられ、サポートするすべての言語が列挙されます。qmake については、この処理を手動で行う必要があります。
メニューバー
Qtはメニューバーを検出し、Macネイティブのメニューバーに変換します。既存のQtアプリケーションへの組み込みは通常自動で行われます。ただし、特別な要件がある場合、現在のQtの実装では、アクティブなウィンドウ(例:QGuiApplication::focusWindow()) から開始し、以下のテストを適用することでメニューバーを選択します:
- ウィンドウにQMenuBar がある場合、それが使用されます。
- ウィンドウがモーダルである場合、そのメニューバーが使用されます。メニューバーが指定されていない場合は、デフォルトのメニューバーが使用されます(後述の通り)。
- ウィンドウに親ウィンドウがない場合は、デフォルトのメニューバーが使用されます(後述の通り)。
これらのチェックは、上記のルールいずれかが満たされるまで、親ウィンドウのチェーンを遡って順次行われます。 これらすべての条件を満たさない場合、デフォルトのメニューバーが作成されます。Qt のデフォルトのメニューバーは空のメニューバーです。ただし、親を持たない `QMenuBar` を作成することで、別のデフォルトのメニューバーを作成することができます。最初に作成されたものがデフォルトのメニューバーとして指定され、デフォルトのメニューバーが必要な場合は常にそれが使用されます。
ネイティブメニューバーを使用すると、Qtクラスに特定の制限が生じます。以下の制限事項の一覧を記載したセクションに、詳細情報が記載されています。
Qtは、QMenuBar を通じてグローバルメニューバーをサポートしています。macOSユーザーは画面上部にメニューバーがあることを期待しており、Qtはこの期待に応えています。
さらに、ユーザーは特定の慣例が守られることを期待しています。例えば、アプリケーションメニューには「About」、「Preferences」、「Quit」などが含まれているべきです。Qtはこれらの慣例に対応していますが、アプリケーションメニューと直接やり取りする手段は提供していません。
各QAction には、アプリケーションメニュー項目の特別な配置を制御するmenuRole プロパティがあります。ただし、デフォルトではmenuRole はTextHeuristicRole に設定されており、これによりメニュー項目はtext によって自動検出されます。
「切り取り」、「コピー」、「貼り付け」、「すべて選択」などのその他の標準メニュー項目は、アプリケーション内だけでなく、QFileDialog などの一部のネイティブダイアログでも使用できます。ダイアログ内で対応する編集機能が有効になるよう、これらのメニュー項目を標準のショートカットを使用して作成することが重要です。 現時点では、これらに対応するMenuRole 識別子は存在しませんが、QAction の値がデフォルトのTextHeuristicRole に設定されている場合、アプリケーションのメニュー項目と同様に自動的に検出されます。
特殊キー
macOS上のQtアプリケーションで期待される動作を実現するため、Qt::Key_Meta 、Qt::MetaModifier 、およびQt::META の列挙値は、標準のAppleキーボードのControlキーに対応し、Qt::Key_Control 、Qt::ControlModifier 、およびQt::CTRL の列挙値はCommandキーに対応しています。
Dock
Dockとの連携が可能です。アプリケーションのメインウィンドウからQWindow::setIcon()を呼び出すことで、アイコンを設定できます。setIcon()の呼び出しは必要なだけ何度でも行うことができ、アイコンを簡単に更新できます。
アクセシビリティ
多くのユーザーは、支援機器を使用して macOS を操作しています。Qt では、アプリケーションがこの操作を自動的に処理し、プラットフォーム上の一般的な慣行に準拠することを目指しています。Qt は、Apple のアクセシビリティフレームワークを使用して、障がいのあるユーザーへのアクセスを提供しています。
ライブラリおよびデプロイメントのサポート
Qtは、FrameworksやバンドルといったmacOSの構造に対するサポートを提供しています。これらはアプリケーションのデプロイに直接影響するため、これらの構造を把握しておくことが重要です。
Qt には、デプロイプロセスを簡素化するためのツール「macdeployqt」が用意されています。詳細については、「Qt for macOS - デプロイ」の記事で解説しています。
フレームワークとしてのQtライブラリ
デフォルトでは、Qt は一連のフレームワークとしてビルドされます。フレームワークは、macOS でライブラリを配布するための推奨される方法です。Apple の「Framework Programming Guide」サイトには、フレームワークに関するさらに詳しい情報が掲載されています。
フレームワークは常にライブラリのリリース版とリンクされることを覚えておくことが重要です。Qt フレームワークのデバッグ版を使用したい場合は、DYLD_IMAGE_SUFFIX という環境変数を設定して、デバッグ版が確実に読み込まれるようにしてください:
export DYLD_IMAGE_SUFFIX=_debugあるいは、Appleのテクニカルノート「Debugging Magic」に記載されているように、デバッグ版とリリース版を一時的に入れ替えることもできます。
フレームワークを使用したくない場合は、単に Qt を-no-framework で設定してください。
./configure -no-frameworkバンドルベースのライブラリ
macOSアプリケーションバンドル(アプリケーションディレクトリ)内でダイナミックライブラリを使用したい場合は、アプリケーションバンドルディレクトリ内に「Frameworks」という名前のサブディレクトリを作成し、そこにダイナミックライブラリを配置してください。アプリケーションは、インストール名が@executable_path/../Frameworks/libname.dylib となっているダイナミックライブラリを検出します。
qmake やMakefileを使用する場合は、QMAKE_LFLAGS_SONAME という設定を使用してください:
QMAKE_LFLAGS_SONAME = -Wl,-install_name,@executable_path/../Frameworks/あるいは、コマンドライン上のinstall_name_tool(1) を使用して、インストール名を変更することもできます。
DYLD_LIBRARY_PATH 環境変数が設定されれば、これらの設定や、/usr/lib内でのダイナミックライブラリの検索など、その他のデフォルトのパス設定よりも優先されます。
ライブラリの結合
Qtのダイナミックライブラリを組み合わせて新しいダイナミックライブラリをビルドする場合は、ld -r フラグを指定する必要があります。これにより、リロケーション情報が出力ファイルに格納され、そのファイルを再度ld で処理できるようになります。これを行うには、.pro ファイルで-r フラグを設定し、LFLAGS の設定を行います。
初期化順序
dyld(1) は、アプリケーションにリンクされた順序でグローバル静的初期化子を呼び出します。ライブラリがQtに対してリンクされ、かつ(自身のライブラリ内のグローバル初期化子から)Qt内のグローバル変数を参照している場合は、そのライブラリに対してリンクする前に、アプリケーションをQtに対してリンクしてください。 そうしないと、Qtのグローバル初期化関数がまだ呼び出されていないため、結果は未定義となります。
コンパイル時のフラグ
macOS 専用のコードを定義する場合、以下のフラグが役立ちます:
Q_OS_DARWINQt が macOS や iOS などの Darwin ベースのシステム上で実行されていることを検出した場合に定義されます。Q_OS_MACOSmacOS システム上で実行されている場合に定義されます。
注: Qt 5以降では、Q_WS_MAC は 定義されなくなりました。
特定のバージョンの macOS 向けにコードを定義したい場合は、/usr/include/AvailabilityMacros.h で定義されている可用性マクロを使用してください。
QSysInfo および QOperatingSystemVersion のドキュメントには、実行時のバージョンチェックに関する情報が記載されています。
macOS ネイティブ API へのアクセス
バンドルパスへのアクセス
macOSアプリケーションは、ディレクトリ(末尾が.app)として構成されています。このディレクトリには、サブディレクトリやファイルが含まれています。プラグインやオンラインドキュメントなどのアイテムを、このバンドル内に配置すると便利な場合があります。以下のコードは、アプリケーションバンドルのパスを返します:
#ifdef Q_OS_MAC
QString bundlePath=QString::fromNSString(NSBundle.mainBundle.bundlePath);
qDebug() << "Bundle path =" << bundlePath;
#endifNSBundle API の使用方法に関する詳細については、Apple の開発者向けウェブサイトをご覧ください。
QCoreApplication::applicationDirPath() を使用すると、バンドル内のバイナリのパスを特定できます。
ネイティブのCocoaパネルの使用
QtのイベントディスパッチャはCocoaが提供するものと比べて柔軟性が高く、画面上にモーダルダイアログが表示されているかどうかを気にすることなく、ユーザーがイベントディスパッチャ(およびQEventLoop::exec の実行)を制御できます(これはCocoaとの違いです)。 そのため、これを正しく処理するには Qt 側で追加の管理が必要となり、残念ながらネイティブパネルの混在が難しくなります。 現時点でこれを行う最善の方法は、以下のパターンに従うことです。このパターンでは、関数を直接呼び出すのではなく、ネイティブコードに呼び出しを委ねます。そうすることで、ネイティブパネルが表示される前に、Qtが保留中のイベントループの再帰処理を確実に更新したことが保証されます。
#include <QtGui>
class NativeProxyObject : public QObject
{
Q_OBJECT
public slots:
void execNativeDialogLater()
{
QMetaObject::invokeMethod(this, "execNativeDialogNow", Qt::QueuedConnection);
}
void execNativeDialogNow()
{
NSRunAlertPanel(@"A Native dialog", @"", @"OK", @"", @"");
}
};
#include "main.moc"
int main(int argc, char **argv){
QApplication app(argc, argv);
NativeProxyObject proxy;
QPushButton button("Show native dialog");
QObject::connect(&button, SIGNAL(clicked()), &proxy, SLOT(execNativeDialogLater()));
button.show();
return app.exec();
}制限事項
MySQL および macOS
静的 C ライブラリをダイナミックライブラリにリンクする際、-prebind と-multi_module の両方が定義されていると、問題が発生するようです。Qt XML をリンクする際に以下のエラーメッセージが表示される場合は、
ld: common symbols not allowed with MH_DYLIB output format with the -multi_module option
/usr/local/mysql/lib/libmysqlclient.a(my_error.o) definition of common _errbuff (size 512)
/usr/bin/libtool: internal link edit command failed-single_module オプションを使用して Qt を再リンクしてください。この問題は、MySQL ドライバを Qt に組み込む場合にのみ発生します。プラグインや静的ビルドには影響しません。
D-Bus と macOS
QtDBus モジュールは、macOS上でデフォルトでlibdbus-1ライブラリを動的に読み込みます。つまり、QtDBus モジュールをリンクしたアプリケーションは、ライブラリが存在しないmacOSシステム上でも起動しますが、どのD-Busサーバーへの接続も失敗し、QDBusServer を使用してサーバーを開くこともできません。
D-Bus 機能を使用するには、Homebrew、Fink、MacPorts などを通じて libdbus-1 ライブラリをインストールする必要があります。他のシステムにアプリケーションをデプロイする場合は、これらのライブラリをアプリケーションのバンドルに含めることをお勧めします。 また、macOS にはシステムバスが存在せず、セッションバスは launchd がそれを管理するように設定された後にのみ起動される点に注意してください。
メニューアクション
- QMenu 内のアクションで、複数のキーストロークからなるアクセラレータ(QKeySequence )が設定されている場合、QMenu がMacネイティブのメニューバーに変換されると、正しく表示されなくなります。最初のキーのみが表示されます。ただし、ショートカットは他のすべてのプラットフォームと同様に機能します。
- QMenu ネイティブメニューバーで使用されるオブジェクトは、通常のイベントハンドラを介してQtイベントを処理することができません。これらの変更を通知してもらうには、メニュー自体にデリゲートを設定してください。あるいは、メニューの可視性を追跡するために、QMenu::aboutToShow() およびQMenu::aboutToHide() シグナルを使用することを検討してください。これらは、Qtがサポートするすべてのプラットフォームで動作するはずの解決策となります。
- デフォルトでは、Qt は
CMD+Qショートカットに応答するネイティブな「終了」メニュー項目を作成します。QAction::QuitRole ロール用のQAction を作成すると、そのメニュー項目が置き換えられます。したがって、置き換えられたアクションは、QCoreApplication::quit スロット、またはアプリケーションを終了させるカスタムスロットのいずれかに接続する必要があります。
ネイティブウィジェット
Qtは、ウィンドウフラグQt::Sheet で表されるシートをサポートしています。
通常、macOSのネイティブアプリケーションについて「ネイティブ」と言う場合、それは中間層を経由するのではなく、基盤となるウィンドウシステムに直接アクセスするアプリケーションを指します。Qtアプリケーションは、Cocoaアプリケーションと同様に、第一級の市民として動作します。OSとの通信には、内部的にCocoaを使用しています。
シンボルの可視性に関する警告
C++ライブラリのリンクにおいて、関数やオブジェクトは「シンボル」と呼ばれます。シンボルの可視性には、default またはhidden のいずれかがあります。
パフォーマンス上の理由から、Qtや他の多くのライブラリは、デフォルトでhidden の可視性を使用してソースをコンパイルし、ユーザープロジェクトで使用されることを意図しているシンボルのみにdefault の可視性を付与します。
残念ながら、あるライブラリがhidden の可視性でコンパイルされ、ユーザープロジェクトのアプリケーションやライブラリがdefault の可視性でコンパイルされている場合、Appleのリンカーが警告を出すことがあります。
プロジェクト開発者がこの警告を抑制したい場合は、プロジェクトのコードもhidden の可視性でビルドする必要があります。
CMakeでは、CMakeLists.txt に以下のコードを追加することでこれを実現できます:
set(CMAKE_CXX_VISIBILITY_PRESET hidden)qmake では、.pro ファイルに以下のコードを追加することでこれを行うことができます:
CONFIG+=hide_symbolsプロジェクトでライブラリをビルドする場合、別のライブラリやアプリケーションで使用されることを意図したライブラリ内のシンボルは、default の可視性を持つように明示的にマークする必要があります。たとえば、そのような関数やクラスに `Q_DECL_EXPORT` を付与することで実現できます。
CMake Xcodeプロジェクトによって生成されたxcarchiveにdSYMバンドルが含まれていない
XcodeのバグおよびCMakeの特定の制限により、CMakeで生成されたXcodeプロジェクトでは、Xcodeのアーカイブ処理中に、アプリケーションのdSYM バンドルをxcarchive に含めることができません。
Qtでは、dSYM バンドルをxcarchive に含めるための回避策がオプションとして提供されていますが、これにはトレードオフが伴います。つまり、以下のCMake機能は正しく動作しなくなります:
$<TARGET_FILE:app>ジェネレータ式が、アプリのバイナリに到達しない無効なパスに展開される可能性があるCMAKE_RUNTIME_OUTPUT_DIRECTORY変数およびそれに関連するRUNTIME_OUTPUT_DIRECTORYターゲットプロパティは、設定されていても無視される- その他の未知の問題
上記の問題を軽減するには、以下の方法があります:
xcarchiveを作成する際のみこの回避策を有効にし、プロジェクトの開発中は有効にしない- 実行ファイルやライブラリは、
add_subdirectoryの呼び出し内ではなく、プロジェクトのルートディレクトリにのみ追加するようにしてください。
この回避策を有効にするには、プロジェクトを次のオプションで設定してください:
cmake . -DQT_USE_RISKY_DSYM_ARCHIVING_WORKAROUND=ONまたは、qt_add_executable やqt_add_library の呼び出しを行う前に、プロジェクト内で変数を設定してください:
set(QT_USE_RISKY_DSYM_ARCHIVING_WORKAROUND ON)
...
qt_add_executable(app)© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.