在Frame上显示时间,实现能够定时刷新的时钟

想在Frame窗口上显示时钟信息,因为没有系统的学习wxwidgets,自己想了一种最笨的方案,见笑。

一、实现方案:

1、原始方案:
用wxDateTime获取当前的时间,赋给一个wxString类的参数。但是如果只采用DrawText写文本,第二次之后就会覆盖前一次的文本。

2、改进后的方案:
先用DrawRectangle画一个确定大小、确定位置的矩形框,再用DrawText写文本,将上述操作封装进入OnTimer中,用wxTimer类的实例来定时触发wxTimerEvent后调用OnTimer,就能实现不停的刷新时间。

二、关于wxTimer的使用:
wxTimer类允许使用者以特定的间隔时间执行代码。其实现原理是计数器记满预设的时间之后会触发事件wxTimerEvent,触发事件EVT_TIMER调用OnTimer,在OnTimer函数中可以写入你想要周期性执行的代码。

成员函数:wxTimer (wxEvtHandler *owner, int id=-1)用于创建一个计数器timer并将其链接到一个拥有者owner,id是这个计数器timer的标示符,用于事件宏EVT_TIMER中用于区分不同的timer。

使用时主要在所在类(这个类要求直接或者间接继承自wxEvtHandler)的构造函数(如ShapedFrame)添加(new)一个wxTimer的指针(如m_timer),然后调用成员函数Start (int milliseconds=-1, bool oneShot=false)启动计时x微秒的计数器。

三、代码节选:
    //定义继承自基类wxFrame的 ShapedFrame 类  
      
    class ShapedFrame : public wxFrame   
    {  
      
    public:  
        // ctor(s)  
          
        ShapedFrame();  
        void SetWindowShape();  
        void OnTimer(wxTimerEvent& event);  
    private:  
          
        // 把 wxTimer作为  ShapedFrame的成员   
        wxTimer *m_timer;  
    }  

本来想这样写class ShapedFrame : public wxFrame,public wxTimer,想让类ShapedFrame继承两种基类,不过行不通,只能像上面的代码一样将wxTimer定义成一个具体的参数,然后再之后的构造函数中创建(new)。

    #define TIMER_ID 1000   
    BEGIN_EVENT_TABLE(ShapedFrame, wxFrame)  
     EVT_TIMER(TIMER_ID, ShapedFrame::OnTimer)   
    END_EVENT_TABLE()  

以上是事件列表,用于连接时间和具体调用的函数。
 
    //ShapedFrame的构造函数  
     ShapedFrame::ShapedFrame()  
           : wxFrame((wxFrame *)NULL, wxID_ANY, wxEmptyString,     //里面的参数定义可以无视  
                      wxDefaultPosition, wxSize(100, 100), //wxDefaultSize,  
                      0  
                      | wxFRAME_SHAPED  
                      | wxSIMPLE_BORDER  
                      | wxFRAME_NO_TASKBAR  
                      | wxSTAY_ON_TOP  
                )  
    {  
      
    // 新建一个wxTimer 类的指针m_timer   
       wxTimer *m_timer = new wxTimer(this,TIMER_ID);  
              
        m_timer->Start(1000); //开始定时计数,定时时间是1s,也就是每秒调用一次OnTimer   
    }  

    void ShapedFrame::OnTimer(wxTimerEvent& event)   
    {  
           
        wxString buf;  
        long chw, chh;  
          
        wxClientDC dc(this);   //设置句柄   
          
        //获取当前时间   
        wxDateTime time = wxDateTime::Now();        
        int h = time.GetHour();    
        int m = time.GetMinute();    
        int s = time.GetSecond();    
          
        wxString title;  
        title.Printf("Clock %i:%.2i:%.2i", h, m, s);  
       // buf = wxT("M");  
          
        dc.SetBrush(*wxLIGHT_GREY_BRUSH);       
        dc.DrawRectangle( 110,10,120,20);     // 画个矩形填充颜色   
          
        dc.SetTextForeground(*wxBLACK);      // 写时间   
        dc.GetTextExtent(title, &chw, &chh); // buf  
        dc.DrawText(title,110,10);      // buf  
        // dc->DrawText(title,110,10)报错:  
        //base operand of `->' has non-pointer type `wxClientDC'  
        //  因为dc不是指针  
    }  

四、效果图:
就截个部分Frame的图,丑陋成一把刀了,凑合能一秒一秒的刷新,和电子钟似的:


2011年10月11日补充:

五、另一种方法
用wx静态文本控件wxStaticText来显示时间,wxStaticText的功能是显示文本,并含有成员函数SetLabel用以更新文本

具体操作如下:
首先在Frame函数的构造函数中添加一个wxStaticText控件:
    TimeText = new wxStaticText( panel1, wxID_ANY, title , wxDefaultPosition, wxDefaultSize, 0 );  
其中title就是已经赋值了当前时间的wxString参数,在控件创建的时候就显示当前时间,如果将title换成wxT(“”)就会出现一开始的瞬间内容为空的效果,这样不太美观;

当然还要在定义Frame函数的时候声明空间名称:如:wxStaticText* TempText;


然后就和之前的操作一样,唯一要改动的就是OnTimer内部的函数了,将title赋值完毕之后,写一句
    TimeText->SetLabel(title);  
就大功告成了。


当然如果你想设置一下字体,也是很方便的,可以仿造下面的样子在SetLable之后加一句:
    TimeText->SetFont( wxFont( 26, 74, 90, 90, false, wxT("Calibri") ) );  
表示采用某种大小的某种字体。

奉上截图:
http://blog.csdn.net/ssl2009/article/details/6780407

你可能感兴趣的:(在Frame上显示时间,实现能够定时刷新的时钟)