分类: C/C++
2010-02-19 23:50:47
Minigui的入口函数是MiniGUIMain,xlib对此函数进行了包装,入口改为MiniGUIMainEx.这两个函数一模一样,只是xlib在MiniGUIMain中进行了一些初始化工作.要使用xlib创建一个界面只需如下代码.int MiniGUIMainEx( int argc, const char* argv[] ){XSysForm *pWindow = new XSysForm( NULL );pWindow->SetPosition(0,0,600,480);pWindow->DoShowModal();delete pWindow;return 0;}这将创建一个600x480大小的模式窗体,窗体关闭后将释放所分配的内存.使用xlib创建应用程序,首先要取得当前应用程序对象的一个实例.在程序任何一个地方调用XApplication::GetApp()即可取到实例对象的指针. 应用程序实例对象是整个程序所有界面的根.int MiniGUIMainEx( int argc, const char* argv[] ){XApplication *pApp = Xapplication::GetApp();XSysForm *pWindow = new XSysForm( pApp );pWindow->SetPosition(0,0,600,480);pApp->SetCurrentForm( pWindow );pWindow->DoShow();pApp->Run();return 0;}取到应用程序对象后就可以开始创建窗体了. 创建一个minigui系统窗体样式的窗体只需new 一个XSysForm对象即可.你也可以使用自己自定义的窗体类来创建窗体,自定义窗体类必须从XCustomForm或XSysForm继承. 窗体创建完毕后可以调用DoShow()方法以无模式的方式显示窗体,也可以调用DoShowModal()以模式方式显示. 在这里需要注意,当系统主窗体以无模式(DoShow)的方式显示时一定要调用app对象的SetCurrentForm方法来设置当前消息派发向何处.当主窗体以模式(DoShowModal)的方式显示时或子窗体以DoShow()方式显示时可设可不设. 最后调用应用程序对象的Run方法来启动程序,进入消息循环以防止无模式显示时函数结束程序退出.
在xlib中所有的控件都按照统一的方式创建和操作.会使用一个就会使用所有的控件.控件特有的属性和方法请参看相关类的文档.窗体也是一个控件.控件的创建必须是在堆上创建.如果在创建时指定了父容器,则由父容器来负责删除控件分配的内存.如果创建时没的指定父容器,必须手工删除. 在xlib库中所有从XContainerControl类继承的控件都是容器控件,容器类控件自带tab键管理子控件功能.如:XSysButton* p = new XSysButton( NULL ); //必须手工删除XsysButton* p = new XSysButton( pParent ); //由pParent删除创建界面的过程就象是搭积本,先建大的再建小的,一层层建下去.如:XSysForm *pForm = new XSysForm( pApp ); //指定父容器为应用程序根对象…XPanel* pPanel = new XPanel( pForm );…XSysButton* pBtn = new XsysButton( pPanel ); //指定父容器为Panel对象....XsysListBox* pList = new XsysListBox( pForm); //指定父容器为窗体对象.…上述代码将创建一个窗体,窗体上有一个Panel和一个列表框.Panel上有一个按钮. Panel和按钮及列表框不需要显示的调用delete,当delete pForm时会自动调用delete pBtn和delete pList 和delete pPanel.
使用xlib可以使用第三方工具来设计界面,如Qt界面设计器或BCB/Delphi. Xlib可以自动解析Qt界面设计器设计的*.ui文件和BCB/Delphi开发工具设计的*.dfm文件来生成界面.如果你使用其它工具来设计界面,你可以扩展xlib库来使用该界面. 要护展xlib库来使用其它工具设计的界面文件,你只需要写一个类从XResParse类继承并实现DoParseRes()虚方法即可. 窗体文件解析的类继承结构详见doc目录下的文档.设计的界面文件默认是放在应用程序执行路径下的UI子目录下.文件名与窗体类名相同.比如窗体类名为CTestWindow,界面文件应命名为CTestWindow.ui或CTestWindow.dfm. 你也可以把界面文件放在系统的任何目录下,但是必须调用应用程序对象的SetAppUIPath()方法来指定该目录.解析界面文件是即时解析,也就是说在界面需要显示时才进行解析.所以界面文件要与程序一同发步.在程序运行时对界面的任何修改都将直接影响到界面下一次显示.要使用自动生成界面功能可以按以下几步来做:1) 使用界面设计工具来设计界面.打开Qt设计器创建一个Dialog,然后添加一个按钮,命名为btn1,再添加一个listbox命名为listbox1并设置好控件大小和位置.在设计界面时控件的命名很重要,xlib解析完界面文件后是按控件的名字来标识控件的.一般设计工具都不会充许同名控件.2) 编写窗口类假设我们的主窗口类为CTestWindow, 那么应该按以下格式来编写.//CtestWindow.h...class CTestWindow : public XSysForm{DECLARE_DYNCREATE_FORM( CtestWindow )public:CTestWindow( XControl* pParent );virtual void DoLoadResComplete();rivate:XysButton* pBtn;XSysListBox* pList;};//CTestwindow.cppIMPLEMENT_DYNCREATE_FORM( CTestWindow, XSysForm )CTestWindow::CTestWindow( XControl* pParent ){LoadRes();}void CtestWindow::DoLoadResComplete(){pBtn = dynamic_cast( m_ctrlMap[ “btn1” ] ); pList = dynamic_cast( m_ctrlMap[“listbox1”] ); }窗体类可以从XCustomForm或XSysForm继承,也可以从你自已写的窗体类继承.这里面有两个很重要的宏DECLARE_DYNCREATE_FORM(类名)和 IMPLEMENT_DYNCREATE_FORM(类名,父类名),这两个宏成对出现一个在.h中定义,一个在.cpp中实现.需要解析文件动态生成的窗体控件和其它控件里都必不可少(控件也有一对宏,与此类似).如果不需要动态生成则编写窗体类时不需要添加这两个宏. 如果没有这两个宏,你只能在程序里面new这个窗体类,如:CTestWindow *p = new CtestWindow( pParent );而不能通过界面文件解析创建并显示窗体.构造函数中的LoadRes()调用解析类解析界面文件创建窗体及其子控件并显示.如果在构造函数中不调用此函数则只会创建窗体不会创建子控件,如界面文件中的btn1和listbox1.LoadRes()方法在调用完毕后会自动调用DoLoadResComplete()这个虚方法,可以在这里按照设计时的控件名取到自动创建的控件指针.也可以在LoadRes()方法调用完毕后的任何地方去获取自动创建的控件指针.3) 绑定控件的事件.取到控件指针后就可以自由的使用控件的各种方法了.其中最重要的就是绑定控件的事件.Xlib库将minigui中控件的常用操作消息封装成事件来与用户互. 控件提供的事件详见doc目录下的文件档.按钮最常用的就是点击,取到按钮的指针后就可以将点击事件绑定到指定的函数上.我们在类的头文件里申明按钮的点击事件函数: void OnBtnClick( Xcontrol* pSender );在cpp里实现该函数:void OnBtnClick( Xcontrol* pSender ){if( pList ){pList->AddItem(“ test “ );}}修改DoLoadResComplete()函数void CTestWindow::DoLoadResComplete(){pBtn = dynamic_cast( m_ctrlMap[ “btn1” ] ); pList = dynamic_cast( m_ctrlMap[“listbox1”] ); if ( pBtn )pBtn->OnClickEvent.bind( this, &CTestWindow::OnBtnClick );}其中OnClickEvent为按钮提供的按钮点击事件属性. pBtn->OnClickEvent.bind的意思即为将pBtn的OnClickEvent事件属性绑定到指定的函数上.这样,在运行时点击按钮将调用CTestWindow类的OnBtnClick函数来向listbox1中添加一条数据.事件绑定时不一定要绑定到类函数,也可以绑定到虚函数、普通函数、全局函数、静态函数等,也可以多个控件绑定到一个函数中. 事件函数参数中pSender就是引起此事件的对象的指针.在上例中pSender就是btn1.4) 将第一步设计的界面文件复制到应用程序执行路径下的UI目录.同时复制include目录下的DfmToObj.ini或UiToObj.ini文件到UI目录下.这两个ini文件里存放的是VCL和QT的类与xlib的类的对应表.xlib库按照此对应表来动态生成界面.你可以按照你在使用界面设计工具时所使用的类名来修改此对应表.这个对应表在程序第一次解析文件时加载,只加载一次,界面设计文件则是在每次界面显示时加载解析.5) 编译运行程序.
使用xlib库并且使用自动生成界面功能时有两种方法来实现多国语言1) 将设计文件中的控件标题全部改成字符串ID,重载XXmlFormParse类的DoCreateObj方法,在该方法中设置控件标题时将该ID翻译成多国语言字符串即可.2) 为每个语言提供一套界面. 在UI目录下创建各语言目录如zh_CN Eng等.将界面文件每个目录下复制一份,更改各语言目录下的界面文件中控件标题为各语言文字. 在程序语言切换时调用XApplication::GetApp()->SetAppUIPath()切换到指定语言的界面文件目录.当界面显示时会自动加载指定语言的界面. 各语言界面完全不同也可以,只要窗体类中使用的控件名字和控件类对应即可.
Xlib库的所有控件全部按照一种方式创建和操作.在窗体类的构造函数或其它地方都可以动态创建控件.如:class CTestWindow : public XSysForm{public:CTestWindow( Xcontrol* pParent ){SetPosition( 0, 0, 600, 480 );pLabel = new XSysLabel( this );pLabel->SetPosition( 10, 10, 30, 25 );pLabel->SetCaption( “label” );pBtn = new XsysButton( this );pBtn->SetPosition( 280, 550, 100, 30 );pBtn->SetCaption( “Create Edit” );pBtn->OnClickEvent.bind(this,CTestWindow::OnBtnClick);}void OnBtnClick( Xcontrol* pSender ){XSysEdit *pEdit = new XSysEdit( this );pEdit->SetPosition( 50, 10, 100, 25 );pEdit->SetCaption("text"); //也可以pEdit->SetText("text");}private:XSysLabel* pLabel;XSysButton* pBtn;};int MiniGUIMainEx( int argc, const char* argv[] ){CTestWindow *pWindow = new CTestWindow( NULL );pWindow->DoShowModal();delete pWindow;return 0;}以上代码创建一个模式显示的窗体,窗体上有一个label和一个button,点击button创建一个edit
Xlib的线程基类是XThread. 使用线程很简单,创建一个类继承自XThread,实现Execute虚方法即可.如:class MyThread : public Xthread{public:virtual void Execute(){//做线程的工作}};使用:MyThread *p = new MyThread();…p->Resume();在调用线程的Resume方法前可以对线程类进行一些初始化操作.详见examples.
Xlib的串口类是XComm,在串口打开时会启动一个串口监听线程。该类使用也极其简单.从XComm类继承并实现OnRecive方法即可。串口打开前可以调用SetBufSize设置串口缓冲区大小.如:class MyComm : public Xcomm{public :virtual void OnRecive(const char* dataBuf, int dataLen){//dataBuf 为串口收到的数据//dataLen 为数据长度.}};使用:MyComm comm;comm.open( port, baud );
类结构图:
![]() |
|
源代码:
![]() |
|
直接在xlib目录下执行cmake . 或在xlib目录下新建一build目录,进入build目录执行cmake .. 编译成功后进入bin目录入执行./demo
如果报minigui not found 错误,编辑examples目录下的CMakeLists.txt,在findpath函数中加入你的minigui头文件和库文件路径.
doc文档
![]() |
|