QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

楼主: wxMidnight

【新人报道】找一块地盘来讨论wxWidgets

[复制链接]
发表于 2005-5-28 11:33:25 | 显示全部楼层 |阅读模式
新人报道,请多多关照,主要是想找一块地盘来讨论wxWidgets编程:
wxWidgets致力于跨平台的GUI开发,支持Linux,FreeBSD,Windows,MacOS X....

主要关注wxWidgets在Linux,Windows(这个上面可能更多些)平台上的开发,请大虾们不吝赐教
 楼主| 发表于 2005-5-28 11:49:29 | 显示全部楼层
wxWidgets网站链接书签:
主站点:http://www.wxwidgets.org
论坛   :http://www.solidsteel.nl/users/wxwidgets/

开发工具:
DialogBlocks快速开发工具(半商业): http://www.anthemion.co.uk/dialogblocks/
CodeBlocks集成开发环境: http://www.codeblocks.org/
MinGWStudio集成开发环境: http://parinyasoft.com/
wx-Devcpp集成开发环境: http://wxdsgn.sourceforge.net/
wxVisualSetup VS集成工具: http://www.litwindow.com/wxVisualSetup

TurboPad轻型程序员编辑器: http://turbopad.sourceforge.net/

语言绑定:(wxWidgets原始语言是C++)
Java: http://www.wx4j.org/
.Net: http://wxnet.sourceforge.net/
Python: http://wxpython.org/
Lua: http://www.luascript.thersgb.net/
回复

使用道具 举报

发表于 2005-5-28 11:56:28 | 显示全部楼层
支持
回复

使用道具 举报

 楼主| 发表于 2005-5-28 11:57:28 | 显示全部楼层
wxWidgets的安装
主要介绍一下在MinGW & Win32下如何安装(编译wxWidgets成发布优化、生成dll、支持Unicode、支持XRC形式)

环境一
MinGW & Win32
打开win32的命令行窗口(不是Msys的shell窗口)
设置路径
set PATH=%PATH%:your_mingw\bin
(注意千万别把你的Msys路径也加进去了)

到wxWidgets的building目录
cd wxWidgets-2.6.0\build\msw

编译wxWidgets
mingw32-make -f makefile.gcc BUILD=release SHARED=1 UNICODE=1 USE_XRC=1 OFFICIAL_BUILD=1

环境二
MinGW & Msys on Win32
打开Msys的shell窗口
建立wxWidgets的building目录
cd wxWidgets-2.6.0/build
mkdir mingw

配置wxWidgets
cd mingw
../../configure --enable-shared --enable-optimise --enable-unicode --enable-official_build --enable-xrc

安装
make install
回复

使用道具 举报

 楼主| 发表于 2005-5-28 12:32:47 | 显示全部楼层
国内网站书签:
wxChinese邮件Group: http://groups-beta.google.com/group/wxChinese
wxWidgets中国网站: http://www.wxwidgets.cn
回复

使用道具 举报

 楼主| 发表于 2005-5-28 13:25:52 | 显示全部楼层
既然编译成了支持Unicode的方式,那么Unicode到非Unicode的转换必然成一个问题,可以考虑采用如下方式:
(由于采用了Unicode,wxWidgets根据自身的宏定义方式,自动放弃对C风格字符串的支持,这个时候wxChar被定义成wchar_t)
{
...
        // 常数的字符串一定用_T或wxT方式,否则会在Unicode和非Unicode之间折腾个头大
        wxString TheString = _T("The String");                    
        wxString TheString2 = wxT("The String");

        // 直接的字符串转换可以用以下方式,wxConvLibc, wxConvLocal都是系统预定义的转换实例
        wxString szTheString("The String", wxConvLibc);
        wxString szTheString2("The String", wxConvLocal);
...
}

...其他,待补充
回复

使用道具 举报

 楼主| 发表于 2005-5-28 14:02:34 | 显示全部楼层
