wxWidgetsで、あまり説明されていない、気になる事を、 書いてみようと思います。
IMPLEMENT_APP と OnInit( ) が、実際どのような実装になっているのか試してみようと思います。
#include <wx/wx.h>
class App : public wxApp
{
public:
bool OnInit()
{
std::cout << "Hello" << std::endl;
return true;
}
};
IMPLEMENT_APP(App)
このコードをコンパイルして、端末(ターミナル)で実行すると次のようになります。
Hello
「Hello」と表示された後に、アプリケーションが終了していないことが分かります。OnInit( ) は、true; 返すと、アプリケーションは起動し続けます。^C(Control + C)で終了させてください。
OnInit( )の中の return true; を return false; と変更すると、次のようにアプリケーションが自動的に終了します。
Hello
$
IMPLEMENT_APP(App)をIMPLEMENT_APP(wxAPP)と変更して、引数にスーパークラスを与えると、アプリケーションは何もせず起動し続けます。
wxApp の OnInit( ) は仮想関数として定義されていますが、return true; 以外は 何も実装されていないことが分かります。
ウィンドウも表示させてみます。
#include <wx/wx.h>
class App : public wxApp
{
public:
bool OnInit()
{
std::cout << "Hello" << std::endl;
//Exit();
(new wxFrame(NULL, -1, "Hello"))->Show();
return true;
}
};
IMPLEMENT_APP(App)
ウィンドウも無事に表示されます。
return true; を return false; に変えると、「Hello」とだけ表示されてアプリケーションが終了します。おそらくウィンドウは一瞬だけ表示されて終了しているので、見えないだけだろうと思います。
⁄ ⁄ Exit(); のコメントを外して、Exit(); とすると、その時点でアプリケーションが終了されます。
次に、IMPLEMENT_APP の部分を、main( ) 関数で書いてみます。
#include <wx/wx.h>
class App : public wxApp
{
public:
bool OnInit()
{
std::cout << "Hello" << std::endl;
return true;
}
};
int main()
{
wxApp *app = new App();
app->OnInit();
return 0;
}
main( ) 関数から OnInit( ) を呼び出した場合は、ウィンドウは表示できません。
#include <wx/wx.h>
class App : public wxApp
{
public:
bool OnInit()
{
std::cout << "Hello" << std::endl;
(new wxFrame(NULL, -1, "Hello"))->Show();
return true;
}
};
int main()
{
wxApp *app = new App();
app->OnInit();
return 0;
}
このコードはコンパイルはできますが、実行結果は、プラットフォームによって違います。Linux では実行時エラーになりますが、macOS では次のように表示されます。
Hello
Segmentation fault: 11
どちらにしても、main() 関数からの呼び出しでは、 ウィンドウは表示できないみたいです。
次のコードをコンパイルして、ターミナルで実行してみてください。
#include <wx/wx.h>
class Hello : public wxFrame
{
public:
Hello();
~Hello();
};
class App : public wxApp
{
public:
virtual bool OnInit();
};
Hello::Hello() : wxFrame(NULL, -1, wxT("Hello wxWidgets!"))
{ std::cout << "Created" << std::endl; }
Hello::~Hello()
{ std::cout << "Deleted" << std::endl; }
IMPLEMENT_APP(App)
bool App::OnInit()
{
Hello *hello = new Hello();
hello->Show();
return true;
}
// 起動すると次のように表示されます。
Created
// 終了すると次のように表示されます。
Deleted
OnInit( ) の中で、hello ポインターを delete する記述はしていません。しかし、
Hello クラスのインスタンスは、アプリケーション終了時に
無事に、破棄(メモリー解放)されるみたいです。
OnInit( ) 内のポインターは自動的に delete されると思ってもいいみたいです。
wxWidgets 2.x では、Connect しか使えません。
wxWidgets 3.x では、Connect と Bind の両方が使えます。
wxWidgets 2.x では、クラス内で用いるすべての文字列で wxT を使わなければなりません。
wxWidgets 3.x では、クラス内で用いる日本語などの2バイト文字列には wxT を使わなければなりませんが、英語などの1バイト文字列には wxT を使う必要はありません。
macOS の wxWidgets 3.x では、日本語も英語も wxT を使う必要はありません。