C#学习笔记(一)使用C#绘制一个时钟

思路:

我们常见的时钟是由表盘和指针构成,所以此次我们将任务分成绘制表盘和指针两部分来完成。

相关概念
1、坐标系
在 windows 默认坐标系中,坐标原点在绘图对象(本例绘图对象是 pictureBox1)的左上角,横轴(x 轴)水平向右,纵轴(y 轴竖直向下),每经过 1 个像素加 1。

2、绘图流程
在 windows 绘图,一般分成 3 步。分别为得到绘图场景、设置画笔/画刷、绘图。

(1)设置绘图场景,我们先创建一个项目

 (2)添加绘图板

选择【工具箱】->【PictureBox】,拖动到窗体中,调整 PictureBox 到窗体大小,查看右侧【属性】,可发现系统将该对象自动起名为 pictureBox1。

 

 (3)双击绘图板,进入代码层

(3.1)我们开始创建画板:

        Bitmap bitmap;//创建画图板
        public Form1()
        {
            InitializeComponent();
            bitmap = new Bitmap(pictureBox1.Width, pictureBox1.Height);
            pictureBox1.Image = bitmap;
        }

随后我们单独创建一个画表盘的函数:

public void Clock_back()//画表盘
        {
            int i;
            var g = Graphics.FromImage(pictureBox1.Image);
            Pen p = new Pen(Color.Black, 3);
            var clock = new Rectangle(100, 0, 370, 370);//绘制一个(100,0)处开始,长370,宽370的矩形
            var dot = new Rectangle(280, 180, 10, 10);
            for (i = 0; i < 12; i++)//时刻标度
            {
                double angel = i * (Math.PI) / 6;

                Point xy1 = new Point((int)(180 * Math.Cos(angel) + 285), (int)(180 * Math.Sin(angel) + 185));//圆心定义为(285,185)
                Point xy2 = new Point((int)(155 * Math.Cos(angel) + 285), (int)(155 * Math.Sin(angel) + 185));

                g.DrawLine(p, xy1, xy2);
            }
            for (i = 0; i < 60; i++)//小时刻标度
            {
                double angel = i * (Math.PI) / 30;

                Point xy1 = new Point((int)(180 * Math.Cos(angel) + 285), (int)(180 * Math.Sin(angel) + 185));
                Point xy2 = new Point((int)(170 * Math.Cos(angel) + 285), (int)(170 * Math.Sin(angel) + 185));

                g.DrawLine(new Pen(Color.Blue), xy1, xy2);
            }
            g.DrawEllipse(p, clock);//绘制一个由clock边框定义的椭圆
            g.DrawEllipse(p, dot);
            g.Dispose();
        }

代码解析:(无注释部分)

 var g = Graphics.FromImage(pictureBox1.Image);
 Pen p = new Pen(Color.Black, 3);

第一行是为了得到 pictureBox1 的绘图场景。var 是 c# 的类型关键字,说明该类型由编译器根据后续代码自动给出。
第二行定义了一个黑色的粗度为3的画笔。new 表示调用构造函数。C#规定,值类型初始化时可以直接赋值。引用类型初始化时需要用 new 调用该类型的构造函数进行初始化。

刻度的制作:

首先我们思考怎样才能绘制出刻度值,在这里我想到的办法是:绘制共用圆心的一个大圆和一个小圆。它们在同一角度下,两圆的点在同一条过圆心的直线上。

 所以我们就能每隔6°和60°取一次角度,在每个圆上取出1个点,然后我们通过

g.DrawLine(p, xy1, xy2);

