Qt实现指针式时钟 Qt实现动态时钟

所属分类: 软件编程 / C 语言 阅读数: 134
收藏 0 赞 0 分享

本文实例为大家分享了Qt实现指针式时钟、动态时钟的具体代码,供大家参考,具体内容如下

先上图:

点击运行后首先是一个指针式时钟窗口,点击Digital Clock->可以跳转到数字时钟窗口,再点击Move Clock->可以还原为指针式时钟窗口

关于整个程序的讲解都在代码注释中给出,很详细~

概要:

我设计两个窗口,一个主窗口一个子窗口,利用按钮+信号与槽机制,实现两个窗口的互相切换,其中主窗口用来显示指针时钟,完成三个基本要求:

1、正确显示系统时钟;
2、能准确定位时钟刻度和时分秒针的位置;
3、能随窗口大小的变化而变化; 

关于主窗口的实现,首先利用Qt自带的时间函数QTime::currentTime()获取系统时间,然后利用paintEvent(QPaintEvent *)函数根据获取到的系统时间进行时针,分针,秒针的绘画,并且画出对应的小时刻度线,分钟刻度线,秒刻  度线,实现基本时钟的样式,最后加入scale()函数进行相应的比例缩放,实现时钟能随窗口的大小变化而变化;

关于子窗口,是我自己多加入的模块,是一个电子时钟,用一个lcd液晶显示器以”时:分:秒”的格式显示当下时间,同样是利用自带的时间函数QTime::currentTime()获取当前时间并通过lcd显示。最后将两个窗口通过两个按钮连接起来,实现互相切换功能。

mainwindow.h(主窗口)

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
 
#include <QMainWindow>
#include<QLCDNumber>
#include<QLabel>
#include<sub.h>
#include<QPushButton>
 
QT_BEGIN_NAMESPACE
QT_END_NAMESPACE
 
class MainWindow : public QMainWindow
{
 Q_OBJECT
 
public:
 MainWindow(QWidget *parent = nullptr);//构造函数
 ~MainWindow();//析构函数
 void paintEvent(QPaintEvent *);//画时钟函数
public:
 void dealsub();//转换为子窗口
 void changeback();//转换为主窗口
private:
 sub w;//子窗口
 QPushButton b;//按钮
};
#endif // MAINWINDOW_H

mainwindow.cpp(主窗口)

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include<QPainter>
#include<QPen>
#include<QTime>
#include<QTimer>
#include<QLabel>
#include<QPushButton>
#include<QLCDNumber>
MainWindow::MainWindow(QWidget *parent)
 : QMainWindow(parent)
{
 setWindowIcon(QIcon(":/new/prefix1/v2-d858191577356128b31c88e186eea0db_r.jpg"));//设置图标
 QTimer *timer = new QTimer(this);//产生一个定时器
 connect(timer, SIGNAL(timeout()), this, SLOT(update()));//关联定时器的信号与槽
 timer->start(1000);//开始定时器,每一秒钟更新一次
 resize(600,600);//窗口大小
 b.setParent(this);//指定按钮父对象
 b.setGeometry(0,0,160,40);//设置按钮位置
 b.setText("Digital clock->");//设置按钮内容
 b.setStyleSheet("QPushButton{background-color: rgba(205,214,216,0);color:rgb(0,0,0);}");//设置按钮样式,rgba前三个参数同rgb,最后一个参数表示不透明度,0~1之间
 connect(&b,&QPushButton::released,this,&MainWindow::dealsub);//鼠标松开时触发,跳转到处理子窗口函数
 void(sub::*funsignal)()=&sub::mysignal;
 connect(&w,funsignal,this,&MainWindow::changeback);//关联信号与槽,实现从子窗口返回到主窗口
}
 
MainWindow::~MainWindow()
{
 
}
 
