Gtk#创建图形时钟

学习新的图形库时有个习惯,就是将罗云彬先生的一个闹钟小程序移植到这个图形库下。

原理也很简单,就是通过图片以第一个点的颜色为透明色创建窗体,但Gtk#创建就有些费劲了,主要是因为Gtk#的原生库Gtk+为C写的,有很多指针操作,在C#下有些麻烦,查了好多资料才写了下面几句代码。

然后用Cairo绘制时钟的时间,也是一张图片,然后按时、分、秒截取图形的一部分绘制到不透明窗体上。

在Windows 7、Ubunu 11.04下运行,效果相同。

见代码:

 

  1  using System;
  2  using System.Collections.Generic;
  3  using System.Linq;
  4  using System.Text;
  5  using Cairo;
  6  using Gdk;
  7  using Gtk;
  8  using Window = Gtk.Window;
  9  using WindowType = Gtk.WindowType;
 10 
 11  namespace GClock
 12 {
 13      public  class MainWindow : Window
 14     {
 15          bool timer =  true;
 16          readonly Pixbuf _pixbufNumber;       //  时钟时间图片,为0-9十个数字和:以及空白部分组成
 17 
 18          public MainWindow()
 19             :  base(WindowType.Toplevel)
 20         {
 21             _pixbufNumber =  new Pixbuf(GetType().Assembly,  " GClock.Bmp.Number06.bmp ");
 22 
 23              //  从嵌入资源中获取Pixbuf
 24              var pixbufO =  new Pixbuf(GetType().Assembly,  " GClock.Bmp.Clock03.bmp ");
 25              //  取Pixbuf第一个点的rgb值
 26               byte r, g, b;
 27              unsafe {
 28                  //  Pixbuf的Pixels未记录图片每个点信息值
 29                   //  取(x,y)的rgb值,以下代码中x,y均为0
 30                   //  var p = (byte*)pixbufO.Pixels.ToPointer() + y * pixbufO.Rowstride + x * pixbufO.NChannels;
 31                  var p = pixbufO.Pixels.ToPointer();
 32                 r = *( byte*)p;
 33                 g = *(( byte*)p +  1);
 34                 b = *(( byte*)p +  2);
 35             }
 36              //  依据第一个点的rgb值增加透明通道
 37              var pixbuf = pixbufO.AddAlpha( true, r, g, b);
 38 
 39             Decorated =  false;       //  不设置窗体边框
 40              AppPaintable =  true;     //  应用程序绘制界面
 41              SetDefaultIconFromFile( " Clock00.ico ");
 42              // SetDefaultSize(pixbuf.Width, pixbuf.Height);
 43              SetDefaultSize( 500500);
 44             SetPosition(WindowPosition.Center);
 45 
 46             Realize();       //  创建Window的资源,若不调用则this.GdkWindow为null
 47 
 48             DeleteEvent +=  delegate { Application.Quit(); };
 49              //  添加鼠标点击事件
 50              AddEvents(( int)EventMask.ButtonPressMask);
 51             GLib.Timeout.Add( 100, OnTimer);      //  时间事件
 52 
 53             Pixmap pixmap, pixmask;
 54              //  依据Pixbuf创建Pixmap以及对应的蒙板Pixmap
 55              pixbuf.RenderPixmapAndMask( out pixmap,  out pixmask,  128);
 56             ShapeCombineMask(pixmask,  00);
 57             GdkWindow.SetBackPixmap(pixmap,  false);
 58 
 59             ShowAll();
 60         }
 61 
 62          protected  override  bool OnButtonPressEvent(EventButton evnt)
 63         {
 64              //  鼠标左键点击移动窗体
 65               if (evnt.Type == EventType.ButtonPress && evnt.Button ==  1) {
 66                 BeginMoveDrag(( int)evnt.Button, ( int)evnt.XRoot, ( int)evnt.YRoot, evnt.Time);
 67             }
 68              return  base.OnButtonPressEvent(evnt);
 69         }
 70 
 71          protected  override  bool OnExposeEvent(EventExpose evnt)
 72         {
 73              base.OnExposeEvent(evnt);
 74 
 75              using (var cr = CairoHelper.Create(evnt.Window)) {
 76                 var curTime = DateTime.Now;
 77                  int tenDigit, entriesDigit;
 78 
 79                 var x =  25;
 80                  const  int y =  80;
 81                 cr.Save();
 82                  //  绘制左侧空白
 83                  cr.Translate(x, y);
 84                 CairoHelper.SetSourcePixbuf(cr, _pixbufNumber, -( 15 *  10 +  8),  0);
 85                 cr.Rectangle( 00225);
 86                 cr.Clip();
 87                 cr.Paint();
 88                 
 89 
 90                  //  HH
 91                  DecToBcd(curTime.Hour,  out tenDigit,  out entriesDigit);
 92                 x +=  2;
 93                 cr.Restore();
 94                 cr.Save();
 95                 cr.Translate(x, y);
 96                 CairoHelper.SetSourcePixbuf(cr, _pixbufNumber, - 15 * tenDigit,  0);
 97                 cr.Rectangle( 001525);
 98                 cr.Clip();
 99                 cr.Paint();
100 
101                 x +=  15;
102                 cr.Restore();
103                 cr.Save();
104                 cr.Translate(x, y);
105                 CairoHelper.SetSourcePixbuf(cr, _pixbufNumber, - 15 * entriesDigit,  0);
106                 cr.Rectangle( 001525);
107                 cr.Clip();
108                 cr.Paint();
109 
110                  //  :
111                  x +=  15;
112                 cr.Restore();
113                 cr.Save();
114                 cr.Translate(x, y);
115                 CairoHelper.SetSourcePixbuf(cr, _pixbufNumber, - 15 *  100);
116                 cr.Rectangle( 00825);
117                 cr.Clip();
118                 cr.Paint();
119 
120                  //  MM
121                  DecToBcd(curTime.Minute,  out tenDigit,  out entriesDigit);
122                 x +=  8;
123                 cr.Restore();
124                 cr.Save();
125                 cr.Translate(x, y);
126                 CairoHelper.SetSourcePixbuf(cr, _pixbufNumber, - 15 * tenDigit,  0);
127                 cr.Rectangle( 001525);
128                 cr.Clip();
129                 cr.Paint();
130 
131                 x +=  15;
132                 cr.Restore();
133                 cr.Save();
134                 cr.Translate(x, y);
135                 CairoHelper.SetSourcePixbuf(cr, _pixbufNumber, - 15 * entriesDigit,  0);
136                 cr.Rectangle( 001525);
137                 cr.Clip();
138                 cr.Paint();
139 
140                  //  :
141                  x +=  15;
142                 cr.Restore();
143                 cr.Save();
144                 cr.Translate(x, y);
145                 CairoHelper.SetSourcePixbuf(cr, _pixbufNumber, - 15 *  100);
146                 cr.Rectangle( 00825);
147                 cr.Clip();
148                 cr.Paint();
149 
150                  //  SS
151                  DecToBcd(curTime.Second,  out tenDigit,  out entriesDigit);
152                 x +=  8;
153                 cr.Restore();
154                 cr.Save();
155                 cr.Translate(x, y);
156                 CairoHelper.SetSourcePixbuf(cr, _pixbufNumber, - 15 * tenDigit,  0);
157                 cr.Rectangle( 001525);
158                 cr.Clip();
159                 cr.Paint();
160 
161                 x +=  15;
162                 cr.Restore();
163                 cr.Save();
164                 cr.Translate(x, y);
165                 CairoHelper.SetSourcePixbuf(cr, _pixbufNumber, - 15 * entriesDigit,  0);
166                 cr.Rectangle( 001525);
167                 cr.Clip();
168                 cr.Paint();
169 
170                  //  绘制右侧空白
171                  x +=  15;
172                 cr.Restore();
173                 cr.Save();
174                 cr.Translate(x, y);
175                 CairoHelper.SetSourcePixbuf(cr, _pixbufNumber, -( 15 *  10 +  8),  0);
176                 cr.Rectangle( 00225);
177                 cr.Clip();
178                 cr.Paint();
179 
180                 cr.Restore();
181             }
182 
183              return  true;
184         }
185 
186          bool OnTimer()
187         {
188              if (!timer)  return  false;
189 
190             QueueDraw();
191              return  true;
192         }  
193 
194          //  依据两位数获取该数字的十位、个位数
195           private  static  void DecToBcd( int decimalNum,  out  int tenDigit,  out  int entriesDigit)
196         {
197             tenDigit = decimalNum /  10;
198             entriesDigit = decimalNum %  10;
199         }
200     }
201 }

 主窗体背景图片:

 

时钟数字图片:

 

程序运行图片:

转载于:https://www.cnblogs.com/srw962/archive/2011/09/30/2196634.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值