函数连接,就可以绘制出表盘了。函数使用方法如下

 (3.2)指针绘制

 public void Clock(int second,int minute,int hour)//画指针
        {
            var gg = Graphics.FromImage(pictureBox1.Image);

            Pen s_p = new Pen(Color.Yellow, 3);
            Pen m_p = new Pen(Color.Blue, 4);
            Pen h_p = new Pen(Color.Red, 5);

            double angel_s = second * Math.PI / 30;
            double angel_m = minute * Math.PI / 30;
            double angel_h = hour * Math.PI / 6 + minute * (1 / (Math.PI * 30));

            Point o = new Point(285, 185);//圆心

            Point s = new Point((int)(285 + 160 * Math.Sin(angel_s)), (int)(185 - 160 * Math.Cos(angel_s)));//秒针
            Point m = new Point((int)(285 + 130 * Math.Sin(angel_m)), (int)(185 - 130 * Math.Cos(angel_m)));//分针
            Point h = new Point((int)(285 + 100 * Math.Sin(angel_h)), (int)(185 - 100 * Math.Cos(angel_h)));//时针

            gg.DrawLine(s_p, o, s);
            gg.DrawLine(m_p, o, m);
            gg.DrawLine(h_p, o, h);
            gg.Dispose();
        }

大致思路和绘制表盘是一样的,只不过这里将时针分针秒针的角度设置成了变量,后续读取系统时钟进行赋值。

此处有两点值得注意的地方

1、时针的设置

时针有12个刻度,得再加上分针走过的刻度,才能使时针不会在非整时的时候都指向整数。

2、x坐标用285+sin(angel_s),y坐标用185-cos(angel_s)求

因为在绘图板中,y轴指向下,并非我们平常认知的坐标系,所以是相反的,我们可以自己找一张白纸画一下就明白了。

(3.3)读取系统时钟,钟表运动

首先我们添加一个timer控件,其作用是没100毫秒执行一次。

 双击,进入代码层,添加要执行的代码:

private void timer1_Tick(object sender, EventArgs e)
        {
             h = DateTime.Now.Hour;//读取系统时钟
             m = DateTime.Now.Minute;
             s = DateTime.Now.Second;
            var gg = Graphics.FromImage(pictureBox1.Image);
            gg.Clear(this.BackColor);
            Clock_back();
            Clock(s, m, h);
            pictureBox1.Refresh();
        }

启动控件:

        public Form1()
        {
            InitializeComponent();
            bitmap = new Bitmap(pictureBox1.Width, pictureBox1.Height);
            pictureBox1.Image = bitmap;
            timer1.Enabled = true;//启动timer
        }

(3.4)

画板显示:

        private void pictureBox1_Click(object sender, EventArgs e)
        {

            Clock_back();
            Clock(s, m, h);
            MessageBox.Show(s.ToString());
            pictureBox1.Refresh();
        }

此时我们的任务就完成了,成品效果如下:

附全部代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace whx1
{
    public partial class Form1 : Form
    {
        Bitmap bitmap;//创建画图板
        public Form1()
        {
            InitializeComponent();
            bitmap = new Bitmap(pictureBox1.Width, pictureBox1.Height);
            pictureBox1.Image = bitmap;
            timer1.Enabled = true;//启动timer
        }
        int h, m, s;
        private void timer1_Tick(object sender, EventArgs e)
        {
             h = DateTime.Now.Hour;//读取系统时钟
             m = DateTime.Now.Minute;
             s = DateTime.Now.Second;
            var gg = Graphics.FromImage(pictureBox1.Image);
            gg.Clear(this.BackColor);
            Clock_back();
            Clock(s, m, h);
            pictureBox1.Refresh();
        }
        public void Clock_back()//画表盘
        {
            int i;
            var g = Graphics.FromImage(pictureBox1.Image);
            Pen p = new Pen(Color.Black, 3);
            var clock = new Rectangle(100, 0, 370, 370);//绘制一个(100,0)处开始,长370,宽370的矩形
            var dot = new Rectangle(280, 180, 10, 10);
            for (i = 0; i < 12; i++)//时刻标度
            {
                double angel = i * (Math.PI) / 6;

                Point xy1 = new Point((int)(180 * Math.Cos(angel) + 285), (int)(180 * Math.Sin(angel) + 185));//圆心定义为(285,185)
                Point xy2 = new Point((int)(155 * Math.Cos(angel) + 285), (int)(155 * Math.Sin(angel) + 185));

                g.DrawLine(p, xy1, xy2);
            }
            for (i = 0; i < 60; i++)//小时刻标度
            {
                double angel = i * (Math.PI) / 30;

                Point xy1 = new Point((int)(180 * Math.Cos(angel) + 285), (int)(180 * Math.Sin(angel) + 185));
                Point xy2 = new Point((int)(170 * Math.Cos(angel) + 285), (int)(170 * Math.Sin(angel) + 185));

                g.DrawLine(new Pen(Color.Blue), xy1, xy2);
            }
            g.DrawEllipse(p, clock);//绘制一个由clock边框定义的椭圆
            g.DrawEllipse(p, dot);
            g.Dispose();
        }
        public void Clock(int second,int minute,int hour)//画指针
        {
            var gg = Graphics.FromImage(pictureBox1.Image);

            Pen s_p = new Pen(Color.Yellow, 3);
            Pen m_p = new Pen(Color.Blue, 4);
            Pen h_p = new Pen(Color.Red, 5);

            double angel_s = second * Math.PI / 30;
            double angel_m = minute * Math.PI / 30;
            double angel_h = hour * Math.PI / 6 + minute * (1 / (Math.PI * 30));

            Point o = new Point(285, 185);//圆心

            Point s = new Point((int)(285 + 160 * Math.Sin(angel_s)), (int)(185 - 160 * Math.Cos(angel_s)));//秒针
            Point m = new Point((int)(285 + 130 * Math.Sin(angel_m)), (int)(185 - 130 * Math.Cos(angel_m)));//分针
            Point h = new Point((int)(285 + 100 * Math.Sin(angel_h)), (int)(185 - 100 * Math.Cos(angel_h)));//时针

            gg.DrawLine(s_p, o, s);
            gg.DrawLine(m_p, o, m);
            gg.DrawLine(h_p, o, h);
            gg.Dispose();
        }

        private void pictureBox1_Click(object sender, EventArgs e)
        {

            Clock_back();
            Clock(s, m, h);
            MessageBox.Show(s.ToString());
            pictureBox1.Refresh();
        }
    }
}

ps:一只编程和写文章的小白萌新,望各路大佬多指点嘿嘿(*^▽^*)

  • 15
    点赞
  • 57
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
您可以使用C#的Graphics类来绘制一个圆角窗体,以下是一个简单的示例代码: ```csharp using System; using System.Drawing; using System.Windows.Forms; public partial class RoundForm : Form { public RoundForm() { InitializeComponent(); this.FormBorderStyle = FormBorderStyle.None; this.BackColor = Color.White; this.DoubleBuffered = true; this.SetStyle(ControlStyles.ResizeRedraw, true); } protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); Graphics graphics = e.Graphics; graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; Rectangle rectangle = this.ClientRectangle; rectangle.Width--; rectangle.Height--; graphics.DrawRoundRectangle(new Pen(Color.Gray), rectangle, 20); } } public static class GraphicsExtensions { public static void DrawRoundRectangle(this Graphics graphics, Pen pen, Rectangle rectangle, int radius) { GraphicsPath path = new GraphicsPath(); path.AddLine(rectangle.Left + radius, rectangle.Top, rectangle.Right - radius, rectangle.Top); path.AddArc(rectangle.Right - radius, rectangle.Top, radius, radius, 270, 90); path.AddLine(rectangle.Right, rectangle.Top + radius, rectangle.Right, rectangle.Bottom - radius); path.AddArc(rectangle.Right - radius, rectangle.Bottom - radius, radius, radius, 0, 90); path.AddLine(rectangle.Right - radius, rectangle.Bottom, rectangle.Left + radius, rectangle.Bottom); path.AddArc(rectangle.Left, rectangle.Bottom - radius, radius, radius, 90, 90); path.AddLine(rectangle.Left, rectangle.Bottom - radius, rectangle.Left, rectangle.Top + radius); path.AddArc(rectangle.Left, rectangle.Top, radius, radius, 180, 90); path.CloseFigure(); graphics.DrawPath(pen, path); } } ``` 这个示例使用一个自定义的GraphicsExtensions类,其中包含了一个绘制圆角矩形的方法。在RoundForm类的OnPaint方法中,我们使用该方法绘制一个圆角矩形作为窗体的边框。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值