void MainWindow::paintEvent(QPaintEvent *)
{
 static const QPoint hour[3] = {
  QPoint(14, 15),
  QPoint(-14, 15),
  QPoint(0, -110)
 };
 static const QPoint minute[3] = {
  QPoint(11, 13),
  QPoint(-11, 13),
  QPoint(0, -170)
 };
 static const QPoint second[3] = {
  QPoint(7, 8),
  QPoint(-7, 8),
  QPoint(0, -210)
 };
 int size=qMin(width(),height());
 QTime time=QTime::currentTime();//获取系统当前时间
 QPainter p(this);//创建画家对象
 p.setRenderHint(QPainter::Antialiasing);//防止图形走样
 p.translate(width()/2,height()/2);//平移坐标系置中心
 p.scale(size/600.0,size/600.0);//缩放
 
 QBrush brush;//定义画刷
 brush.setColor(QColor(245,182,96));//设置画刷颜色
 brush.setStyle(Qt::SolidPattern);//设置样式
 
 
 QPen pen;//定义画笔
 pen.setWidth(18);//设置画笔宽度
 pen.setColor(QColor(205,214,216));//rgb设置颜色
 pen.setStyle(Qt::SolidLine);//设置风格
 p.setPen(pen);//将画笔交给画家
 p.drawEllipse(QPoint(0,0),280,280);//画圆
 pen.setColor(Qt::white);
 pen.setWidth(160);//设置画笔宽度
 p.setPen(pen);//将画笔交给画家
 p.drawEllipse(QPoint(0,0),160,160);//画圆
 //画时针
 p.setBrush(brush);//将画刷交给画家
 p.setPen(Qt::NoPen);
 p.save();//保存当下状态
 p.rotate(30.0*(time.hour()+time.minute()/60.0));//图形旋转,以原点为旋转中心,顺时针水平旋转对应时针的角度
 p.drawConvexPolygon(hour,3);//画时针这个凸多边形,第一个参数为所有的点,第二个参数为点的个数
 p.restore();//恢复上一次保存的结果,和save()成对出现
 
 //绘制小时线
 pen.setStyle(Qt::SolidLine);
 pen.setWidth(5);
 pen.setColor(Qt::black);
 p.setPen(pen);
 for(int i=0;i<12;i++)
 {
  p.drawLine(0,268,0,276);//画小时线
  p.drawText(-5,-235,QString::number(i));//表明小时数
  p.rotate(30);//每画一次旋转30度
 }
 
 //画分针
 p.setPen(Qt::NoPen);
 p.setBrush(QColor(144,199,247));
 p.save();//保存当下状态
 p.rotate(6.0*(time.minute()+time.second()/60.0));//顺时针旋转至分针的位置
 p.drawConvexPolygon(minute,3);//画分针这个凸多边形,第一个参数为所有的点,第二个参数为点的个数
 p.restore();//恢复上一次保存的结果,和save()成对出现
 
 //绘制分钟线
 pen.setStyle(Qt::SolidLine);
 pen.setColor(QColor(0,0,0));
 pen.setWidth(1);
 p.setPen(pen);
 for(int i=0;i<60;i++)
 {
  if((i%5)!=0)
  p.drawLine(0,265,0,276);//5的倍数时不画,因为有小时线
  p.rotate(6);//每画一次旋转6度
 }
 
 //画秒线
 p.setPen(Qt::NoPen);
 p.setBrush(QColor(119,217,175));
 p.save();
 p.rotate(6*time.second());//顺时针旋转至秒针的位置
 p.drawConvexPolygon(second, 3);//画秒针这个凸多边形,第一个参数为所有的点,第二个参数为点的个数
 p.restore();
 
 //画圆心
 p.setBrush(Qt::black);
 p.setPen(Qt::white);
 p.save();
 p.drawEllipse(QPoint(0,0),3,3);//画圆心
 p.restore();
 
 //表明上午还是下午
 p.setPen(Qt::black);
 if(time.hour()>=12)
 p.drawText(-6,-50,"PM");//画文本区
 else
 p.drawText(-6,-50,"AM");//画文本区
 p.drawText(-60,-130,"Made By ZSR");//画文本区
}
 
void MainWindow::dealsub()
{
 w.show();//显示子窗口
 this->hide();//主窗口隐藏
}
 
void MainWindow::changeback()
{
 w.hide();//子窗口隐藏
 this->show();//显示主窗口L
}

sub.h(子窗口)

#ifndef SUB_H
#define SUB_H
 
#include <QMainWindow>
#include<QPushButton>
#include<QLCDNumber>
class sub : public QMainWindow
{
 Q_OBJECT
public:
 explicit sub(QWidget *parent = nullptr);
 void sentsignal();//发送信号
 void paintEvent(QPaintEvent *event);//画电子时钟
signals://信号
 void mysignal();
public slots://槽
 void showtime();//显示时间函数
private:
 QPushButton b1;//按钮
 QLCDNumber *lcd;//lcd
};
 
#endif // SUB_H

sub.cpp(子窗口)

