【GUI】wxWidgets(旧wxWindows) その5【サイザー】
クロスプラットフォーム GUI ライブラリの wxWidgets (旧 wxWindows)についてのスレ。 本家 ttp://www.wxwidgets.org/ wxWindows日本語プロジェクト ttp://wxwindowsjp.sourceforge.jp/ Cross-Platform Programming with wxWidgets ttp://wxwidgets.info/ Let's wxWidgets ttp://dot-gray.s33.xrea.com/ wxWindowsで始めるC++ GUIプログラミング ttp://www.h3.dion.ne.jp/~k5_n/wxwin/ wxWidgets でクロスプラットフォーム GUIアプリを作ろう ttp://0xcc.net/pub/uu-2004-08/ 前スレ 【GUI】wxWidgets(旧wxWindows) その4【サイザー】 http://pc12.2ch.net/test/read.cgi/tech/1214657360/ 完全テンプレートライブラリにしたら軽くなるんだろうか >>694 でも wxWidgets がやっていることの割にはリンクされるバイト数が多すぎる 感じがする。 基本、Win32をラッピングしているだけなのだから、2MBも必要ない。 ラッピングしてるだけじゃなくマルチプラットフォームのために徹底した抽象化をしてるんでしょ とソースも読まず推測 >>697 でもソースを呼んでみたら、たとえば、wxListCtrl なんかは、 Win32 の LIST CONTROL をそのまま使っていた。 DrawRect()などで書いているわけではない。 ただし、wxGenericListCtrl だったかは、DrawRect()みたいなグラフィック 関数で独自に描画していた。が、それは、Windows版では簡単には使えない という噂を聞いたが。 >>697 wxWidgets の基本設計は、Widgetは、OS nativeの物を使うが、 どんなサイズであっても対応できるように Sizer で Layout を コントロールする、という物。 なので、抽象化はサイズと配置程度で済むはずなのだが・・・。 >>696 >>697 の言ってることが正しい。 --------------------- wxWidgets --------------------- Win32 | GTK | Cocoa etc... --------------------- wxWidgetsは通常のGUI用ライブラリに一枚レイヤを重ねた形になるので 型情報・関数テーブルの情報だけで結構容量食う >>692 ASCIIモードでビルドするのはやめておいたほうがいい 日本語使えないし というかなぜMonolithicビルドにこだわるのか… 普通にconfigureからビルドしてdllごと配布したほうが立ち上がりは早い wxWidgets の samples で ListCtrl 関連を見てみたが、ヘッダを ドラッグしようとしてもドラッグできないので、ドラッグによる列の入れ替 えは出来ないようだった。 実は、Win32 の LIST CONTROL は、 ・マウスドラッグによる自動的な列の入れ替えをした際、どこにどの列が 行ったかを掌握するには注意が必要。動作を知るには基本的に実験を必要 とする。 ・第1カラムを削除すると第2カラム以降を削除した時とは同じとは言えない 奇妙な動作をする。奇妙な動作と言ったがバグに近い。 こういった辺りがどう処理されているか知りたかったのだが、サンプルでは 故意か偶然か、全くそこに触れていないようだった。 wxWidgets の samples で ListCtrl 関連を見てみたが、ヘッダを ドラッグしようとしてもドラッグできないので、ドラッグによる列の入れ替 えは出来ないようだった。 実は、Win32 の LIST CONTROL は、 ・マウスドラッグによる自動的な列の入れ替えをした際、どこにどの列が 行ったかを掌握するには注意が必要。動作を知るには基本的に実験を必要 とする。 ・第1カラムを削除すると第2カラム以降を削除した時とは同じとは言えない 奇妙な動作をする。奇妙な動作と言ったがバグに近い。 こういった辺りがどう処理されているか知りたかったのだが、サンプルでは 故意か偶然か、全くそこに触れていないようだった。 >>700 >wxWidgetsは通常のGUI用ライブラリに一枚レイヤを重ねた形になるので >型情報・関数テーブルの情報だけで結構容量食う オイラはコンパイラの基本部分に詳しいが、それだけで1MBなどには ならない。 >>694 諦めることも手かも知れないけど、やっている事の規模とサイズとの ギャップに納得がいかない人もいるはず。 wxWidgetsはラッピング・ライブラリの一種。 8bit時代、16bit時代を知る人にとって、Widget 程度が64KBを超える 事があってはならない。どういうプログラミングをしたら2MBにもなる のか。 >>703 >>704 一理あるのでちょっとメーリングリストを探ってみたり まず、wx/wx.hがいろいろなヘッダファイルを事前にincludeしているので それがバイナリサイズの増加の一因になっているらしい [wxMSW]: why EXE-files are so large? https://groups.google.com/d/msg/wx-users/psTmm3nB6AU/9j6-4ir95-gJ >>591 のライブラリを samples/keyboard にも使ってみたら、 keyboard.exe のサイズを 1,619,968 にまで縮小することに成功した。 コンパイラは MinGW32 のまま。 条件は:release, 非UNICODE(ASCII), SHARED=0(静的リンク), MONOLITHIC = 1 どうやら MONOLITHIC であるかどうかは最終 exe サイズには関係してないらしい。 ライブラリと言うのは集めてもばらしても、最終 exe のリンク結果には影響を 及ぼさない事が基本なので、元々当たり前なことなのだが。 [samples/keyboard] $ mingw32-make -f makefile.gcc BUILD=release UNICODE=0 SHARED=0 MONOLITHIC=1 [samples/keyboard/makefile.gcc の修整] ------------------------------------------------------------------------------------- $(OBJS)\keyboard.exe: $(KEYBOARD_OBJECTS) $(OBJS)\keyboard_keyboard_rc.o $(CXX) -o $@ $(KEYBOARD_OBJECTS) $(__DEBUGINFO) $(__THREADSFLAG) -L$(LIBDIRNAME) -Wl,--subsystem,windows -Wl,--gc-sections -Wl,-s -mwindows $(____CAIRO_LIBDIR_FILENAMES_p) $(LDFLAGS) $(__WXLIB_CORE_p) $(__WXLIB_BASE_p) $(__WXLIB_MONO_p) $(__LIB_TIFF_p) $(__LIB_JPEG_p) $(__LIB_PNG_p) -lwxzlib$(WXDEBUGFLAG) -lwxregex$(WXUNICODEFLAG)$(WXDEBUGFLAG) -lwxexpat$(WXDEBUGFLAG) $(EXTRALIBS_FOR_BASE) $(__UNICOWS_LIB_p) $(__GDIPLUS_LIB_p) $(__CAIRO_LIB_p) -lkernel32 -luser32 -lgdi32 -lcomdlg32 -lwinspool -lwinmm -lshell32 -lcomctl32 -lole32 -loleaut32 -luuid -lrpcrt4 -ladvapi32 -lwsock32 -lodbc32 -------------------------------------------------------------------------------------- 上記は original の makefile.gcc に、 -Wl,--gc-sections -Wl,-s を追加しただけ。 wxWidgets の samples で ListCtrl 関連を見てみたが、ヘッダを ドラッグしようとしてもドラッグできないので、ドラッグによる列の入れ替 えは出来ないようだった。 実は、Win32 の LIST CONTROL は、 ・マウスドラッグによる自動的な列の入れ替えをした際、どこにどの列が 行ったかを掌握するには注意が必要。動作を知るには基本的に実験を必要 とする。 ・第1カラムを削除すると第2カラム以降を削除した時とは同じとは言えない 奇妙な動作をする。奇妙な動作と言ったがバグに近い。 こういった辺りがどう処理されているか知りたかったのだが、サンプルでは 故意か偶然か、全くそこに触れていないようだった。 >>694 >あとコア、主要のライブラリのビルドから、ダイナミックリンクを徹底してOSに丸投げしたら小さくなるだろ。 「>>692 」で示した Win32 import library は、Windows のシステム DLL をリンクするための小さなライブラリ。例えば、 libcomctrl32 をリンクしていても、実際は、comctrl32.dll が動的リンク される。libcomctrl32.a は、MinGW32 が用意している import library で: /xxx/CodeBlocks/MinGW/lib/libcomctl32.a # 86,428 bytes C:/WINDOWS/system32/comctl32.dll # 617,472 bytes のように、windows/system32 の comctrl32.dll を動的リンクするための 呼び出し部分だけを提供する小さなライブラリ。 MONOLITHIC の値が違うと別の *.o が作成されることが判明。 以下は、SHARED=0(静的リンク)の場合の、MONOLITHIC が 0 と 1 の場合。 CORELIB_CXXFLAGS = $(__DEBUGINFO) $(__OPTIMIZEFLAG) $(__THREADSFLAG) \ $(GCCFLAGS) -DHAVE_W32API_H -D__WXMSW__ $(__WXUNIV_DEFINE_p) \ $(__DEBUG_DEFINE_p) $(__NDEBUG_DEFINE_p) $(__EXCEPTIONS_DEFINE_p) \ $(__RTTI_DEFINE_p) $(__THREAD_DEFINE_p) $(__UNICODE_DEFINE_p) \ $(__MSLU_DEFINE_p) $(__GFXCTX_DEFINE_p) -I$(SETUPHDIR) -I..\..\include \ $(____CAIRO_INCLUDEDIR_FILENAMES) -W -Wall -DWXBUILDING -I..\..\src\tiff \ -I..\..\src\jpeg -I..\..\src\png -I..\..\src\zlib -I..\..\src\regex \ -I..\..\src\expat\lib -DwxUSE_BASE=0 $(__RTTIFLAG) $(__EXCEPTIONSFLAG) \ -Wno-ctor-dtor-privacy $(CPPFLAGS) $(CXXFLAGS) MONOLIB_CXXFLAGS = $(__DEBUGINFO) $(__OPTIMIZEFLAG) $(__THREADSFLAG) \ $(GCCFLAGS) -DHAVE_W32API_H -D__WXMSW__ $(__WXUNIV_DEFINE_p) \ $(__DEBUG_DEFINE_p) $(__NDEBUG_DEFINE_p) $(__EXCEPTIONS_DEFINE_p) \ $(__RTTI_DEFINE_p) $(__THREAD_DEFINE_p) $(__UNICODE_DEFINE_p) \ $(__MSLU_DEFINE_p) $(__GFXCTX_DEFINE_p) -I$(SETUPHDIR) -I..\..\include \ $(____CAIRO_INCLUDEDIR_FILENAMES) -W -Wall -DWXBUILDING -I..\..\src\tiff \ -I..\..\src\jpeg -I..\..\src\png -I..\..\src\zlib -I..\..\src\regex \ -I..\..\src\expat\lib -DwxUSE_BASE=1 $(__RTTIFLAG) $(__EXCEPTIONSFLAG) \ -Wno-ctor-dtor-privacy $(CPPFLAGS) $(CXXFLAGS) 違いは、-DwxUSE_BASE の部分で、 MONOLITHIC = 0 の場合 : -DwxUSE_BASE=0 // #define wxUSE_BASE 0 MONOLITHIC = 1 の場合 : -DwxUSE_BASE=1 // #define wxUSE_BASE 1 となっている。 例えば、/xxx/src/msw/dc.cpp は、同じソースに対し make に渡すオプションに応じて 以下の2種類の *.o ファイルが作成される。 1つ目は、MONOLITHIC=0の時に作られ、2つ目は、MONOLITHIC=1の時に作られる。 ifeq ($(USE_GUI),1) $(OBJS)\corelib_dc.o: ../../src/msw/dc.cpp $(CXX) -c -o $@ $(CORELIB_CXXFLAGS) $(CPPDEPS) $< endif ifeq ($(USE_GUI),1) $(OBJS)\monolib_dc.o: ../../src/msw/dc.cpp $(CXX) -c -o $@ $(MONOLIB_CXXFLAGS) $(CPPDEPS) $< endif ソースを見ると、wxUSE_BASE の値に応じて場合分けされている箇所が多数ある。 つまり、MONOLITHIC の 0 と 1 の違いは単に *.o ファイルの集め方の問題では無い。 コンパイル時点のソース自体が変更されるのである。故にリンク後の*.exe のサイズ が変わって来ても不思議は無い。これは驚くべきことである。 >>713 コンパイルオプションまで変えてしまって何をやっているかと言うこと なんだよ。ライブラリの集め方だけの問題じゃないって事なんだ。 ライブラリの動作が変わってしまい、MONOLITHIC が 0 と 1とで結果が違うことに 悩まされる可能性もある。 単にライブラリのオブジェクトの集め方(含み方)の問題では無いとすると、MONOLITHIC オプションの意味はいったい何かと言う問題になる。 また、最終EXEが大きくなる理由として、アプリが使ってないオブジェクトを 非常に基本的なライブラリの一部が参照している可能性がある。 そしてそのオブジェクトが別のオブジェクトを勝手に参照して・・・という 事が続いて最終EXEのサイズが肥大化してしまっているのかも知れない。 http://wiki.wxwidgets.org/WxWidgets_Build_Configurations 「MONOLITHIC=1 : Packages all libraries in a single file. (Note: do not combine this option with a static build.)」 とあった。static build の時は、MONOLITHIC=1 にするな、と 書かれている・・・。 configure を試してみたら、configureのヘルプ通りには行かなかった: ・以下、xxx = wxWidgets-2.8.12 とする。/xxx/ に configure スクリプトがある。 ・configureを使用するために、単なるcmd.exeではなくcygwin環境が必要であった。 ・cygwinを起動する際、cygwin に入ってからの PATH が、 (MinGWのbin) : /usr/local/bin/ : /usr/bin/ : (Winからのbin) の順になるようにした。 ・カレントを /xxx/ にして configure した。configure の引数には少なくとも ・--build=i686-pc-mingw32 --host=i686-pc-mingw32 --target=i686-pc-mingw32 を指定し、例外, rtti, regex, zlib, jpeg, png, tiff は無効にするオプション を設定した。他にも無効にしたものも多い。大量に及ぶので スクリプトに記述した。 ・Makefileが普段の /xxx/build/msw/ ではなく、/xxx/ に作られた。 ・/xxx/samplesのサブディレクトリにあるMakefileが書き換えられた。 ・setup.h が、 /xxx/lib/wx/include/msw-ansi-releasw-static-2.8/wx /xxx/lib/wx/include/msw-ansi-releasw-2.8/wx の二箇所に作成された。元々各所にあるが、例としては /xxx/include/ws/msw や /xxx/lib/gcc_lib/msw/wx にある。 ・/xxx/ で make[ret] してみた。 ・途中で例外を有効にするように言われたので有効にした。 ・regex, zlib, jpeg, png, tiff は全て無効にしていたにも関わらず、 src/regex, src/zlib, src/jpeg, src/tiff にしかない *.h ファイルが見つから ないエラーとなった。。 そこで、Makfileを直接修整して、CPPFLAGS に -I 指定によって、上記ディレクトリ を最後尾に追加した。 ・make には成功した。 ・/xxx/ に大量の *.o ファイルが作られ、*.a は /xxx/lib/ に作られた。 /build/msw から make した場合は、/xxx/lib/gcc_lib に作られるのと対照的 である。 ・/xxx/samples/console で make してみたら、成功した。 ・「プロシージャエントリポイント _gxx_persolanity_v0 が ダイナミック リンク ライブラリ libstdc++-6.dll から見つかりませんでした。」 のメッセージボックスが出て起動できず。 ・Makefileを書き換えて、LIBS の最後に -lstdc++ を書いても症状は治まらない。 ・regex, zlib, jpeg, png, tiff は全て無効にしていたにも関わらず、 src/regex, src/zlib, src/jpeg, src/tiff にしかない *.h ファイルが見つから ないエラーとなった。。 そこで、Makfileを直接修整して、CPPFLAGS に -I 指定によって、上記ディレクトリ を最後尾に追加した。 ・make には成功した。 ・/xxx/ に大量の *.o ファイルが作られ、*.a は /xxx/lib/ に作られた。 /build/msw から make した場合は、/xxx/lib/gcc_lib に作られるのと対照的 である。 ・/xxx/samples/console で make してみたら、成功した。 ・「プロシージャエントリポイント _gxx_persolanity_v0 が ダイナミック リンク ライブラリ libstdc++-6.dll から見つかりませんでした。」 のメッセージボックスが出て起動できず。 ・Makefileを書き換えて、LIBS の最後に -lstdc++ を書いても症状は治まらない。 console.cpp の中身を printf() だけを使う4行の main() 関数だけに 書き換えてみたら問題なく起動して普通に文字列が表示された。 なので、MinGW 環境の問題ではなさそう。 wxPrintf()だけを使った console 版 hello world が、static link で 96,468 bytes で済んだ。 ところが、wxString を使った場合、作成した exe を実行しようとすると >>721 後半で書いたメッセージ・ボックスが出て起動できない。 libstdc++がダイナミックリンクになってるだけだろ。 >>724 ダイナミックライブラリであるところの libstdc++-6.dll は既に読み込めているんですわ。 「libstdc++-6.dll から見つかりませんでした。」 の「から」がそれを表している。 なお、configureを使わずに、build/msw から build したライブラリだと wxStringとwxPrintfだけを使ったconsoleアプリは、静的リンクでも 451,584 バイトで済むことが判明。こちらはちゃんと起動できる。 パスが通ったところに互換性のない別バージョンのdllがあるんだろ。 mingwだとsjljとdw2の2種類あるから。 MinGW/bin を i686-pc-mingw32-g++ と MinGW/bin/g++ は別物らしくコンパイラのサイズ (作ったプログラムのサイズではなく変換機のサイズ)がそもそも違う。 また、前者では、リンク段階で何もエラーを出さないが、 後者では、ちゃんと、_gxx_persolanity_v0 や _Unwind_Resume が undefined reference というエラーになる。 >>726 最初、xxx dw2 yyy.dll が見つからない、と言うメッセージ・ボックス が出たのだが、そのdllを検索すると MinGW/bin にある事が分かって、 そこにパスを通したらそのメッセージ・ボックスは出なくなった。 その代わりに >>721 のメッセージ・ボックスが出るようになった。 結論的に言うと、自分のローカルにMinGW32 の別バージョンが沢山あった。 サンプルのコンパイルに使われたのと同じMinGW32のbinだけをパスに 設定してからサンプルを起動すると実行できるようになった。 実行結果も問題ない。実行ファイルはstripするとサイズが小さくなったが、 >>691 のライブラリをリンクした物よりも大きくなってしまった。 [wxStringを使った最小な cui program のサイズ] ・>>691 のwxライブラリ使用時 : 451,584 bytes コンパイラは CodeBlocks付属のMinGW ・configureしたwxライブラリ使用時 : 547,342 bytes コンパイラは cygwinにインストールしたMinGW [wxFrameを使った最小な gui program のサイズ] ・>>691 のwxライブラリ使用時 : 1,611,264 bytes コンパイラは CodeBlocks付属のMinGW なお、今回は、>>719-720 のような不具合を回避するため、RegExや、png,jpeg,tiff,zlib などはconfigureで有効にしておいた。そうすると>>720 の最初のヘッダファイル問題は 消えたので、何か良いことがあるかと思ったから。ただし、様子を見るとそれは必要なかった かも知れない。サイズ縮小のためには disable にすべきかも。 よかったな -Wl,-Bstatic -lstdc++ -Wl,-Bdynamic にすればlibstdc++とスタティックリンクできるかもな cygwin版のMinGWと、cmd.exe 版のMinGWって結構違うような気がしてきた。 Makefileなんかもcygwin版だと/cygdrive/c/xxx/yyy/zzz の形式になっている のに対し cmd.exe版は c:\xxx\yyy\zzz になっているらしい。 また、コンパイラに -I 指定したパスなんかも同様の違いがあるらしく、 configureが作ったMakefileは、cygwin版MinGW用で、 cmd.exe版のMinGWでは、#inclde "wx/setup.h" のパスが探せなかったり する。 build, host, target の指定は、全て mingw を指定していたのだから、 cygwinが入り込む余地は無かったはず。これは、configure.inか、 Makefileのどちらかを自前で修整する必要がありそう。 さらに、makeが(?) process_begin: CreateProcess(NULL, sh xxxxxx, ...) failed. というエラーを出すことがあり、その原因を探る必要もある。 cygwin版のMinGWと、cmd.exe 版のMinGWって結構違うような気がしてきた。 Makefileなんかもcygwin版だと/cygdrive/c/xxx/yyy/zzz の形式になっている のに対し cmd.exe版は c:\xxx\yyy\zzz になっているらしい。 また、コンパイラに -I 指定したパスなんかも同様の違いがあるらしく、 configureが作ったMakefileは、cygwin版MinGW用で、 cmd.exe版のMinGWでは、#inclde "wx/setup.h" のパスが探せなかったり する。 build, host, target の指定は、全て mingw を指定していたのだから、 cygwinが入り込む余地は無かったはず。これは、configure.inか、 Makefileのどちらかを自前で修整する必要がありそう。 Makfileの / を \ で置換して、/cygdrive/x/ を x:/ にしてみたら結構 行ける。途中、pch でファイルにアクセス拒否で書き込めないと言われるが、 もう一度 make すると、何事も無かったように続行する。 >>732 wx アプリのサイズダウンの仕方関連なんだけど。 作ったバイナリのサイズなんてwxWidgetsのビルド方法によって大きく変わるうえ、 最終的に使い物にならないライブラリの出来上がりとなるのが目に見えている 本当に必要なものだけを炙り出すつもりなら止めはしないが、どう考えても徒労でしかないと思うぞ 正直wxWidgetsのバイナリサイズの話以外はほとんど既出だし CygwinとMinGWの仕様の違い、クロスコンパイラのターゲット、configureの基本 それらの件に関しては自分のブログにでも書いていてほしい まあ一応上から目線でコメントしとくと >>725 libgccの存在に関して勉強不足、>>726 の言うとおりdllの種別が2種類ある DLLにするよりもlibgccだけスタティックリンクしたほうがいいが、libtoolにかませるのが 割と面倒なので一緒に配布したほうが楽、まぜこぜにするとか初心者くさい >>727 クロスコンパイラとネイティブコンパイラを混同している >>731 もうネット上で一万回は言及されたであろうCygwinとMinGWのファイルパスについて 述べているが無駄なのでやめてほしい、てか環境を混ぜるな >>737 最後の段落について。 ・cygwin版のMinGW ---> ファイル名はUnixライクな /cygdrive/c/xxx/yyy/zzz 形式だが、 出来た実行ファイルはcygwinが無くても動作する。 ユーザー・プログラムからは主にWin32 APIを使う。 ・cmd.exe版のMinGW ---> 何もかも Windows 用。ファイル名もDOS式、 出来た実行ファイルは Windows のみで動作。 ユーザー・プログラムからは Win32 API を使う。 ・cygwinのgcc ---> cygwin環境で動く実行ファイルを作成する。 ユーザー・プログラムからはUnix系関数を使う。 >>738 スレ違いだ、こっちでやれ Cygwin + MinGW + GCC 相談室 Part 7 http://peace.2ch.net/test/read.cgi/tech/1357019230/ あとMinGWはcmd.exeではなくminttyから使うべきだ さっさとネットで資料を探す作業に戻るんだな ちなみに c:\cygwin\bin と c:\cygwin\usr\local\bin にパスを通せば、 cmd.exe からでも cygwin のコマンドが実行できるようになる。 gccもlsもmakeも。ここでbashを起動すればcygwin環境になる。 久しぶりに2ちゃん観に来たら wxのスレめっちゃ野比てて嬉しい wx のソースを修正したら、wxString() を使った最小サンプルが、 静的リンクしても 70KB で済むようになった。 PATHには、MInGW/bin しか設定せずにテストしているので、wx の DLL がリンクされている可能性は無く、間違いなくスタンド・アローンの プログラム。 ちなみに、wx のソースを修正しなければ、451,584 バイトになってしまう。 >>729 に書いたものとほぼ同じプログラムだから。 wxというよりgccとライブラリのお話で伸びている >>742 dllの依存関係すらまともに調べられないのか dependency walkerとかobjdumpとか使え mingw入ってるならlddコマンドでもいける>依存動的ライブラリ ただ、パス設定を空にして起動できるかどうか見るのも1つの確実な方法。 GUIアプリのサイズ縮小を試みていたが、断念するかも知れない。 △性格が悪い ○無駄が嫌い ◎無駄な事をしてる奴が嫌い >>749 何も悪いことをせず、自分にも害を与えない人を嫌うのが性格が悪いんだよ。 公園の蚊を駆除するのに外側からじゃなくて内側から始めるとかが無駄 自分にも危害が及ぶので嫌 >>749 >>750 言われた側が一方的に立場が悪くなるという効能は興味深いと思う 言ったもん勝ちという現象は絶対にあるのだ >>751 生死にかかわる難しい判断を 「無駄なこと」に無理やりおしこめた詭弁 物事を矮小化させる効果もある >>751 正直言って、今回のこととの関連も分からない。 それ以前に外側から、内側から、ということの意味が全く分からない。 まるで会話ロボットが生成した文書のようだ。 >>752 この文書も意味不明。人間が書いたとは思えない全く理解できない文書だ。 俺の大好きなwxWidgetsスレがめちゃんこ糞スレになって泣きそう 案の定あらし化したか これ以上触れないで放っとくの推奨 wxWidgets って、GTK をバックエンド(port to)に使うことも出来るらしい ね(wxGTK)。 上位のツールキットが、下位のツールキットに被さっているってことか。 X11 を直接バックエンドに使うのともまた違うのかな? \ ヽ | / / \ ヽ / / ‐、、 殺 伐 と し た ス レ に 鳥 取 県 が ! ! _,,−'' `−、、 __/\ _,,−'' `−、、 _| `〜┐ _,,−'' _ノ ∫ _,.〜’ / ───────‐ ,「~ ノ ───────‐ ,/ ` ̄7 | 島 根 県 / _,,−' ~`⌒^7 / `−、、 _,,−'' 丿 \, `−、、 ,'´\ / _7 /`⌒ーへ_,._⊃ /`i ! \ _,,-┐ \ _,.,ノ r‐-、、 / ! ゙、 `ー--<´ / L. ,〜’ ゙、 >−一'′ ,' y' U `ヽ/ / ヽ ヽ '´ U イ ____ / __ | \____\ ___/__ / ̄ ____|____ \ \____\ //ヽ /___ /|\ \ \____\ / / ヽ / /__ / | \ \_______ / / / / / / | \ | \ / / / / _/ __/ | \__ | \  ̄―_ >>756 X11は組み込み向けのportなので一般的には使われないよ(メンテされてるかもよくわからん) Linuxでの使用の際はGTKベースと思っていた方がいい つまりwxWidgetsのクラスやメソッドでコードを書いてLinux上でビルドするとGTKアプリができる 最近はwxQtというwxWidgetsからQtをバンドルするイカれたプロジェクトが本流にマージされたようだが… >>759 目的は、Qtベースのデスクトップ(KDE)でもwxWidgetsアプリを使うためとか (→まあKDE上でGNOMEアプリを使うツールもあった気がするのだが…) あとQtをバンドルすることでAndroid対応も果たしていた(実用性は不明) wxWidgetsで、POPUP Menu (Windows では、Context Menu が正式名称かも)を作る場合、 どうしてますか? 特に、CodeBlocksなどのIDEで行う場合の最良の作法が知りたいです。 自分は、基本的な wxSmith の使い方が分かったところです。 MenuItem作って SubMenu作って AddItem >>762 それは手作業の場合ですよね。 そこの部分は対した手間ではないですが、 イベント・ハンドラを*.cpp, *.h, EVENT_TABLEの全てに書くのが面倒で。 >>764 これ、今ちょうど数秒前に見終わったところだった。 これ見てると、 1. wxSmithでwxFormをエディット中に、「MenuBar」ではなく「Menu」ボタンを押して 「要素」を追加する。 そうするとwxSmithの上辺に要素のアイコンが並んでいる末尾に新しいアイコンが追加される。 2. 追加したMenu要素に名前を付ける。 3. wxFormの中に既に配置してあったwxPanelに対して、マウス右UPイベントに対応するハンドラを追加する。 4. そのハンドラの中に、手作業で PopupMenu()関数の関数呼び出しを書き、 その引数に2.でMenuに付けおいた名前を書く。 こここまでは大した手間じゃない。 その後が問題で、EVENT_TABLE の「自動的にwxSmith が作成する範囲」の外側(直後)に、 POPUP MENUのMENU項目数分だけ、手作業で Connect() 関数を書いている。メニュー項目が7個だと、 Connect()関数も7個書く。それぞれ、MENU項目に付けた ID_xxxx の値と、対応する自前の イベント・ハンドラの関数名を引数に指定して。 最後の部分が知りたかった事で、POPUP MENUの作り方としてはかなり面倒な方法に属する。 7個のメニュー項目にイベント結びつけるのに7行コード書くのって、そんな突出して面倒か? >>767 それは、「EVENT_TABLE」の箇所だけの話で、実際は、*.h に メンバ関数宣言を7つ書き、*.cpp に Zzzz Ccccc::OnXxxxx( Yyyy *pYyyy ) { return Qqqqq; } みたいなの(4行)を 7 つ書く必要がある。 少なくとも (1+1+4)*7 = 42 行だ。 なんで今更wxSmithなんだよ古臭いな なんでイベントテーブル使ってんだよ古臭いな 黙ってwxFormBuilder使ってみろよメッチャ簡単で笑えるぞ >>770 IDEとの組み合わせは? IDEがサポートしていなくてもいけるんだろうか? >>771 ちんまい個人用ツールしか作った事が無いから大規模プログラムでどうなるかは分からんが、 俺はwxFormBuilderでGUIデザインし、VisualStudioでコード書いてる。 GUI部品を追加したくなったら、いつでも追加編集できる。 もちろんイベント追加も問題ない。 VSでコード書きつつGUIエディットしても、VSにフォーカスを移したら勝手に読み込み直してくれる。 今まで書いたコードがGUI生成時に消去される事も無い。 これにはちょっと条件があるけどな。 >>772 POPUP MENU を作る時、EVENT_TABLE を使わずに何か良い方法で やってくれるのかな? wxFormBuilderかあ もはやクロスプラットフォームでGUIがGUIでデザインできるのか(しかもフリーソフトウェア) VSは、外部エディタでソースを編集した場合、VSに戻ると自動的に再ロード してくれる機能がある事は知ってる。これは昔からある機能。 >>773 凝りに凝ったメニューは知らんが、ポップアップメニューの作成および メニュークリック時のイベント生成なんかは全部wxFormBuilder上で出来る。 従来のイベントテーブルでも生成してくれるし、Connect関数を使ったイベント生成も出来る。 今はConnectも古くてBindがトレンドらしいが、詳しくは知らない。 http://www.dotup.org/uploda/www.dotup.org5309542.zip.html 参考までに、wxFormBuilderのみで作ったサンプルコードを添付する。 自分で書いたのはmain.cppとthis->Close();だけ。 VS2013 + wxWidget3.0.1でビルド確認済。 >>776 これは、どうやって作ったの? 生成されたコードも参考にはなるけど、wxFormBuilder上での操作方法が 知りたい。 >>777 説明がめんどくさいから、wxFormBuilderでこの「wxMenuTest.fbp.」を開いて確認してくれ。 あとは適当に触ってれば理解できるだろ。 http://www.dotup.org/uploda/www.dotup.org5310926.zip.html 適当にGUIを作ったらF8キーでメインクラスを生成して、 その後F6キーでサブクラスを生成すればいい。 あとは添付した「main.cpp」みたいなコードを書いてビルドすれば目出度くGUIプログラムの完成だ。 レイアウトやイベントの仕様が 前もって分かって一発で決まるようなものならいいけど そうでない場合は細かいテクが必要になるんだよなぁ VB,delphi,VisualStudio他のポトペタとは違って 基本クラスや継承クラスの生成コードは 上書きしちゃってよしなにしてくれないから目視マージが必要になる で、それならxrcでいっかなとなったりとね あとは最近のバージョンでは修正されてるかも知らないけど splitter > panel > sizer > xxx の深いネストが嫌いだったな バグだよね >>778 出来れば言葉で説明していただけるととても有難いんだけれども。 >>776 MyProject1MyFrame1.cpp に、 void MyProject1MyFrame1::m_button1OnButtonClick( wxCommandEvent& event ) { // TODO: Implement m_button1OnButtonClick this->Close(); } と類似の行が沢山あるけど、this->Close() 以外は、wxFormBuilder が自動生成したとのことで Ok ? >>779 >基本クラスや継承クラスの生成コードは >上書きしちゃってよしなにしてくれないから目視マージが必要になる >で、それならxrcでいっかなとなったりとね この辺りとの関連が知りたい。自分で書いたコードが勝手に上書きされて消されてしまうということ? そもそも wxFormBuilder って、人間が書いたコードと「マージ」や「アペンド」する機能は全くなくて、 デザイナのテキスト領域に表示されるコードをコピペして使う程度の事しかできないのかな? xrcはwxFormBuilderだとwxRibbonとかで生成に抜けがあるよね これ自体はそのうちなおるだろうけど、案外使われてないのかなxrc class MyFrame1 : public wxFrame {・・・}; class MyProject1MyFrame1 : public MyFrame1 {・・・}; となっていて、 http://stackoverflow.com/questions/8255753/how-to-add-personal-code-into-wxformbuilder-generated-class の ・build your frame/panel in formbuilder ・generate inherited class ・implement your handling code in inherited class ・make changes to form/panel in wxFormbuilder -> will only affect generated class, not inherited class の最後の行と矛盾するね。 wxFormBuilder は、MyFrame1 は書き換えるが、それを継承した所の MyProject1MyFrame1 は、最初の 一回しか書き換えない(というよりユーザーが指示しないと生成しない)、ということらしいから。 つまり、>>781 のイベント・ハンドラにおいて、this->Close(); の外側の部分も手作業で 書くしかないのではなかろうか? そして、対応する *.h ファイルの中に、同じ関数のメンバ関数宣言も手作業で追加するしかないのでは? 実装の中身以外は何一つ手では書かないっていうなら、wxWidgetsは投げ捨てて QtCreator有するQtか、C++ Builderあたりを使うしかないよ。 wxFormBuilderはIDEじゃないし。 >>786 QtCreator では、それが出来るのかな? >>785 言葉通りに受け取ってくれればいい。 本当に「this->Close();以外書いてない」んだ。 つまり関数実装部は全て自動生成される。 つーか試してくれよ。 これだけ御膳立てしたんだからさ。 >>789 大体、答えが分かった。 つまりあなたは、wxFormBuilder に MyProject1MyFrame1 を生成させて、 this->Close(); を追加したんだ。 そいういうやり方だと、ボタンやメニュー項目を一つ増やす度に、手作業で、また、 this->Close(); を自分で書かなきゃならない。 それが、>>779 の意味だね? だとすれば、this->Close(); の部分は、実践的には、もっと長くなるのだから、 物凄く面倒で、なおかつ危険が伴う作業になるね。 >>790 >そいういうやり方だと、ボタンやメニュー項目を一つ増やす度に、手作業で、また、 >this->Close(); >を自分で書かなきゃならない。 ここの部分を補足すると、その時に追加したボタンやメニュー項目に対するハンドラだけ でなく、既に存在していたボタンやメニュー項目に対する全てのハンドラの中身を手作業で コピーする必要があるということになる。 ボタンやメニュー項目の個数をN とすると、O(N^2) の作業時間が必要になるね。 >>790 > そいういうやり方だと、ボタンやメニュー項目を一つ増やす度に、手作業で、また、 > this->Close(); > を自分で書かなきゃならない。 そこらへんに少しコツがあってな。 自動生成された部分を一切変更しない限りにおいて、 後から機能追加して再度サブクラスを生成した時、以前書いた部分は削除されない。 つまり今回の例では「this->Close();」は消えずに残る。 逆に言えば「// TODO〜」コメントの削除や編集すら許されないという事なんだけどな。 これが守られなかった場合、同名の(空の)関数が別に生成される。 この場合は旧関数から新関数へのコピペおよび旧関数の削除の手間が生じるが、 いずれにせよ一度書いたものが消える事は無い。 ヘッダファイルにおいても同様であり、 //// end generated include と /** Implementing MyFrame1 */ の間、それと //// end generated class members 以降の行に書いた内容は削除されない。 安心して機能追加できる。 不安だったら再生成する前にバックアップ取っておけばいい。 問題があるとすれば、コードのインデントが全て消える事。 Eclipse等開発環境のコードフォーマッタで解決するが、3.4.0beta時点では インデント維持されてた筈なんだ。なんで維持されなくなったんだ? 俺の見落しか仕様かバグか。 なるほど、wxFormBuilderも新規出力(全書き換え)しかできないわけではないという ことなの? どうやるのかな? あと、EVENT TABLEが古いと言ってる人がいたけど、Connect()がそれに置き換わっただけ だからね。使う側から目線では(抽象的な意味では)変わってない。配列で静的に持っているか、 関数で登録するかの違いに過ぎないから。 以下によると、wxSmith には、TOP LEVEL RESOURCE を2つ以上作成する方法が見つからないらしい。 いったん、1つのTOP LEVEL WINDOW を作ると、全てがそのウィンドウの子供になってしまう。 POPUP MENU や、メインウィンドウに付随する1群のダイアログは、作るのが難しいらしい。 それに対して、wxFormBuilderは、2つ以上の TOP LEVEL RESOURCE を作ることが出来る、 と主張している。 http://forums.codeblocks.org/index.php?topic=15742.0 It's one of reasons why I have switched from wxSmith to wxFormBuilder. I haven't found how can I create more than one "top level" resource in my XRC file using wxSmith. Once I created a top level window, everything needed to be a child of this window. Create a set of popup menus? Forget it. Create a set of dialogs along with your main window? Forget it. wxFormBuilder allows more than one top level resource. Moreover, wxFormBuilder can create only a XRC file - well, it creates a code, too, and you can paste parts of the code in your own code. I am curious what I have missed. I am a "XRC user", too. read.cgi ver 07.5.5 2024/06/08 Walang Kapalit ★ | Donguri System Team 5ちゃんねる