wxWidgets 的 **XRC (XML-based Resource System)** 允許將界面佈局、控件屬性、字符串、圖片等資源外部化為 XML 文件,實現「界面與邏輯解耦」、無需重編譯修改 UI、支持國際化(i18n)、設計師與開發者並行工作。本文給出完整實戰流程:XRC 文件編寫、C++ 加載、事件綁定、自定義控件擴展十步法。
// TextApp.cpp
#include "wx/wx.h"
#include "TextFrame.h"
class TextApp : public wxApp {
public:
virtual bool OnInit() override {
wxXmlResource::Get()->InitAllHandlers(); // 註冊標準控件處理器
if (!wxXmlResource::Get()->Load("rc/TextFrame.xrc")) return false;
TextFrame* frame = new TextFrame(nullptr);
frame->Show(true);
return true;
}
};
IMPLEMENT_APP(TextApp)
// TextFrame.h
#ifndef TEXTFRAME_H
#define TEXTFRAME_H
class TextFrame : public wxFrame {
public:
TextFrame(wxWindow* parent);
virtual ~TextFrame();
void OnSave(wxCommandEvent& event);
private:
DECLARE_EVENT_TABLE()
};
#endif
// TextFrame.cpp
#include "TextFrame.h"
#include "wx/filedlg.h"
#include "wx/xrc/xmlres.h" // XRCCTRL 宏所需
BEGIN_EVENT_TABLE(TextFrame, wxFrame)
EVT_MENU(XRCID("save_menuitem"), TextFrame::OnSave)
END_EVENT_TABLE()
TextFrame::TextFrame(wxWindow* parent) {
// 從 XRC 資源創建窗口及其子控件
wxXmlResource::Get()->LoadFrame(this, parent, "main_frame");
}
TextFrame::~TextFrame() {}
void TextFrame::OnSave(wxCommandEvent& event) {
wxFileDialog dlg(this, _("Save File"), ".", "",
"Text files (*.txt)|*.txt|All files (*.*)|*.*",
wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
if (dlg.ShowModal() == wxID_OK) {
// 通過 XRCID 獲取控件指針(運行時查找)
wxTextCtrl* tc = XRCCTRL(*this, "tc", wxTextCtrl);
if (tc) tc->SaveFile(dlg.GetPath());
wxMessageBox(_("Saved successfully"));
}
}
| 技術點 | 說明 |
|---|---|
wxXmlResource::Get()->InitAllHandlers() | 必須在 Load 前調用,註冊所有標準控件的 XRC 處理器 |
LoadFrame(this, parent, "name") | 兩階段創建:先構造 C++ 對象,再從 XRC 加載屬性/子控件 |
XRCID("name") | 將字符串 ID 轉為整數 ID,用於事件表匹配 |
XRCCTRL(window, "name", Type) | 運行時查找子控件並轉型,失敗返回 NULL,需檢查 |
| 國際化 (i18n) | XRC 中字符串可用 `_("text")` 標記,配合 `wxLocale` 加載 `.mo` 文件實現多語言 |
XRC 是 wxWidgets 實現「關注點分離」的核心機制。掌握「標準控件零代碼加載」與「自定義控件編寫 Handler」兩大場景,即可構建可維護、可本地化、設計師友好的跨平台桌面應用。