为什么选择了wxWidgets:
- 提供了基于LGPL许可证的跨平台GUI库。
- 提供了各个平台上的native控件(而不是类似其他自己绘画出来的),速度上要好一些
- 在各个平台上都基本上支持GCC编译器
- 提供有dialogblocks式的半商业快速开发工具
- 开发人员、社区的支持不错(在绑定语言上几乎可以说做得最完善的)
缺点:
- 缺少优秀的快速开发集成开发环境
- 对嵌入式设备领域支持极弱极弱

vs QT:
- moc编译器的繁琐使用
- signal & slot效率不太高
- 个头过于庞大
- 基于GPL许可证发布

vs GTK+:
- 慢!特别在一些能够使用native控件的地方,相比较起来就是蜗牛
- C式风格的面向对象风格
- 一些优秀的地方和X绑定得太死
回复

使用道具 举报

 楼主| 发表于 2005-6-4 08:31:51 | 显示全部楼层
wxWidgets的个头问题
粗看wxWidgets编译出来的程序都挺大的,但是wxWidgets在发展的过程已经考虑到了这个问题,所以它自身提供了一个configtool,可以用它来进行wxWidgets的详细配置:
- 当你处于开发模式,可以把所有选项都打开,甚至把wxWidgets的调试符号信息也打开(请保证你有足够的硬盘空间)
- 当你需要发放产品时,可以针对你产品使用到的特定进行精挑细选,多余的部分统统拿掉。
- 在你更改wxWidgets的配置选项之后,从新编译建立你的wxWidgets库,动态的或静态的。
- 然后再在这个新建立的优化库的基础上重建你的应用程序或产品(当然用的应该是没有调试符号信息来编译你的应用程序)。

之后还能做些什么呢?
- 最单一的,采用strip命令把应用程序里多余的信息再进一步去掉。
- 采用压缩工具对你的二进制可执行程序进行压缩,它是不会对你的应用程序有任何损伤的。二进制执行程序压缩工具比较经典的是:http://upx.sourceforge.net 可以使用于Linux平台及Windows平台,压缩率在0.3 - 0.4左右。

通过这样一道流程,把你的应用程序尺寸减小到1M左右是非常可能的。
回复

使用道具 举报

 楼主| 发表于 2005-6-4 08:33:41 | 显示全部楼层
wxWidgets 2.6.1 released:
Bug fixes include refresh improvements on Windows, better wxX11 menu support, wxMac fixes for Tiger, and the ability to compile wxMSW with Winelib under Unix.
回复

使用道具 举报

 楼主| 发表于 2005-6-4 10:38:37 | 显示全部楼层
gxl117翻译的文章:事件处理部分
事件处理

目录

介绍
它是如何工作的
事件跳转
禁止事件
加挂事件句柄

在上一章里已经学习了如何处理菜单事件。这章将解释事件处理是如何工作的,同时解释了如何去处理其它事件。

介绍Introduction

事件是出现在程序内部或外部的一些事情。一个事件可能是通过用户或是其它程序、操作系统等来触发的。这时需要一个机制来让程序对期望的事件产生反应。

在wxWindows的早期版本中,程序的事件处理是完全通过回调函数或者重载虚拟函数来实现的。从wxWindows2.0开始转而使用事件表了。如例3,事件表告诉wxWindows将事件映射到成员函数。事件表是在实现文件(cpp)中声明的。

例 3.1.事件表

BEGIN_EVENT_TABLE(MyFrame, wxFrame)
   EVT_MENU(wxID_EXIT, MyFrame::OnExit)
   EVT_SIZE(MyFrame::OnSize)
   EVT_BUTTON(BUTTON1, MyFrame::OnButton1)
END_EVENT_TABLE()

上面的事件表告诉wxWindows当它接收到一个WM_SIZE事件时调用MyFrame的成员函数OnSize。 宏 BEGIN_EVENT_TABLE 声明wxFrame和它的子类MyFrame拥有这个事件表。

处理事件的成员函数不能是虚拟的。实际上事件处理器将忽略虚拟声明。事件处理函数有类似的形式:返回类型为void并且接受一个事件参数。这个参数的类型与具体的事件相关。对于size事件,使用的类型是wxCommandEvent。当控件变的更复杂时它们使用自己的事件类。

在类定义中,必须有一个DECLARE_EVENT_TABLE宏。参见例2.11。

