wxWidgets自定义按钮的方法

场景:

1.现在的软件上的按钮都不是标准的按钮了,因为基本上是贴图上去的,正常情况下一种图片,鼠标移上去之后按钮显示另一种效果,按下去之后又是另一种效果。

2.wx的做法其实和mfc的按钮原理是一样的,就是给按钮贴图和重绘背景。

以下是源文件.

dh_bitmap_button.h

/*
 * File:  dh_bitmap_button.h
 * Author: Sai
 *
 * Created on 2009年12月29日, 下午4:08
 */

#ifndef _DH_BITMAP_BUTTON_H
#define _DH_BITMAP_BUTTON_H

#include "wx/wx.h"

enum DhBitmapButtonStatus
{
  kDhBitmapButtonNormal,
  kDhBitmapButtonEnter,
  kDhBitmapButtonDown,
  kDhBitmapButtonUp,
  kDhBitmapButtonLeave,
  kDhBitmapButtonDClick,
  kDhBitmapButtonDisable
};

class DhBitmapButton : public wxControl
{
  DECLARE_DYNAMIC_CLASS(DhBitmapButton)
  DECLARE_EVENT_TABLE()
public:
  DhBitmapButton();
  virtual ~DhBitmapButton();

  DhBitmapButton(wxWindow* parent, wxWindowID id,
      const wxPoint& pos = wxDefaultPosition,
      const wxSize& size = wxDefaultSize,
      long style = wxBORDER_NONE,
      const wxValidator& validator = wxDefaultValidator);
  bool Create(wxWindow* parent, wxWindowID id,
      const wxPoint& pos = wxDefaultPosition,
      const wxSize& size = wxDefaultSize,
      long style = wxSUNKEN_BORDER,
      const wxValidator& validator = wxDefaultValidator);

  wxSize DoGetBestSize() const;
  void OnPaint(wxPaintEvent& event);
  virtual void OnEnter(wxMouseEvent& event);
  virtual void OnLeave(wxMouseEvent& event);
  virtual void OnDown(wxMouseEvent& event);
  virtual void OnDClick(wxMouseEvent& event);
  virtual void OnUp(wxMouseEvent& event);
  virtual bool Enable(bool enable = true);
  virtual bool Disable();
  /**
   * 设置正常图片
   *
   * @param bitmap
   */
  DhBitmapButton* set_normal_bitmap(wxBitmap* bitmap);

  /**
   * 1.设置按钮按下时的切换图片
   */
  DhBitmapButton* set_down_bitmap(wxBitmap* bitmap);

  /**
   * 1.设置按钮按经过时的切换图片
   */
  DhBitmapButton* set_enter_bitmap(wxBitmap* bitmap);

  /**
   * 1.设置Disable图片.
   *
   * @param bitmap
   * @return this
   */
  DhBitmapButton* set_disable_bitmap(wxBitmap* bitmap);

  DhBitmapButton* set_background(const wxBitmap& bitmap);

  bool SetBackgroundColour(const wxColour& colour);

protected:
  void DrawExistBitmap(wxDC* dc,wxBitmap* image1,wxBitmap* exist_image);

private:
  wxBitmap background_;
  bool is_used_bg_;

  wxBitmap* normal_bitmap_;
  wxBitmap* down_bitmap_;
  wxBitmap* enter_bitmap_;
  wxBitmap* disable_bitmap_;

  int button_status_;
  wxString text_;
  wxFont text_font_;

  void DrawBackground(wxDC* dc);

};
#endif /* _DH_BITMAP_BUTTON_H */

dh_bitmap_button.cpp

/*
 * File:  DhBitmapButton.cpp
 * Author: Sai
 *
 * Created on 2009年12月29日, 下午4:08
 */

#include "dh_bitmap_button.h"

BEGIN_EVENT_TABLE(DhBitmapButton, wxControl)
EVT_PAINT(DhBitmapButton::OnPaint)
EVT_ENTER_WINDOW(DhBitmapButton::OnEnter)
EVT_LEAVE_WINDOW(DhBitmapButton::OnLeave)
EVT_LEFT_DOWN(DhBitmapButton::OnDown)
EVT_LEFT_DCLICK(DhBitmapButton::OnDClick)
EVT_LEFT_UP(DhBitmapButton::OnUp)
END_EVENT_TABLE()

IMPLEMENT_DYNAMIC_CLASS(DhBitmapButton, wxControl)

DhBitmapButton::DhBitmapButton()
{
}

DhBitmapButton::DhBitmapButton(wxWindow* parent, wxWindowID id,
    const wxPoint& pos,
    const wxSize& size,
    long style,
    const wxValidator& validator)
: normal_bitmap_(NULL), down_bitmap_(NULL), enter_bitmap_(NULL)
{
  Create(parent, id, pos, size, style, validator);
}

DhBitmapButton::~DhBitmapButton()
{
  wxDELETE(normal_bitmap_);
  wxDELETE(enter_bitmap_);
  wxDELETE(down_bitmap_);
}

bool DhBitmapButton::Create(wxWindow* parent, wxWindowID id,
    const wxPoint& pos,
    const wxSize& size,
    long style,
    const wxValidator& validator)
{
  normal_bitmap_ = NULL;
  down_bitmap_ = NULL;
  enter_bitmap_ = NULL;
  disable_bitmap_ = NULL;

  if (!wxControl::Create(parent, id, pos, size, style, validator))
  {
    return false;
  }
  SetBackgroundStyle(wxBG_STYLE_PAINT);
  is_used_bg_ = false;
  return true;
}

wxSize DhBitmapButton::DoGetBestSize() const
{
  return GetSize();
}

void DhBitmapButton::DrawExistBitmap(wxDC* dc, wxBitmap* image1,
    wxBitmap* exist_image)
{
  if (image1)
  {
    dc->DrawBitmap(*image1, 0, 0, true);

  } else
  {
    dc->DrawBitmap(*exist_image, 0, 0, true);
  }
}

void DhBitmapButton::OnPaint(wxPaintEvent& event)
{
  wxPaintDC dc(this);
  DrawBackground(&dc);
  //1.状态控制绘画,好处就是可以调用Refresh连背景一起刷新.
  switch (button_status_)
  {
    case kDhBitmapButtonNormal:
      dc.DrawBitmap(*normal_bitmap_, 0, 0, true);
      break;
    case kDhBitmapButtonEnter:
      if (!enter_bitmap_)
      {
        int width = DoGetBestSize().GetWidth();
        int height = DoGetBestSize().GetHeight();
        wxClientDC dc(this);
        dc.SetPen(*wxRED_PEN);
        dc.SetBrush(*wxTRANSPARENT_BRUSH);

        dc.DrawRectangle(0, 0, width, height);
        break;
      }
      dc.DrawBitmap(*enter_bitmap_, 0, 0, true);
      break;
    case kDhBitmapButtonDown:
      DrawExistBitmap(&dc,down_bitmap_,normal_bitmap_);
      break;
    case kDhBitmapButtonUp:
     dc.DrawBitmap(*normal_bitmap_, 0, 0, true);
      break;
    case kDhBitmapButtonLeave:
      dc.DrawBitmap(*normal_bitmap_, 0, 0, true);
      break;
    case kDhBitmapButtonDClick:
      DrawExistBitmap(&dc,down_bitmap_,normal_bitmap_);
      break;
    case kDhBitmapButtonDisable:
      DrawExistBitmap(&dc,disable_bitmap_,normal_bitmap_);
      break;
    default:
      dc.DrawBitmap(*normal_bitmap_, 0, 0, true);
      break;
  }

}

void DhBitmapButton::DrawBackground(wxDC* dc)
{
  if (is_used_bg_)
  {
    dc->DrawBitmap(background_, 0, 0, true);
  } else
  {
    wxBrush brush(GetBackgroundColour());
    wxPen pen(GetBackgroundColour());
    dc->SetBrush(brush);
    dc->SetPen(pen);
    dc->DrawRectangle(0, 0, GetSize().x, GetSize().y);
  }
}

void DhBitmapButton::OnEnter(wxMouseEvent& event)
{
  button_status_ = kDhBitmapButtonEnter;
  Refresh();
  Update();
}

void DhBitmapButton::OnLeave(wxMouseEvent& event)
{
  if (!IsEnabled())
  {
    return;
  }
  button_status_ = kDhBitmapButtonLeave;
  Refresh();
  Update();
}

void DhBitmapButton::OnDClick(wxMouseEvent& event)
{
  button_status_ = kDhBitmapButtonDown;
  Refresh(false);
  Update();
}

void DhBitmapButton::OnDown(wxMouseEvent& event)
{
  button_status_ = kDhBitmapButtonDown;
  Refresh();
  Update();
}

void DhBitmapButton::OnUp(wxMouseEvent& event)
{
  if (kDhBitmapButtonDown != button_status_)
  {
    return;
  }
  button_status_ = kDhBitmapButtonUp;
  Refresh();
  Update();
  wxCommandEvent myEvent(wxEVT_COMMAND_BUTTON_CLICKED, GetId());
  myEvent.SetEventObject(this);
  GetEventHandler()->ProcessEvent(myEvent);
}

DhBitmapButton* DhBitmapButton::set_normal_bitmap(wxBitmap* bitmap)
{
  normal_bitmap_ = bitmap;
  return this;
}

DhBitmapButton* DhBitmapButton::set_down_bitmap(wxBitmap* bitmap)
{
  down_bitmap_ = bitmap;
  return this;
}

DhBitmapButton* DhBitmapButton::set_enter_bitmap(wxBitmap* bitmap)
{
  enter_bitmap_ = bitmap;
  return this;
}

bool DhBitmapButton::Enable(bool enable)
{
  if (enable)
  {
    button_status_ = kDhBitmapButtonNormal;
  } else
  {
    button_status_ = kDhBitmapButtonDisable;
  }

  Refresh(false);
  Update();
  return wxControl::Enable(enable);
}

bool DhBitmapButton::Disable()
{
  return Enable(false);
}

DhBitmapButton* DhBitmapButton::set_disable_bitmap(wxBitmap* bitmap)
{
  disable_bitmap_ = bitmap;
  return this;
}

DhBitmapButton* DhBitmapButton::set_background(const wxBitmap& bitmap)
{
  is_used_bg_ = true;
  background_ = bitmap;
  return this;
}

bool DhBitmapButton::SetBackgroundColour(const wxColour& colour)
{
  is_used_bg_ = false;
  return wxControl::SetBackgroundColour(colour);
}

调用方式和wxButton一样.

1.先注册事件映射宏.

EVT_BUTTON(Minimal_StartSimplePopup, MyFrame::OnStartSimplePopup)

2.调用代码.

wxBitmap* normal = new wxBitmap("./resources/start/start_normal.png",
    wxBITMAP_TYPE_PNG);
  wxBitmap* down = new wxBitmap("./resources/start/start_pressed.png",
    wxBITMAP_TYPE_PNG);
  wxBitmap* enter = new wxBitmap("./resources/start/start_current.png",
    wxBITMAP_TYPE_PNG);
  wxBitmap* disable = new wxBitmap("./resources/start/stop_normal.png",
    wxBITMAP_TYPE_PNG);
  wxBitmap bg = GetPositionBackgroundBitmap(0,0,normal->GetWidth(),normal->GetHeight());
  start = new DhBitmapButton(page,Minimal_StartSimplePopup,wxPoint(0,0),
    normal->GetSize());
  start->set_normal_bitmap(normal)->set_down_bitmap(down)->set_enter_bitmap(enter);
  start->set_disable_bitmap(disable);
  start->set_background(bg);

wxBitmap MyFrame::GetPositionBackgroundBitmap(int x, int y,
    int width,int height)
{
  wxRect rect;
  rect.x = x;
  rect.y = y;
  rect.width = width;
  rect.height = height;
  wxBitmap temp = this->bg.GetSubBitmap(rect);
  return temp;
}

3.当然我觉得有更好的方式.

比如重载这个类.wxBit

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • wxWidgets实现图片和文件按钮

    在wxWidgets中,想要通过其本身的控件来实现图片+文件的按钮,貌似不太容易做到.但是可以通过重载wxControl来自绘图片+文件按钮.下面给出的是已经封装好的按钮类: wxBitmapButtonEx.h #ifndef _BITMAP_BUTTON_EX_H #define _BITMAP_BUTTON_EX_H #include "wx/wx.h" enum eBitmapButtonStatus { BitmapButtonNormal, BitmapButtonEnte

  • wxWidgets自定义按钮的方法

    场景: 1.现在的软件上的按钮都不是标准的按钮了,因为基本上是贴图上去的,正常情况下一种图片,鼠标移上去之后按钮显示另一种效果,按下去之后又是另一种效果. 2.wx的做法其实和mfc的按钮原理是一样的,就是给按钮贴图和重绘背景. 以下是源文件. dh_bitmap_button.h /* * File: dh_bitmap_button.h * Author: Sai * * Created on 2009年12月29日, 下午4:08 */ #ifndef _DH_BITMAP_BUTTON_

  • C# WPF 自定义按钮的方法

    本文介绍WPF一种自定义按钮的方法. 实现效果 使用图片做按钮背景: 自定义鼠标进入时效果: 自定义按压效果: 自定义禁用效果 实现效果如下图所示: 实现步骤 创建CustomButton.cs,继承自Button: 创建一个资源文件ButtonStyles.xaml: 在资源文件中设计按钮的Style: 在CustomButton.cs中添加Style中需要的依赖属性: 在程序中添加资源并引用(为了方便在不同的程序中引用自定义按钮,自定义按钮放在独立的类库中,应用程序中进行资源合并即可). 示

  • IOS 开发之自定义按钮实现文字图片位置随意定制

    IOS 开发之自定义按钮实现文字图片位置随意定制 可能有些看到这篇文章的朋友会觉得很不屑:"按钮谁不会自定义?还需要看你的?" 也确实,按钮是我们项目中最常见的控件之一,天天在使用.对于不同类型的按钮,我们是否有更加简便的方法来实现需求是我们需要做的.这里我提出自己的两种方法,您可以对你自己平时自定义按钮的方法做一下对比,看看哪种方法更加简单. 多说一句,千万不要觉得知识简单,觉得自己会了,没必要学习.'往往简单的东西存在大智慧'(这个比给满分),知识都是慢慢积累出来的. 按钮是应用中

  • AngularJS创建自定义指令的方法详解

    本文实例讲述了AngularJS创建自定义指令的方法.分享给大家供大家参考,具体如下: 这是一篇译文,来自angular开发者说明的指令.主要面向已经熟悉angular开发基础的开发者.这篇文档解释了什么情况下需要创建自己的指令,和如何去创建指令. 什么是指令 从一个高的层面来讲,指令是angular $compile服务的说明,当特定的标签(属性,元素名,或者注释) 出现在DOM中的时候,它让编译器附加指定的行为到DOM上. 这个过程是很简单的.angular内部有很用这样自带的指令,比如说n

  • yii2.0之GridView自定义按钮和链接用法

    本文实例讲述了yii2.0之GridView自定义按钮和链接用法.分享给大家供大家参考.具体实现方法如下: 复制代码 代码如下: <?= GridView::widget([         'dataProvider' => $dataProvider,         //'filterModel' => $searchModel,         'columns' => [             ['class' => 'yii\grid\SerialColumn'

  • Easyui Datagrid自定义按钮列(最后面的操作列)

    做项目的时候因为需求,要在表格的最后添加一列操作列,easyUI貌似没有提供这种功能,不过没关系,我们可以自定义来实现 版本:jQuery easyUI 1.3.2 这里我的实现方式是采用HTML形式,js方式暂时还没用到 首先是HTML部分 <table id="dg" title="学生信息" class="easyui-datagrid" url="${ctx}listStudent.do" toolbar=&qu

  • Jquery Mobile 自定义按钮图标

    很多朋友都反应jquery mobile自带的图标真的是少之又少,另外我也觉得图标偏小(系统自带的是18*18的),于是琢磨着如何自定义按钮图标,下面小编把我的方法分享给大家. 刚接触Jquery Mobile框架,遇到个很现实问题,就是如何自定义按钮图标,我觉得jquery mobile 自带的图标实在是太少了,另外我觉得图标也偏小(系统自带的应该是18*18的)下面是我的方法,希望大家踊跃拍砖. 1.第一种方法是比较简单的,但是有前提,前提就是你自定义的图标大小应该和系统内置的保持一致,这样

  • Android 自定义按钮点击事件和长按事件对比

     Android 自定义按钮点击事件和长按事件对比 一个按钮同时实现点击和长按事件,有时候会有冲突,我们针对这一现象来自定义按钮来区分点击和长按事件 1.xml中 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="mat

  • AngularJS2 与 D3.js集成实现自定义可视化的方法

    本文介绍了ANGULAR2 与 D3.js集成实现自定义可视化的方法,分享给大家,具体如下: 目标 展现层与逻辑层分离 数据与可视化组件相分离 数据与视图双向绑定,实时更新 代码结构清晰,易于维护与修改 基本原理 angular2 的组件生命周期钩子方法\父子组件交互机制\模板语法 源码解析 代码结构很简单,其中除主页index.html和main.ts之外的代码结构如下所示: 代码结构 app.module.ts import { BrowserModule } from '@angular/

  • Element-ui tree组件自定义节点使用方法代码详解

    工作上使用到element-ui tree 组件,主要功能是要实现节点拖拽和置顶,通过自定义内容方法(render-content)渲染树代码如下~ <template> <div class="sortDiv"> <el-tree :data="sortData" draggable node-key="id" ref="sortTree" default-expand-all :expand-

随机推荐