想在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") ) );
表示采用某种大小的某种字体。
奉上截图: