[ C++で開発 ]

Windows OS上のVisual StudioでQtを使う

QtはX Window System上のGUIツールキットの一つとして有名ですが、非X Window Systemへもポーティングされています。APIはC++言語として提供されています。Windows OS上Visual StudioでQtを使ってみます。

ただし、Windows用のQtは、非商用利用のGPLバージョンはMinGWコンパイラのみ対応しており、Visual C++は商用ライセンスでのサポートとなります。

インストールと設定

Windows用Qt (非商用利用)

Qt開発元のTrolltech社のWebサイトにあるQtダウンロードページから、Qt/Windows Open Source Editionを辿って入手します。MinGWとともにプレビルドされたパッケージとソースパッケージの2種類が提供されています。

ソースパッケージの展開

2007年11月14日現在の最新版

を入手し、解凍・展開します。展開先ディレクトリ名には、空白が含まれないようにします。

環境変数PATHの設定

QTを展開したディレクトリ下のbinを環境変数に追加します。

D:\qt-4.3.2> PATH=%PATH%;D:\qt-4.3.2\bin

環境変数QMAKESPECの設定

Visual Studio 2005のビルド設定を行うために、環境変数QMAKESPECを指定します。

D:\qt-4.3.2> set QMAKESPEC=win32-msvc2005

Qtのビルド実行

configure実行
D:\qt-4.3.2> configure -debug-and-release -D _CRT_SECURE_NO_WARNINGS -prefix=D:\lib
   :
Qt is now configured for building. Just run nmake.
To reconfigure, run nmake confclean and configure.

D:\qt-4.3.2> 

上記で設定している内容は以下のとおりです。

-debug-and-release
Qtライブラリは、デバッグ版、リリース版の双方を生成
-D _CRT_SECURE_NO_WARNINGS
セキュリティ上strcat等のバッファオーバフロー可能性あるライブラリを使用している箇所の警告を抑制
-prefix D:\lib
Qtのインストール先ディレクトリを指定
configureのオプションについて

このconfigureには、多数のQtライブラリ・ビルドに関するオプションがあります。以下は一部抜粋です。

基本設定

-release デバッグ情報を無効でビルド
-debug デバッグ情報付きでビルド(デフォルト)
-debug-and-release デバッグ情報あり・なし両方をビルド
-shared 共有ライブラリ形式でビルド(デフォルト)
-static 静的リンクライブラリ形式でビルド
-no-stl STL非対応
-stl STL対応用にビルド(デフォルト)
-no-qt3support Qt 3のサポートを無効にする

コンパイル・リンクに関する設定

-D <define> 
プリプロセッサへの定義を追加
-I <includepath>
インクルードパスを追加
-L <librarypath>
ライブラリパスを追加
-l <libraryname>
リンクするライブラリ名を追加

インストール先に関する設定

-prefix インストール先ディレクトリ

SQL関係の設定

-no-sql-<driver> <driver>用のSQLを無効にする(デフォルト:すべてのdriverが無効) <driver>に指定可能なものは、
mysql, psql, oci, odbc, tds, db2,
sqlite, sqlite2, ibase
-qt-sql-<driver> <driver>のSQLをQtライブラリに含める
-plugin-sql-<driver> <driver>のSQLを実行時にリンクするプラグインとして有効にする
-system-sqlite OSからのsqliteを使用する(?)
nmakeの実行
D:\qt-4.3.2> nmake
  :

Advanced compiler supportの展開

有志がQt Windows OpenSource版の対応コンパイラを増やしたパッチを開発しています。Acsプロジェクト・サイトから、acsファイル

を入手し、qtソースパッケージを展開したディレクトリに展開します。

Visual Studio環境設定されたコマンドプロンプトを起動し、Acsのバッチファイルを実行します。

D:\qt-4.3.2> installpatch43.bat

すると、別なコマンドプロンプトが現れます。which already exists! Assume -R? [n] と何回か問い合わせてくるので、ただ{Enter]キーだけ入力して進めました。([y] + [Enter]としたところ、このプログラムがエラーとなってしまうため)

その後、ビルドが始まりますが、以下エラーが発生してしまいます。

        link /NOLOGO /SUBSYSTEM:CONSOLE /incremental:no /OUT:"..\bin\qmake.exe"
@C:\Users\torutk\Temp\nm7B17.tmp
metamakefile.obj : error LNK2019: unresolved external symbol "public: __thiscall
 DspMakefileGenerator::DspMakefileGenerator(void)" (??0DspMakefileGenerator@@QAE
@XZ) referenced in function "public: static class MakefileGenerator * __cdecl Me
taMakefileGenerator::createMakefileGenerator(class QMakeProject *,bool)" (?creat
eMakefileGenerator@MetaMakefileGenerator@@SAPAVMakefileGenerator@@PAVQMakeProjec
t@@_N@Z)
..\bin\qmake.exe : fatal error LNK1120: 1 unresolved externals
NMAKE : fatal error U1077: '"C:\Program Files (x86)\Microsoft Visual Studio 9.0\
VC\BIN\link.EXE"' : return code '0x460'
Stop.

ビルド時の問題対応

shlwapi.hが見つからない

Visual C++ 2005 ExpressとMicrosoft Platform SDK で発生。shlwapi.hは、Core SDKには含まれないので、Platform SDKのインストール時に、"Microsoft Web Workshop(IE) SDK"をインストールする必要がある。

Qtプログラミング

Qt Tutorial 1のHello World!

まずは、Hello Worldプログラムを記述し、その環境でコンパイル・リンクし実行させる手順を確認します。

Hello World!のソースコード

Qt 3のHello Worldは、「そんなメンバー関数ない」とエラーになったため、新たにTrolltech社のチュートリアルを見ながら写経。

main.cpp

#include <QApplication>
#include <QPushButton>

int main(int argc, char* argv[])
{
    QApplication app(argc, argv);

    QPushButton hello("Hello world!");
    hello.resize(100, 30);

    hello.show();
    return app.exec();
}

Hello World!のコンパイル(コマンドプロンプト編)

WindowsOS上のVisual Studio環境でのQtアプリケーションのビルドには、Visual Studioのプロジェクトファイルを作成してGUI環境上でビルドする方法と、コマンドプロンプトからnmakeツールを使ってMakefileを作成してビルドする方法の2つがあります。

いずれも、qmakeツールを使ってプロジェクトファイル/Makefileを生成します。qmakeは、qmake専用プロジェクトファイル(*.pro)を読み込んで、指定されたビルドツール用の設定ファイルを生成する機能を持っています。また、空のディレクトリでqmake専用プロジェクトファイルの雛形を生成する補助機能を持っています。

まず、上記Hello World!のソースコード「main.cpp」を保存したディレクトリにおいて、qmake専用プロジェクトファイルの雛形を以下のコマンドを実行して生成します。

D:\Users\torutk\work> qmake -project

D:\Users\torutk\work> qmake /B
work.pro
main.cpp

D:\Users\torutk\work> 

work.proという名前でqmake専用プロジェクトファイルの雛形が生成されました。ファイル名は、実行したディレクトリ名(work)に拡張子(.pro)が付与されたものになります。qmake -projectを実行すると、その時点でそのディレクトリに存在するC++ソースファイル、ヘッダーファイルを検索してプロジェクトファイルの雛形が生成されます。

qmake -projectで生成されたwork.pro

######################################################################
# Automatically generated by qmake (2.01a) ? 11 18 11:16:49 2007
######################################################################

TEMPLATE = app
TARGET =
DEPENDPATH += .
INCLUDEPATH += .

# Input
SOURCES += main.cpp

アプリケーションで必要な設定があれば、このqmakeプロジェクトファイルに追記します。

続いて、nmake用のMakefileをqmakeツールで生成します。

D:\Users\torutk\work> qmake

D:\Users\torutk\work> qmake /B
debug
work.pro
main.cpp
Makefile
Makefile.Debug
Makefile.Release
release

D:\Users\torutk\work> 

nmakeでビルドします。

D:\Users\torutk\work> nmake

Microsoft (R) Program Maintenance Utility Version 9.00.20706.01
Copyright (C) Microsoft Corporation.  All rights reserved.

        "D:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\BIN\nmake.exe" -f
 Makefile.Debug

Microsoft (R) Program Maintenance Utility Version 9.00.20706.01
Copyright (C) Microsoft Corporation.  All rights reserved.

        cl -c -nologo -Zm200 -Zc:wchar_t- -Zi -MDd -GR -EHsc -W3 -w34100 -w34189
 -DUNICODE -DWIN32 -DQT_LARGEFILE_SUPPORT -DQT_DLL -DQT_GUI_LIB -DQT_CORE_LIB -D
QT_THREAD_SUPPORT -I"d:\qt-4.3.2\include\QtCore" -I"d:\qt-4.3.2\include\QtCore" 
-I"d:\qt-4.3.2\include\QtGui" -I"d:\qt-4.3.2\include\QtGui" -I"d:\qt-4.3.2\inclu
de" -I"." -I"d:\qt-4.3.2\include\ActiveQt" -I"debug" -I"." -I"d:\qt-4.3.2\mkspec
s\win32-msvc2005" -Fodebug\ @D:\Users\torutk\Temp\nm344.tmp
main.cpp
        link /LIBPATH:"d:\qt-4.3.2\lib" /NOLOGO /DEBUG /MANIFESTFILE:"debug\ex1.
