QT时钟制作
作为一名计算机小白,在第一次设计时钟时我也遇到很多困难,也借鉴了一位大佬的程序,在融会贯通后,试着自己码了一下代码,但是我觉得写下这样一篇文章更能加深我对它的理解,所以也给大家讲讲我的浅见。
原理
#1首先,在设计时钟之前你需要创立一个定时器,借由timeout()作为信号,在定时器每触发一次时(也就是一秒)发出一次信号,让你的槽函数(也就是绘图事件)重绘一次图像,以此达到时钟转动的功能。代码如下
内联代码片
。
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
QTimer *time=new QTimer;
time->start(1000);//一秒跳一次
connect(time,SIGNAL(timeout()),this,SLOT(update()));//关联定时器计满信号和响应的槽函数,更新,槽函数每执行一次就会调用一次paintevent函数,实现更新窗口
setWindowTitle("FATE");//设置窗口标题
}
绘图事件
首先,你要知道绘图事件中的Qpainter painter相当于是一个永远站在原点的画家,它会以原点为中心绘制图像。所以在绘制是你需要用到translate,将画家抱到你想开始的地方,让他在此作图。
我的代码解释很详细,在此只多赘述一点(也是我此前百思不得解的一点),关于最后在显示三个指针位置时,为何每次都要用到restore复位?因为你在分别绘制三个指针时,每个指针有不同的旋转度数,你的画家需要旋转自己,然后再作图,如果你不复位,那么下一个指针在实现时会在上一个指针的基础上进行旋转
下面展示一些 内联代码片
。
void Widget::paintEvent(QPaintEvent *)
{
QPainter pan(this);
QPixmap map(":/timg2.jpg");//将背景图取出
QRect q(0,0,1920,1200);// (0,0)为左上点,(1024,1024)为右下点,以此矩形取出上诉图片
QRect q2(0,0,1024,1024);//定义背景图大小
pan.drawPixmap(q2,map,q);//得到背景图
QTime time=QTime::currentTime();
QPainter painter(this);//声明一个画家对象
painter.translate(200,230);//平移坐标系,后续时针的中点就在平移后坐标系的原点
//相当于画家作画本来是默认从(0,0)开始,现在你命令他移动到你给的位置去,以你给的位置开始作画
painter.scale(2,2);//按比例额缩放坐标系,此处为放大两倍,将横纵坐标都放大两倍,则之后你的时钟也被放大
//painter.shear(0,1);
painter.save();//保存此时的坐标系状态
//开始绘制时针,分针,秒针的颜色。
QColor hour(212,181,227,300);//分别设置时针,分针,秒针颜色
QColor min(10,100,100,150);//前三项为三基色三个方向比例度,形成一种颜色,最后一个是不透明度
QColor sec(226,207,182,300);
//绘制分针刻度线,一共有60条刻度线,所以要绘制60次
for (int i=1;i<=60;i++)
{
//绘制5个像素点长度的刻度线
painter.drawLine(0,-80,0,-75); //这个时候可以看上面的世界坐标转换。圆心坐标200,230,为坐标系原点,
//他的上方,和左边为负数,右边,和下面为整数
painter.rotate(6); //一分钟旋转6度。其实就是以此时的原点为中心将绘画区域旋转6度
}
// painter.setPen(hour);
//绘制时针刻度线,同上
for (int i=1;i<=60;i++)
{
if(i%5==0)//每隔五格可一次
{
//绘制5个像素点长度的刻度线
// painter.setPen(Qt::red|Qt::cyan);
painter.drawLine(0,-80,0,-70);//与上相同
painter.rotate(30);
//painter.setPen(Qt::red|Qt::blue);
//tr("%1").arg(i/5)这个函数,是将数字转换成个字符串,默认情况,是以10进制转换
painter.drawText(-3,-60, tr("%1").arg(i/5));//在-3,-60,的位置添加每个刻度代表的数字,即添加钟表刻度数字
}
}
painter.restore();//恢复之前状态
//绘制时针,分针,秒针的形状。四个坐标,那就是四边形。注意坐标一定要按顺序写,不然是一个不规则的形状。
QPoint handhour[4]={
QPoint(0,-40),
QPoint(3,0),
QPoint(0,6),
QPoint(-3,0),
};
QPoint handsec[4]={
QPoint(0,-60),
QPoint(3,0),
QPoint(0,6),
QPoint(-3,0),
};
QPoint handmin[4]={
QPoint(0,-50),
QPoint(3,0),
QPoint(0,6),
QPoint(-3,0),
};
//显示时针的位置
painter.setPen(Qt::NoPen);
painter.setBrush(hour);//填充时针,hour是上述定义过的颜色
painter.save();//保存
painter.rotate(30.0*(time.hour()+time.minute()/60));//time.hour()+time.minute()/60就是说现在是几个小时,乘以三十得到需要转动的//角度
painter.drawConvexPolygon(handhour,4); //绘制多边形函数。
painter.restore();//切记旋转之后,一定要复位,不然,分针的旋转会在时针的基础上旋转。
//显示分针的位置
//painter.setPen(Qt::NoPen);
painter.setBrush(min);
painter.save();
painter.rotate(6.0*(time.minute()+time.second()/60));//分针的旋转,以秒针为基础进行
painter.drawConvexPolygon(handmin,4);
painter.restore();
//显示秒针位置
painter.setPen(Qt::NoPen);
painter.setBrush(sec);
painter.save();
painter.rotate(time.second()*6);
painter.drawConvexPolygon(handsec,4);
painter.restore();
}
总结
时钟的实现一是依赖于定时器每隔一秒调用一次绘图事件,二是绘图事件对于时钟的绘制,时针刻度盘,分针刻度盘,三个指针的旋转