3.xml描述界面

上篇中我們手寫了一個界面,并在上面添加了兩個按鈕,在收到WM_CREATE消息后,創(chuàng)建界面。一般界面包含很多個控件,而且界面經(jīng)常發(fā)生變化,如果還是手寫的畫,顯然不現(xiàn)實。

在duilib中可以使用xml來描述界面,框架通過解析xml,創(chuàng)建界面,這和我們手動寫xml的效果是一樣的。使用xml來描述界面,實現(xiàn)了界面和界面處理邏輯的分離。

這種界面和界面處理邏輯分離的方式其實和Qt是一樣的,Qt 使用的是.ui文件(實質(zhì)上是xml格式的文件)來描述界面。

在duilib源碼中的屬性列表.xml這個文件描述了duilib支持解析的元素和屬性。以Button為例:

<Button parent="Label" notifies="setfocus killfocus timer menu click windowinit(root)">
        <Attribute name="name" default="" type="STRING" comment="控件名字,同一窗口內(nèi)必須唯一,如(testbtn)"/>
        <Attribute name="pos" default="0,0,0,0" type="RECT" comment="位置,如果為float控件則指定位置和大小,否則只指定大小,如(0,0,100,100)"/>
        <Attribute name="padding" default="0,0,0,0" type="RECT" comment="外邊距,如(2,2,2,2)"/>
        <Attribute name="bkcolor" default="0x00000000" type="DWORD" comment="背景顏色,如(0xFFFF0000)"/>
        <Attribute name="bkcolor2" default="0x00000000" type="DWORD" comment="背景漸變色2,和bkcolor配合使用,如(0xFFFFFF00)"/>
        ...省略很多...
</Button>

他的父節(jié)點為Label控件,他的屬性有name,pos,paddingbkcolor等。
屬性名、默認(rèn)值、值的類型、屬性的用途都在屬性列表.xml有描述。
我們編寫界面xml時要根據(jù)屬性列表.xml

我們用xml這么描述上篇手寫的界面:

<?xml version="1.0" encoding="UTF-8"?>
<Window size="800,600"> <!-- 窗口的初始尺寸 -->
    <HorizontalLayout bkcolor="#FF00FF00"> <!-- 整個窗口的背景 -->
        <Button name="btnHello1" pos="30,80,0,0" width="70" height="30" text="btnHello1"/> <!-- 按鈕的屬性,如名稱、文本 -->
        <Button name="btnHello2" pos="120,80,0,0" width="70" height="40" text="btnHello2"/>
    </HorizontalLayout>
</Window>

創(chuàng)建窗口時的對應(yīng)代碼要修改為:

    if (uMsg == WM_CREATE)
        {
            m_PaintManager.Init(m_hWnd);
            CDialogBuilder builder;
            CControlUI* pRoot = builder.Create(_T("duilib.xml"), (UINT)0, NULL, &m_PaintManager);
            ASSERT(pRoot && "Failed to parse XML");
            m_PaintManager.AttachDialog(pRoot);
            m_PaintManager.AddNotifier(this);
            return lRes;
        }

同時我們要設(shè)置xml的路徑:

int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
    CPaintManagerUI::SetInstance(hInstance);
    // 設(shè)置資源的默認(rèn)路徑(此處設(shè)置為和exe在同一目錄)
    CPaintManagerUI::SetResourcePath(CPaintManagerUI::GetCurrentPath()+"\\Debug");
    CDuiFrameWnd duiFrame;
    duiFrame.Create(NULL, _T("DUIWnd"), UI_WNDSTYLE_FRAME, WS_EX_WINDOWEDGE);
    duiFrame.CenterWindow(); // 啟動居中;
    duiFrame.ShowModal();
    return 0;
}

大家可能覺得,手寫界面xml也很麻煩,看效果也不是很方便,網(wǎng)友還是提供了一些ui設(shè)計工具,比如DuiDesigner,通過工具操作,可以幫助我們生成xml,還可以預(yù)覽效果。

其實對比下Qt的代碼:

class dlg_login : public QDialog
{
    Q_OBJECT

public:
    dlg_login(QWidget *parent = Q_NULLPTR);
    ~dlg_login();
signals:
    void mainWndLogin();
private slots:
    void OnLogin();
    void showLoginWnd();
private:
    void InitEvent();
private:
    Ui::dlg_login ui;
};

duilib的業(yè)務(wù)代碼:

class CDuiFrameWnd : public CWindowWnd, public INotifyUI
{
public:
    virtual LPCTSTR GetWindowClassName() const;
    virtual void    Notify(TNotifyUI& msg);
    virtual LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
protected:
    CPaintManagerUI m_PaintManager;
};

是不是有點類似呢?CPaintManagerUI m_PaintManager相當(dāng)于Ui::dlg_login ui;他們都是用來管理ui上的控件。
不同的是Qt的通信機制使用的是信號槽,而duilib使用的是windows消息。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容