intermediate.manifest" /SUBSYSTEM:WINDOWS /OUT:debug\ex1.exe @D:\Users\torutk\Te
mp\nmA89.tmp
        mt.exe -nologo -manifest "debug\ex1.intermediate.manifest" -outputresour
ce:debug\ex1.exe;1

D:\Users\torutk\work> dir /B debug
work.exe
work.ilk
work.intermediate.manifest
work.pdb
main.obj

D:\Users\torutk\work> 

デフォルトでは、debugビルドが実行されます。work.exeという名前で実行ファイルが生成されました。

※ディレクトリ名にはアプリケーションにちなんだ名前を与えるのがよいようです。または、qmake -projectに-oオプションを追加し生成する雛形ファイル名を指定することもできます。

Hello World!のコンパイル(Visual Studio GUI編)

コマンドプロンプト上でビルドするのもよいものですが、Windows上で開発している大半の人は、Visual StudioのGUI上でビルドできないと不満が大いに残るでしょう。

そこで、今度はqmakeツールにVisual Studioのプロジェクトファイルを生成させることにします。先と同様まずqmake専用プロジェクトファイルを生成します。今回はディレクトリ名にちなんだ名前でなく、指定した名前で生成するよう-oオプションでhello.proを追加しています。

D:\Users\torutk\work> qmake -project -t vcapp -o hello.pro

D:\Users\torutk\work> qmake /B
hello.pro
main.cpp

D:\Users\torutk\work> 

このときカレントディレクトリにプロジェクトへ登録される対象ファイルが一つもないとエラーとなります。

qmake -t vcapp -projectで生成されたhello.pro

######################################################################
# Automatically generated by qmake (2.01a) ? 11 18 11:45:00 2007
######################################################################

TEMPLATE = vcapp
TARGET = hello
DEPENDPATH += .
INCLUDEPATH += .

# Input
SOURCES += main.cpp

前回の違いは、TEMPLATEが"app"から"vcpp"に変化している箇所、TARGETが空でなく-oで指定した名前にちなんだものになっている箇所です。

Visual Studio用設定ファイルを生成します。

D:\Users\torutk\work> qmake

D:\Users\torutk\work> qmake /B
debug
hello.pro
hello.vcproj
main.cpp
release

D:\Users\torutk\work> 

Visual Studioから、hello.vcprojを読み込みビルドします。

なお、Visual Studio上でQtアプリケーションを実行するには、QtのbinディレクトリがVC++ディレクトリ設定で実行可能ファイルに追加されている必要があります。あらかじめ環境変数PATHにQtのbinディレクトリを追加しておくか、コマンドプロンプト上で環境変数PATHにQtのbinディレクトリを追加してからVisual Studioを/useenvオプション付きで実行する方法があります。

D:\Users\torutk\work> devenv /useenv
VCプロジェクトの課題

いったんqmakeからVC++用プロジェクトファイルを生成した後、ソースファイルを追加する、インクルードパスやライブラリを追加する、などの変更はどこに行えばよいのでしょうか?

qmakeプロジェクトファイル(この例ではhello.pro)に追加し、毎回VC++プロジェクトファイル(この例ではhello.vcproj)を生成するのが本来のやり方に思います。しかし、qmakeで記述できることはVC++の一部に過ぎず、現実にはVC++プロジェクトファイルに追記せざるを得ないでしょう。ファイルを1つ追加するたびにqmakeプロジェクトを編集しvcprojを再生成し、VC++で再度プロジェクトを開きなおすという作業は苦痛です。

ということで現実的には、最初のVC++プロジェクトファイルを生成するときにqmakeを使い、以後はVC++プロジェクトの世界で維持するということになりそうです。

MOCによるプリプロセスの実行

 クラス定義において、signal、slotの記述をしているクラスは、ビルドに先立ってMOCコマンドによる処理が必要です。qmakeツールがVC++用プロジェクトを生成するときに、そのディレクトリにあるクラス定義にsignal、slotが含まれる場合はMOCの実行を行うようになります。一方、クラス定義にsignal、slotが含まれないと、あとから追加してもVC++プロジェクトはMOCを実行しません。

Hello World!の実行

WindowsOSでは、実行時にDLLが置かれた場所が環境変数PATH上にないとエラーになります。コマンドプロンプト環境ではあらかじめPATHに設定していますが、Visual Studioの場合は何らかの手段でQTのbinディレクトリへのPATHを設定しておく必要があります。

D:\Users\torutk\work> debug\hello.exe


This page is written by Toru TAKAHASHI.(torutk@02.246.ne.jp)