所有这些宏隐藏了复杂的事件处理系统。
它是如何工作的?

当接收到一个事件时,wxWindows首先调用窗口上产生事件的对象上的wxEventHandler的ProcssEvent处理器。wxWindow(和其它的窗口类)继承自wxEventHander。ProcessEvent查找事件表里的每一个事件并且调用零或多个事件处理器函数。下面是处理一个事件的步骤:

   1.   当对象关闭时(包括wxEvtHandler的SetEvtHandle)函数跳转到第六步。
   2.   如果对象是一个wxWindow对象,ProcessEvent在窗口的wxValidator上递归调用。如果返回真函数退出。
   3.   SearchEventTable是事件处理器调用的函数。当它失败时,开始在基类 上尝试直到没有更多的事件表或者发现了一个合适的函数时这个函数退出。被发现的函数开始执行。
   4.   查找过程应用于整个事件处理器链,当应用成功时(表示事件处理完毕)函数退出。
   5.   当对象是一个wxWindow对象时,并且事件为wxCommandEvent类型时,ProcessEvent向上递归应用于父窗口的事件处理器。当它返回真,函数退出。这可以让一个按钮的父亲来处理按钮的点击而不是让按钮自己来处理。
   6.   最后ProcessEvent 在wxApp对象上调用。

事件跳转Event skipping

ProcessEvent在发现一个可以处理事件的函数后退出。这表示当你的类对一个事件起反应时,下层的类不会得到这个事件。有时我们不希望这样。这个问题可以根据基类的事件类型用wxEvent类的Skip方法来解决,使事件处理器的查找继续进行。

下面的例子展示了事件跳转的用处。例3.2是一个文本控件的定义,它只接受数字字符。

例 3.2. NumTextCtrl.h

class NumTextCtrl : public wxTextCtrl
{
public:
   NumTextCtrl(wxWindow *parent);
   void OnChar(wxKeyEvent& event);
protected:
   DECLARE_EVENT_TABLE()
};

当NumericTextCtrl接收到一个键盘事件时,就进行keycode检查。如果输入的是数字,基类wxTextCtrl就可以处理这个事件。这就是我们要对这个事件使用跳转的原因。你必须在这调用Skip方法,否则基类不会处理任何键。

例3.3. NumTextCtrl.cpp

// For compilers that supports precompilation , includes "wx/wx.h"
#include "wx/wxprec.h"
#ifndef WX_PRECOMP
    #include "wx/wx.h"
#endif
#include "NumTextCtrl.h"
#include <ctype.h>
NumTextCtrl::NumTextCtrl(wxWindow *parent) : wxTextCtrl(parent, -1)
{
}
void NumTextCtrl::OnChar(wxKeyEvent& event)
{
   if ( isdigit(event.GetKeyCode()) )
   {
     // Numeric characters are allowed, so the base class wxTextCtrl
     // is allowed to process the event. This is done using the Skip() method.
     event.Skip();
   }
   else
   {
     // Character is not allowed.
     wxBell();
   }
}
BEGIN_EVENT_TABLE(NumTextCtrl, wxTextCtrl)
   EVT_CHAR(NumTextCtrl::OnChar)
END_EVENT_TABLE()

禁止事件

一些事件是可以禁止的。当你禁止一个事件时,这个事件不会被进一步处理。例3.4演示了,当一个文本控件内的文本改变后如何禁止这个简单文本编辑器的关闭事件。这表示当在用户还没有保存改变后的文本内容时这个窗口不能被关闭。

例 3.4. 禁止事件

