C++圖形時鐘(畫圖入門篇)
第一次接觸製作窗口畫圖感覺還不錯,聽老師講過後寫的,希望對大家有幫助。
本次工程是製作一個圓形和方形時鐘,涉及畫圖操作,先介紹一下畫圖庫(ACLLib)的用到的函數;
1.圖形庫的介紹(這裏只介紹此工程用到的函數,想額外瞭解的可以百度此庫的名稱)
ACLLib是一個基於Win32API的函數庫,提供了相對較爲簡單的方式來做Windows程序,同時也是一個C語言圖形庫
需要Setup是ACLLib程序的入口/啓動函數 ,其意義等同於main函數 ;
一般框架爲:
#include "acllib.h"
int Setup(){
initWindow("test",DEFAULT,DEFAULT,width,width);
return 0;
}
畫圖稍顯需要構建一個窗口
函數原型爲: void initWindow(const char title[] , int left , int top , int width , int height);
參數含義依次爲:窗口標題,窗口左邊起始座標,上面起始座標,窗口寬度,窗口高度。
如果在窗口上畫圖需要把畫圖部分放在*beninPaint()和endPaint()*之間,分別代表畫圖的開始和畫圖的結束。
另外需要注意的是在Windows中,座標是以像素點的數字來定義的,左上角是(0,0),x軸自左向右增大,而y軸自上向下增大。
void setPenWidth(int width) ;//設置畫筆的寬度,單位爲像素點
void ellipse(int Leftx, int TopX ,int width,int height);//畫橢圓(起點下,y;寬度高度)
void rectangle(int Leftx, int TopX ,int width,int height);//畫矩形(起點下,y;寬度高度)
void moveTo(int x, int y); //把當前座標移動到(x,y)
void lineTo(int x,int y); //從當前點畫線到(x,y)
setPenColor(ACL_Color newColor); //設置畫筆顏色
setBrushColor(ACL_Color newColor); //設置所畫區域顏色
2. 獲取系統時間
#include<stdio.h>
#include<time.h>
int main()
{
time_t timer = time(NULL);
printf("ctime is %s\n", ctime(&timer));//得到日曆時間
return 0;
}
需要注意的是別忘記加頭文件 “time.h”,time.h是C/C++中的日期和時間頭文件。用於需要時間方面的函數。
3. 做時鐘
終於到我們的時鐘部分了,首先和別的項目一樣都需要先建立項目的類
在這裏我們建立時鐘類。(註釋應該算比較詳細啦,就不一一介紹了)
clock.h
class Clock
{
private:
int h,m,s,z;
SHAPE shape; //形狀
void EllipseShape(int x,int y,int width,int height);
void RectangleShape(int x,int y,int widht,int height);
public:
//根據電腦時間初始化時鐘,缺省是橢圓
Clock(SHAPE s=ellipseShape);//默認圓形時鐘,指明方形纔是方形
//根據指定時間初始化時鐘
Clock(int z,int h,int m,int s,int shape);
//根據已經存在的時鐘初始化該時鐘
Clock(Clock &);
~Clock(void);
//設置時間
void SetTime(int h,int m,int s);
//獲取時間
void GetTime(int &h,int &m,int &s);
//設置時區
void SetZone(int z);
//獲取時區
int GetZone();
//時間增1
void AddOneS();
//獲取形狀,注意:時鐘生成後,不能修改形狀,所以沒有設置形狀的函數
SHAPE GetShape();
void DispTime(); //顯示時間
void DrawMyClockWithShape(int x,int y,int w,int h);//畫時鐘
};
clock.c
#include<iostream>
#include"Clock.h"
#include"acllib.h"
#include"time.h"
#include"math.h"
using namespace std;
Clock::Clock(SHAPE shape)
{
/*****************************/
time_t t;
struct tm tmm;
//h=m=s=0;
t = time(NULL);//獲取系統時間
localtime_s(&tmm,&t);//把時間給tmm
h=tmm.tm_hour;
m=tmm.tm_min;
s=tmm.tm_sec;
/**********獲得時間格式********************/
z=8;
this->shape=shape;
}
Clock::~Clock(void)
{
}
//根據指定時間初始化時鐘
Clock::Clock(int z,int h,int m,int s,int shape)
{
this->z=z;
this->h=h;
this->m=m;
this->s=s;
this->shape;
}
//根據已經存在的時鐘初始化該時鐘
Clock::Clock(Clock &c)
{
z=c.z;
h=c.h;
m=c.m;
s=c.s;
shape=c.shape ;
}
//設置時間
void Clock::SetTime(int h,int m,int s)
{
this->h=h;
this->m=m;
this->s=s;
}
//獲取時間
void Clock::GetTime(int &h,int &m,int &s)
{
h=this->h;
m=this->m;
s=this->s;
}
//設置時區
void Clock::SetZone(int z)
{
this->z=z;
}
//獲取時區
int Clock::GetZone()
{
return this->z;
}
void Clock::DispTime()
{
cout<<"時區:"<<z<<"時間: "<<h<<":"<<m<<":"<<s<<endl;
}
void Clock::AddOneS()
{
s++;
if(s>=60)
{
m++;
s=0;
if(m>=60)
{
m=0;
h++;
if(h>12)
{
h=0;
}
}
}
}
//下面的橢圓繪製來自於acllib的samples
double RAD(double x)
{
return ((x)/360.0*2*3.1415926535);
}
void Clock::DrawMyClockWithShape(int x,int y,int width,int height)
{
switch(shape)
{
case ellipseShape: EllipseShape(x,y,width,height);
break;
case rectangleShape:RectangleShape(x,y,width,height);
break;
}
}
//獲取時鐘形狀
SHAPE Clock::GetShape()
{
return shape;
}
//畫圓型時鐘
void Clock::EllipseShape(int x,int y,int width,int height)
{
int ox =x+ width/2;//150;
int oy =y+ height/2;//150;
int min=width<height?width:height;
int hl = min/4-min/7;//46;
int ml = min/3-min/6;//74;
int sl = min/2-min/5;//120;
int i;
// circle
setPenWidth(2); //設置畫筆粗細
setPenColor(BLACK); //設置畫筆顏色
setBrushColor(WHITE);//設置背景顏色
ellipse(x,y,x+width,y+height); //橢圓大小位置
// label
setPenWidth(1);
setPenColor(BLACK);
int len1=min/2-min/8,len2=len1+10;
for(i=0;i<12;++i)
{
moveTo(ox+len1*sin(RAD(180-i*30)),oy+len1*cos(RAD(180-i*30)));
lineTo(ox+len2*sin(RAD(180-i*30)),oy+len2*cos(RAD(180-i*30)));
}
// hour
setPenWidth(8);
setPenColor(BLACK);
moveTo(ox,oy);
lineTo(ox+hl*sin(RAD(180-h*30)),oy+hl*cos(RAD(180-h*30)));
// minute
setPenWidth(4);
setPenColor(GREEN);
moveTo(ox,oy);
lineTo(ox+ml*sin(RAD(180-m*6)),oy+ml*cos(RAD(180-m*6)));
// second
setPenWidth(2);
setPenColor(RED);
moveTo(ox,oy);
lineTo(ox+sl*sin(RAD(180-s*6)),oy+sl*cos(RAD(180-s*6)));
}
void Clock::RectangleShape(int x,int y,int width,int height)
{
//矩形中心/圓心位置
int ox =x+ width/2;//150;
int oy =y+ height/2;//150;
int min=width<height?width:height;
int hl = min/4-min/7;//46;
int ml = min/3-min/6;//74;
int sl = min/2-min/5;//120;
int i;
// circle
setPenWidth(2);
setPenColor(BLACK);
setBrushColor(WHITE); //錶盤爲白色
rectangle(x,y,x+width,y+height);//畫框
// label
setPenWidth(1);
setPenColor(BLACK);
int len1=min/2-min/8,len2=len1+10;
for(i=0;i<12;++i)//錶針
{
moveTo(ox+len1*sin(RAD(180-i*30)),oy+len1*cos(RAD(180-i*30)));
lineTo(ox+len2*sin(RAD(180-i*30)),oy+len2*cos(RAD(180-i*30)));
}
// hour
setPenWidth(8);
setPenColor(BLACK);
moveTo(ox,oy);
lineTo(ox+hl*sin(RAD(180-h*30)),oy+hl*cos(RAD(180-h*30)));
// minute
setPenWidth(4);
setPenColor(GREEN);
moveTo(ox,oy);
lineTo(ox+ml*sin(RAD(180-m*6)),oy+ml*cos(RAD(180-m*6)));
// second
setPenWidth(2);
setPenColor(RED);
moveTo(ox,oy);
lineTo(ox+sl*sin(RAD(180-s*6)),oy+sl*cos(RAD(180-s*6)));
}
下面就是主函數了
srand((unsigned)time(NULL));
s = rand() % 2;
這兩句的意思是根據時間生成隨機數然後對2取餘。
下面是ACLLib庫裏的定時器函數
registerTimerEvent(timerEvent); //配置定時器 括號裏爲定時器函數名稱
void startTimer(int id,int timeinterval) //設置定時器 一秒 參數爲定時器id ,定時時間us
void timerEvent(int tid) //定時器中斷函數參數爲定時器id;
下面是我們的主函數代碼
main.cpp
#include "acllib.h"
#include"Clock.h"
#include<stdio.h>
#include <stdlib.h>
#include<time.h>
#include <math.h>
#define RAD(x) ((x)/360.0*2*3.1415926535)//把角度轉化爲弧度
Clock *c1,*c2;
int s, pos;
void timerEvent(int tid) //定時器函數
{
beginPaint(); //畫圖開始
clearDevice(); //清圖
if (s == 0)
{
c1->AddOneS();
c1->DrawMyClockWithShape(30, 30, 250, 250);
}
else
{
c2->AddOneS();
c2->DrawMyClockWithShape(30, 30, 250, 250);
}
endPaint(); //畫圖結束
}
int Setup()
{
initWindow("Clock",DEFAULT,DEFAULT,400,300); //畫一個窗口
registerTimerEvent(timerEvent); //配置定時器
c1 = new Clock; //生成圓形時鐘c1
c2 = new Clock(rectangleShape);//生成矩形時鐘c2
srand((unsigned)time(NULL));
s = rand() % 2; //根據時間生成隨機數
startTimer(0,1000); //設置定時器 一秒
return 0;
}