#include "sub.h"
#include<QTime>
#include<QTimer>
#include<QLCDNumber>
#include<QPainter>
sub::sub(QWidget *parent) : QMainWindow(parent)
{
 setWindowIcon(QIcon(":/new/prefix1/f56513788384645db768d0ec542dec33_r.jpg"));//设置图标
 this->setWindowTitle("Digital clock");//设置窗口标题
 this->resize(900,500);//设置窗口大小
 b1.setParent(this);//指按钮定父对象
 b1.setText("Move clock->");//设置按钮内容
 b1.setGeometry(0,0,140,40);//设置按钮位置
 b1.setStyleSheet("QPushButton{background-color: rgba(205,214,216,0);color:rgb(0,0,0);}");//设置按钮风格
 connect(&b1,&QPushButton::clicked,this,&sub::sentsignal);//连接信号与槽,当点击按钮的时候跳转到发送信号函数,主窗口接收,再执行changeback()函数,即实现了跳回主窗口
 QTimer *timer1=new QTimer(this);////产生一个定时器
 timer1->start(1000);//开始定时器,每一秒钟更新显示时间
 connect(timer1,SIGNAL(timeout()),this,SLOT(showtime()));//关联定时器的信号与槽,1s到即更新显示时间
 lcd=new QLCDNumber();//创建一个lcd液晶显示器
 lcd->setSegmentStyle(QLCDNumber::Filled);//设置显示器风格
 lcd->setParent(this);//指定显示器父对象
 lcd->move(0,50);//移动显示器位置
 lcd->setDigitCount(8);//设置所显示的位数为8位
 lcd->resize(200,50);//设置显示器大小
 showtime();//显示时间
}
 
void sub::sentsignal()//发送信号
{
 emit mysignal();
}
 
void sub::showtime()
{
 QTime time1=QTime::currentTime();//获取当前时间
 QString text=time1.toString("hh:mm:ss");//定义时间显示格式
 if((time1.second()%2)==0)
  text[5]=' ';//每2s冒号消失一次
 lcd->display(text);//lcd显示时间
}
 
void sub::paintEvent(QPaintEvent *event)//
{
 QPainter p(this);//创建一个画家对象
 p.drawPixmap(rect(),QPixmap(":/new/prefix1/f8fa6c0b00b51e33e8949627d52942ea.jpg"));//设置背景图
}

main.cpp(主函数)

#include "mainwindow.h"
#include <QApplication>
 
int main(int argc, char *argv[])
{
 QApplication a(argc, argv);
 MainWindow w;//创建一个主窗口
 w.setWindowTitle("Move clock");//设置主窗口标题
 w.show();//显示主窗口
 return a.exec();
}

THE END

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

更多精彩内容其他人还在看

用标准c++实现string与各种类型之间的转换

这个类在头文件中定义, < sstream>库定义了三种类:istringstream、ostringstream和stringstream,分别用来进行流的输入、输出和输入输出操作。另外,每个类都有一个对应的宽字符集版本
收藏 0 赞 0 分享

C++如何通过ostringstream实现任意类型转string

再使用整型转string的时候感觉有点棘手,因为itoa不是标准C里面的,而且即便是有itoa,其他类型转string不是很方便。后来去网上找了一下,发现有一个好方法
收藏 0 赞 0 分享

C/C++指针小结

要搞清一个指针需要搞清指针的四方面的内容:指针的类型,指针所指向的类型,指针的值或者叫指针所指向的内存区,还有指针本身所占据的内存区
收藏 0 赞 0 分享

C++ 类的静态成员深入解析

在C++中类的静态成员变量和静态成员函数是个容易出错的地方,本文先通过几个例子来总结静态成员变量和成员函数使用规则,再给出一个实例来加深印象
收藏 0 赞 0 分享

C++类的静态成员初始化详细讲解

通常静态数据成员在类声明中声明,在包含类方法的文件中初始化.初始化时使用作用域操作符来指出静态成员所属的类.但如果静态成员是整型或是枚举型const,则可以在类声明中初始化
收藏 0 赞 0 分享

C++类静态成员与类静态成员函数详解

静态成员不可在类体内进行赋值,因为它是被所有该类的对象所共享的。你在一个对象里给它赋值,其他对象里的该成员也会发生变化。为了避免混乱,所以不可在类体内进行赋值
收藏 0 赞 0 分享

C++中的friend友元函数详细解析

友元可以是一个函数,该函数被称为友元函数;友元也可以是一个类,该类被称为友元类。友元函数的特点是能够访问类中的私有成员的非成员函数。友元函数从语法上看,它与普通函数一样,即在定义上和调用上与普通函数一样
收藏 0 赞 0 分享

static全局变量与普通的全局变量的区别详细解析

以下是对static全局变量与普通的全局变量的区别进行了详细的分析介绍,需要的朋友可以过来参考下,希望对大家有所帮助
收藏 0 赞 0 分享

C++ explicit关键字的应用方法详细讲解

C++ explicit关键字用来修饰类的构造函数,表明该构造函数是显式的,既然有"显式"那么必然就有"隐式",那么什么是显示而什么又是隐式的呢?下面就让我们一起来看看这方面的知识吧
收藏 0 赞 0 分享

教你5分钟轻松搞定内存字节对齐

随便google一下,人家就可以跟你解释的,一大堆的道理,我们没怎么多时间,讨论为何要对齐.直入主题,怎么判断内存对齐规则,sizeof的结果怎么来的,请牢记以下3条原则
收藏 0 赞 0 分享
查看更多