void TextFrame::OnClose(wxCloseEvent& event)
{
  bool destroy = true;
  if ( event.CanVeto() )
  {
    if ( m_pTextCtrl->IsModified() )
    {
      wxMessageDialog *dlg =
               new wxMessageDialog(this, "Text is changed!\nAre you sure you want to exit?",
                                   "Text changed!!!", wxYES_NO | wxNO_DEFAULT);
      int result = dlg->ShowModal();
      if ( result == wxID_NO )
      {
        event.Veto();
        destroy = false;
      }
    }
  }
  if ( destroy )
  {
    Destroy();
  }

当CanVeto返回false时程序作什么呢?你将不能禁止这个事件你的程序将会退出。
阻塞事件处理器Plug an event handler

考虑下面的问题:每个菜单命令都必须被记录。一个解决方案是创建一个在每个命令事件处理函数中调用的函数。这种方法带来的问题是使维护变得十分困难。当添加一个新的菜单并且没有调用这个函数时,这个菜单命令将不被记录。

解决这个问题是去创建一个新的事件处理器并添加到一个wxWindow类。要完成它需要创建一个从wxEvtHandler派生的新类。在新类中处理事件与一个正常的窗口是相同的。

例 3.5. LogEventHandler.h -LogEventHandler的定义

#ifndef _LogEventHandler_H
#define _LogEventHandler_H
class LogEventHandler : public wxEvtHandler
{
public:
  LogEventHandler() : wxEvtHandler()
  {
  }
  virtual ~LogEventHandler()
  {
  }
protected:
  DECLARE_EVENT_TABLE()
  void OnMenu(wxMenuEvent &event);
private:
};
#endif // _LogEventHandler_H

例3.6. LogEventHandler.cpp -  LogEventHandler的实现

// For compilers that supports precompilation , includes "wx/wx.h"
#include "wx/wxprec.h"
#ifndef WX_PRECOMP
    #include "wx/wx.h"
#endif
#include "LogEventHandler.h"
void LogEventHandler::OnMenu(wxMenuEvent &event)
{
  wxLogMessage("Someone selected a menu item");
  event.Skip();
}
BEGIN_EVENT_TABLE(LogEventHandler, wxEvtHandler)
    EVT_MENU_RANGE(-1, -1, LogEventHandler::OnMenu)
END_EVENT_TABLE()

在宏EVT_MENU_RANGE里,所有的菜单事件都可以被处理。前两个参数用来指定要处理的菜单的ID范围。-1表示处理所有的菜单项。不要忘记在事件上调用Skip,否则不会有任何事件传递到类wxWindow的事件处理器。

下一步是把新的事件处理器压入处理器栈。这是使用wxWindow的PushEventHandler来完成的。要从栈上移除事件处理器使用PopEventHandler。

PushEventHandler(new LogEventHandler());

PopEventHandler 有一个布尔类型的参数,当这个参数为真时,wxWindows删除事件处理器。注意在没有事件处理器被取出时,wxWndows将在窗口撤消时尝试删除事件处理器。这在访问在栈上创建的事件处理器时会发生一个访问错误。可以在一个类撤消之前调用使用false参数的PopeventHandler来避免这个问题。
回复

使用道具 举报

 楼主| 发表于 2005-6-4 10:55:28 | 显示全部楼层
如何定义个新的事件? As following:
有两类方法:
- 定义一个全新的事件类,典型的是从wxEvent或wxCommandEvent派生出来。
- 使用现有的事件类(event class),但是给以新的类型(type)。
在这两类方法中都必须声明这个新的事件类型:
// in the header of the source file
DECLARE_EVENT_TYPE(name, value)

// in the implementation
DEFINE_EVENT_TYPE(name)

这里,value是没什么意义的,只是为了和wxWidgets 2.0.x保持兼容。

◎ 使用现有的事件类
如果你仅仅想使wxCommandEvent赋予一个新的类型,可以使用如下的方式
(这样可以不必定义一个新的事件类,也不用实现使用于线程见通信时使用的wxEvent::Clone())
DECLARE_EVENT_TYPE(wxEVT_MY_EVENT, -1)

DEFINE_EVENT_TYPE(wxEVT_MY_EVENT)

// user code intercepting the event

BEGIN_EVENT_TABLE(MyFrame, wxFrame)
  EVT_MENU    (wxID_EXIT, MyFrame::OnExit)
  // ....
  EVT_COMMAND  (ID_MY_WINDOW, wxEVT_MY_EVENT, MyFrame::OnMyEvent)
END_EVENT_TABLE()

void MyFrame::OnMyEvent( wxCommandEvent &event )
{
    // do something
    wxString text = event.GetText();
}


// user code sending the event

void MyWindow::SendEvent()
{
    wxCommandEvent event( wxEVT_MY_EVENT, GetId() );
    event.SetEventObject( this );
    // Give it some contents
    event.SetText( wxT("Hallo") );
    // Send it
    GetEventHandler()->ProcessEvent( event );
}


◎定义全新的事件类
这某些情况下,你需要定义全新的事件类以实现复杂数据的传输。例子:

// code defining event

class wxPlotEvent: public wxNotifyEvent
{
public:
    wxPlotEvent( wxEventType commandType = wxEVT_NULL, int id = 0 );

    // accessors
    wxPlotCurve *GetCurve()
        { return m_curve; }

    // required for sending with wxPostEvent()
    wxEvent* Clone();

private:
    wxPlotCurve   *m_curve;
};

DECLARE_EVENT_MACRO( wxEVT_PLOT_ACTION, -1 )

typedef void (wxEvtHandler::*wxPlotEventFunction)(wxPlotEvent&);

#define EVT_PLOT(id, fn) \
    DECLARE_EVENT_TABLE_ENTRY( wxEVT_PLOT_ACTION, id, -1, \
    (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) (wxNotifyEventFunction) \
    wxStaticCastEvent( wxPlotEventFunction, & fn ), (wxObject *) NULL ),


// code implementing the event type and the event class

DEFINE_EVENT_TYPE( wxEVT_PLOT_ACTION )

wxPlotEvent::wxPlotEvent( ...

// user code intercepting the event

BEGIN_EVENT_TABLE(MyFrame, wxFrame)
  EVT_PLOT  (ID_MY_WINDOW,  MyFrame::OnPlot)
END_EVENT_TABLE()

void MyFrame::OnPlot( wxPlotEvent &event )
{
    wxPlotCurve *curve = event.GetCurve();
}


// user code sending the event

void MyWindow::SendEvent()
{
    wxPlotEvent event( wxEVT_PLOT_ACTION, GetId() );
    event.SetEventObject( this );
    event.SetCurve( m_curve );
    GetEventHandler()->ProcessEvent( event );
}

◎几个宏的说明
回复

使用道具 举报

发表于 2005-6-4 14:39:18 | 显示全部楼层
加油,加油。

顶一下这个帅哥
回复

使用道具 举报

 楼主| 发表于 2005-6-8 14:37:58 | 显示全部楼层
问题问题:(同时发到了wxWidgets的论坛,所以是英文的,懒得翻译了抱歉)
wxExecute or others Questions:
Hello,
I want to learn more about wxExecute, wxProcess etc. However, when I try the exec sample in wxWidgets distribution(2.6.0), there is a strange thing but I can't understand( I read the source code and have tried to modify some codes inside, but nothing happens). Could you please help me?

For exec sample in wxWidgets-2.6.0
- When I run the action of "Capture command output..." with command:gdb in async mode. The sample recodes the initial output of GDB, however, then the sample has no responsible. Why? In general, the sample should continue its event handler when there is no stream come from GDB process. If I killed the GDB process, the sample will be fine.

- Another, when I run the action of "pipe through command..." with command:gdb and send string:help, the sample prints all information but there is no GDB process anymore. Why? Why and when did the sample kill the GDB process?

Could you please help me? Thank you so much.
(My Environment: wxWidgets 2.6.0 compiled under MinGW and with Unicode options)
回复

使用道具 举报

 楼主| 发表于 2005-6-10 16:27:05 | 显示全部楼层
问题找到,因为wxWidget里提供的wxTextInputStream根本就是一个block的类,在读取完输入时而进程并无结束,整个程序会block在ReadLine上。

看来线程还是不可避免的要被使用!
回复

使用道具 举报

发表于 2008-3-6 21:23:31 | 显示全部楼层
本人有开发工具:
DialogBlocks破解版
以及wxVisualSetup 2003正版
有需要的朋友可以联系我,DialogBlocks破解版因每本人破解
可以免费提供,wxVisualSetup 2003因系本人购买如有需要请支付少量费用。

联系方式[email protected]
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2024-4-19 04:47 , Processed in 0.090101 second(s), 14 queries .

© 2021 Powered by Discuz! X3.5.

快速回复 返回顶部 返回列表