显示标签为“wxWidgets”的博文。显示所有博文
显示标签为“wxWidgets”的博文。显示所有博文

2010年12月27日星期一

wxWidgets 多平台开发心得

不得不承认C++跨平台开发是有一定难度的,即使有wxWidgets这么好的库。


首先要考虑文件系统方面的差异:



  • 1.Ubuntu下面C++的源代码使用UTF8无BOM格式,换行符为n, 而在XP下面则为ansi编码,换行符为rn,源代码要进行转换。

  • 2.Ubuntu下面路径分隔符为/,而xp下面则为, 一定要注意在字符串中此字符表示为"",可以用wxFILE_SEP_PATH宏统一起来


其次是一些函数不同平台下实现细节的差异



  • 1.在ubuntu下获取Report格式的listctrl某一列的text 代码如下

    wxListItem info;
    info.SetId(row);
    info.SetColumn(col);
    list->GetItem(info);

    而在xp中必需在list->GetItem(info) 之前设置item的text码:info.SetMask(wxLIST_MASK_TEXT);

  • 2.wxDC类中设置放大系数和正负逻辑方向的一些不同,参见以前的有关讨论。


2010年12月14日星期二

wxWidgets中定时器(wxTimer)的使用

最简单的例子:



class MyFrame : public wxFrame
{
public:
...
       void OnTimer(wxTimerEvent& event);

private:
       wxTimer m_timer; //定义 wxTimer对象
};

BEGIN_EVENT_TABLE(MyFrame, wxFrame)
     EVT_TIMER(TIMER_ID, MyFrame::OnTimer) //绑定事件处理函数
END_EVENT_TABLE()

MyFrame::MyFrame()
: m_timer(this, TIMER_ID) //绑定此对象到this并指定TIMER_ID
{
       m_timer.Start(1000); // 设置1秒间隔,并启动它
}

void MyFrame::OnTimer(wxTimerEvent& event)
{
     // 在下面写需要执行的代码
}

2010年10月13日星期三

使用wxWidgets时发现的一些bug及解决方案

Ubuntu中

wxDC类

bug 1.  使用SetLogicalOrigin时必须确保坐标轴为默认方向(SetAxisOrientation(true,false)),使用后可更改为需要的方向(SetAxisOrientation(true,true));

解决方案:查看wxGTK源代码文件dc.cpp可看到如下代码:

void wxDC::SetLogicalOrigin( wxCoord x, wxCoord y )
{
m_logicalOriginX = x * m_signX; // is this still correct ?
m_logicalOriginY = y * m_signY;
ComputeScaleAndOrigin();
}

作者也察觉到了这里可能有问题,标注了// is this still correct ?


将上面代码修改如下即可:



void wxDC::SetLogicalOrigin( wxCoord x, wxCoord y )
{
m_logicalOriginX = x ;
m_logicalOriginY = y ;
ComputeScaleAndOrigin();
}

bug 2. 使用SetUserScale函数设置放大倍数时画笔(wxPen)的宽度随之放大,但在xp系统下画笔宽度不变。也就是说如果设置SetUserScale(1,1000),则画笔宽度可能变为1000像素,导致无法成功绘制图像。

解决方案:从源代码文件dc.cpp中我们可以看到SetUserScale函数的定义:

void wxDC::SetUserScale( double x, double y )
{
// allow negative ? -> no
m_userScaleX = x;
m_userScaleY = y;
ComputeScaleAndOrigin();
}

在源代码文件dcclient.cpp中我们可以看到wxWindowDC::ComputeScaleAndOrigin()函数的定义:



void wxWindowDC::ComputeScaleAndOrigin()
{
const wxRealPoint origScale(m_scaleX, m_scaleY);

wxDC::ComputeScaleAndOrigin();

// if scale has changed call SetPen to recalulate the line width
if ( wxRealPoint(m_scaleX, m_scaleY) != origScale && m_pen.Ok() )
{
// this is a bit artificial, but we need to force wxDC to think the pen
// has changed
wxPen pen = m_pen;
m_pen = wxNullPen;
SetPen( pen );
}
}

进一步我们可以找到函数 wxWindowDC::SetPen 的定义



void wxWindowDC::SetPen( const wxPen &pen )

{

wxCHECK_RET( Ok(), wxT(“invalid window dc”) );
if (m_pen == pen) return;
m_pen = pen;
if (!m_pen.Ok()) return;
if (!m_window) return;

gint width = m_pen.GetWidth();
if (width <= 0)
{
// CMB: if width is non-zero scale it with the dc
width = 1;
}
else
{
// X doesn’t allow different width in x and y and so we take
// the average
double w = 0.5 +
( fabs((double) XLOG2DEVREL(width)) +
fabs((double) YLOG2DEVREL(width)) ) / 2.0;
width = (int)w; //注意,这个宽度是最终绘制的宽度
if ( !width )
{
// width can’t be 0 or an internal GTK error occurs inside
// gdk_gc_set_dashes() below
width = 1;
}
}

//…… 中间的代码省略

gdk_gc_set_line_attributes( m_penGC, width, lineStyle, capStyle, joinStyle );

m_pen.GetColour().CalcPixel( m_cmap );

gdk_gc_set_foreground( m_penGC, m_pen.GetColour().GetColor() );

}

综合以上代码分析我们可以看到:当我们调用函数SetUserScale 放大绘制的图形时,wxGTK同时放大了绘制线条的宽度。


解决办法是删除 width = (int)w;  这行代码。



修改源代码后,重新编译wxGTK即可。



XP中

wxDateTime

bug 1. wxDateTime::Format 函数不支持中文字符的格式化。

解决方案:暂时可以使用wxString::Format函数替代。