スポンサーリンク

wxWidgetsで.xrcファイルからデザインを読み込んで適用(1) xrcファイルからGUI作成

wxWidgetsで画面デザインを定義する.xrcファイルを読み込んでGUIを作成する。

例1 基本的な書き方

layout.xrc

<?xml version="1.0" ?>
<resource version="2.3.0.1">

    <!-- トップレベルはコントロールである必要がある。パネルを作成。 -->
    <object class="wxPanel" name="myMainPanel">
 
    
        <!-- レイアウト用のサイザーを作成 -->
        <object class="wxBoxSizer" name="myBoxSizer">
        
            <orient>wxVERTICAL</orient> <!-- レイアウト方法の指定 -->
            
            <!-- コントロールは sizeritem に入れる -->
            <object class="sizeritem">
            
                <!-- 左側と上側に15pxの余白を入れる -->
                <flag>wxLEFT|wxTOP</flag>
                <border>15</border>
                
                <!-- このコントロールはサイザーのサイズ変更で大きさが変わらない -->
                <option>0</option>

                <!-- 名前 myButton を追加 -->
                <object class="wxButton" name="myButton">
                    <label>ボタン</label>
                    <size>100,30</size>
                </object>
            </object>
      
            <!-- コントロールは sizeritem に入れる -->
            <object class="sizeritem">
            
                <!-- 上下左右の余白は15px -->
                <flag>wxALL|wxEXPAND</flag>
                <border>15</border>

                <!-- このコントロールはサイザーのサイズ変更で大きさが変わる -->
                <option>1</option>
                <object class="wxTextCtrl" name="mytext1">
                    <label>ボタン</label>
                    <size>100,30</size> <!-- サイザーが有効なのでサイズは無視される -->
                </object>
            </object>
        </object>
    </object>
</resource>

サンプルコード

// https://docs.wxwidgets.org/3.0/overview_helloworld.html

// プリプロセッサに以下二つを追加
// __WXMSW__
// WXUSINGDLL

// サブシステムをWindowsに設定(WinMainで呼び出すので)
// Windows (/SUBSYSTEM:WINDOWS)

#ifndef WX_PRECOMP
#include <wx/wx.h>
#endif

#include <wx/gdicmn.h> // wxPointに必要
#include <wx/frame.h>  // wxFrameに必要


#pragma comment(lib,"wxbase32u.lib")
#pragma comment(lib,"wxbase32u_net.lib")
#pragma comment(lib,"wxbase32u_xml.lib")
#pragma comment(lib,"wxmsw32u_adv.lib")
#pragma comment(lib,"wxmsw32u_aui.lib")
#pragma comment(lib,"wxmsw32u_core.lib")
#pragma comment(lib,"wxmsw32u_gl.lib")
#pragma comment(lib,"wxmsw32u_html.lib")
#pragma comment(lib,"wxmsw32u_media.lib")
#pragma comment(lib,"wxmsw32u_propgrid.lib")
#pragma comment(lib,"wxmsw32u_qa.lib")
#pragma comment(lib,"wxmsw32u_ribbon.lib")
#pragma comment(lib,"wxmsw32u_richtext.lib")
#pragma comment(lib,"wxmsw32u_stc.lib")
#pragma comment(lib,"wxmsw32u_webview.lib")
#pragma comment(lib,"wxmsw32u_xrc.lib")


/////////////////////////////////////
/////////////////////////////////////
/////////////////////////////////////

#include <wx/xrc/xmlres.h>


// ウィンドウ作成
class MyFrame : public wxFrame
{
public:
 
    void PostCreate() {

        wxXmlResource::Get()->InitAllHandlers();// 初期化
        wxXmlResource::Get()->Load(R"(C:\test\layout.xrc)"); // ファイル読み込み

        wxXmlResource::Get()->LoadPanel(this, "myMainPanel"); // GUIの作成

        this->Layout(); // レイアウトの更新
    }

MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size) : wxFrame(NULL, wxID_ANY, title, pos, size) { // CallAfter : 現在処理中のイベントが終わったらPostCreateを実行 // コンストラクタはウィンドウ生成イベント扱い CallAfter(&MyFrame::PostCreate); } private: }; ///////////////////////////////////// ///////////////////////////////////// ///////////////////////////////////// // wxWidgetsのアプリケーション作成 class MyApp : public wxApp { public: virtual bool OnInit() { MyFrame* frame = new MyFrame("Hello World", wxPoint(50, 50), wxSize(450, 340)); frame->Show(true); return true; } }; ///////////////////////////////////// ///////////////////////////////////// ///////////////////////////////////// // WinMainをマクロで定義 wxIMPLEMENT_APP(MyApp);

実行例

例2 コントロールを単体で読み込む場合

パネルにはLoadPanelがあるが、すべてのコントロールにLoad***が用意されているわけではない。LoadObject関数を使って、部品名とその部品のクラスを指定して読み込む。

button.xrc

<?xml version="1.0" ?>
<resource version="2.3.0.1">

  <!-- 名前 myButton を追加 -->
  <object class="wxButton" name="myButton">
      <label>ボタン</label>
      <size>300,30</size>
      
  </object>

</resource>

読み込み部分コード

    void PostCreate() {

        wxXmlResource::Get()->InitAllHandlers();// 初期化
        wxXmlResource::Get()->Load(R"(C:\test\button.xrc)"); // ファイル読み込み
        wxWindow* btn = (wxWindow*)wxXmlResource::Get()->LoadObject(this, "myButton"/*識別子*/, "wxButton"/*クラス*/);

        // boxsizerの追加
        wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL);
        this->SetSizer(sizer);


        sizer->Add(btn, 0, wxALL, 10);

        this->Layout(); // レイアウトの更新
    }

実行例

例3 メモリ上の文字列から作成

原則として、メモリ上のテキストを読み込む方法はない。しかし、wxWidgetsにはメモリ上に仮想的なファイルを作成する機能があるので、これを使って仮想的な.xrcファイルを作れば実現できる。

仮想ファイルを作るために、fs_mem.h が必要。

#include <wx/fs_mem.h>

読み込み部分コード

    void PostCreate() {

        wxXmlResource::Get()->InitAllHandlers();

        wxString layout_xrc =
R"(<?xml version="1.0" ?>
<resource version="2.3.0.1">
  <object class="wxPanel" name="myPanel">
    <object class="wxBoxSizer">
      <orient>wxVERTICAL</orient>
      <object class="sizeritem">
        <object class="wxTextCtrl" name="text"/>
        <option>0</option>
        <size>100,30</size>
        <flag>wxALL</flag>
        <border>10</border>
      </object>
    </object>
  </object>
</resource>
)"
;

        wxFileSystem::AddHandler(new wxMemoryFSHandler);
        wxMemoryFSHandler::AddFile("myxrc", layout_xrc.GetData().AsWChar(), layout_xrc.size()*2);
        wxXmlResource::Get()->Load("memory:myxrc");
        wxWindow* mysizer = wxXmlResource::Get()->LoadPanel(this, "myPanel");
        this->Layout(); // レイアウトの更新

    }

実行例

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)


この記事のトラックバックURL: