想在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 );
当然还要在定义Frame函数的时候声明空间名称:如:wxStaticText* TempText;
然后就和之前的操作一样,唯一要改动的就是OnTimer内部的函数了,将title赋值完毕之后,写一句
TimeText->SetLabel(title);
就大功告成了。
当然如果你想设置一下字体,也是很方便的,可以仿造下面的样子在SetLable之后加一句:
TimeText->SetFont( wxFont( 26, 74, 90, 90, false, wxT("Calibri") ) );表示采用某种大小的某种字体。
奉上截图: