基于实现Qt秒表设计
作者:独影阑珊°
基于Qt秒表设计
这个只是虚拟机下的Dialog中设计的秒表,大家感兴趣的可以根据自己手机的秒表界面来设计,亦或是有别的想法也可以在ui中添加函数,或者是在ui界面自己添加调整。本篇将给除了给出Qt秒表设计例子之外还会为大家提供一些常用函数。
一、Qt绘图系统简介
Qt的绘图系统允许使用相同的API在屏幕和其它打印设备上进行绘制。整个绘图系统基于 QPainter,QPainterDevice和QPaintEngine三个类。
QPainter用来执行绘制的操作;
QPaintDevice则允许QPainter在其上面进行绘制,也就是QPainter工作的空间;
QPaintEngine提供了画笔(QPainter)在不同的设备上进行绘制的统一的接口。
Qt 的绘图系统实际上是,使用 QPainter在QPainterDevice上进行绘制,它们之间使用QPaintEngine进行通讯(也就是翻译QPainter 的指令)。
二、QPainter类的绘图函数
drawPoint 点drawLine 线
drawRect 矩形drawPath 路径
drawArc 圆弧drawChord 弦
drawPie 扇形drawEllipse 椭圆
drawText 文字
drawRoundRect 圆角矩形
drawImage drawPixmap drawPicture 显示图像
drawPoints,drawLines,drawRects 多个点、多条线、多个矩形
三、几种常用函数效果图:
四、画刷和画笔
QBrush定义了QPainter的填充模式,具有样式、颜色、渐变以及纹理等属性。画刷的style()定义了填充的样式,使用Qt::BrushStyle枚举,默认值是Qt::NoBrush,也就是不进行任何填充。
QPen定义了用于QPainter应该怎样画线或者轮廓线。画笔具有样式、宽度、画刷、笔帽样式和连接样式等属性。画笔的样式style()定义了线的样式。画笔宽度width()或widthF()定义了画笔的宽。注意,不存在宽度为 0 的线,画笔宽度通常至少是 1 像素。
声明画刷或画笔对象的时候,通常可以先指定颜色,然后再通过类中的setStyle、setWidth等成员函数设置画刷或画笔属性。
QPainter对象要使用画刷或画笔,通常是调用setBrush和setPen成员函数,设置过画刷和画笔的状态将会一直保持。
五、图像处理
Qt提供了4个处理图像的类:QImage、QPixmap、QBitmap,QPicture,它们有着各自的特点。
QImage优化了I/O操作,可以直接存取操作像素数据。
QPixmap优化了再屏幕上显示图像的性能。
QBitmap从QPixmap继承,只能表示黑白两种颜色。
QPicture是可以记录和重启QPrinter命令的类。
对最简单的图片显示而言,用QImage或QPixmap类比较常见。显示一副图像,可以在paintEvent函数中如下操作:
QPainter painter(this); // 声明QPainter对象
… // 其他绘图操作
// 声明一个QPixmap对象并初始装载图像文件
QPixmap pm("/home/fish/HDU.png");
painter.drawPixmap((rect().width() - pm.width()) / 2,
(rect().height() - pm.height()) / 2, pm); // 居中显示图像
六、秒表设计例子
1、.pro文件
#------------------------------------------------- # # Project created by QtCreator 2019-12-04T16:50:48 # #------------------------------------------------- QT += core gui greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TARGET = qt_clock TEMPLATE = app SOURCES += main.cpp\ dialog.cpp HEADERS += dialog.h FORMS += dialog.ui
2、头文件:
dialog.h代码;
#ifndef DIALOG_H #define DIALOG_H #include <QDialog> #include <QTime> #include <QMouseEvent> namespace Ui { class Dialog; } class Dialog : public QDialog { Q_OBJECT public: explicit Dialog(QWidget *parent = 0); ~Dialog(); private: Ui::Dialog *ui; int state; int nMSCnt; QTime sTime; QList<int> lstCnt; int idx; QRect rcBottom; QRect rcLeft; QRect rcRight; private slots: void mytimer ( ); // QWidget interface protected: void paintEvent(QPaintEvent *); // QWidget interface protected: void mousePressEvent(QMouseEvent *); // QWidget interface protected: void wheelEvent(QWheelEvent *); }; #endif // DIALOG_H
3、源文件
(1)dialog.cpp
#include "dialog.h" #include "ui_dialog.h" #include <QPainter> #include <QTimer> Dialog::Dialog(QWidget *parent) : QDialog(parent), ui(new Ui::Dialog) { ui->setupUi(this); state = 0; nMSCnt = 0; idx =0; sTime =QTime::currentTime(); QTimer*timer =new QTimer(this); connect(timer,SIGNAL(timeout()),this,SLOT(mytimer())); timer->start(10); } Dialog::~Dialog() { delete ui; } void Dialog::mytimer() { if(1==state){ update(); } } void Dialog::paintEvent(QPaintEvent *) { QRect rc = rect(); int size = rc.width() > rc.height() ? rc.height() : rc.width(); QPainter qp(this); qp.setFont(QFont("Arial",size/6)); qp.setPen(Qt::black); QString str; int nms; if(state>0){ if(1==state) nms = (sTime.msecsTo(QTime::currentTime()) + nMSCnt) / 10; else nms = nMSCnt / 10; str.sprintf("%02d:%02d.%02d",nms / 6000 , (nms / 100) % 60 , nms % 100); } else { str="00:00.00"; } if (lstCnt.empty()) qp.drawText(rect(),Qt::AlignCenter,str); else{ qp.drawText(rect(),Qt::AlignTop | Qt::AlignHCenter,str); qp.setPen(Qt::gray); qp.setFont(QFont("Arial",size / 10)); QRect t = rect(); t.translate(0, size / 6 + size / 20); nms -= lstCnt.last() / 10; str.sprintf("%02d:%02d.%02d",nms/6000 , (nms/100)%60 , nms%100); qp.drawText(t,Qt::AlignTop | Qt::AlignHCenter,str); qp.setFont(QFont("Arial",size / 15)); qp.setPen(Qt::darkBlue); t.translate(0, size / 6); int i =idx,j; if(i>= lstCnt.size()) i = lstCnt.size() - 1; j =i - 4; for(;i>=0 &&i>j;--i){ nms = lstCnt[i] / 10; int nnms; if(i>0) nnms = (lstCnt[i] - lstCnt[i-1]) / 10; str.sprintf("%02d %02d:%02d.%02d %02d:%02d.%02d", i + 1, nms / 6000,(nms /100) % 60,nms % 100, nnms /6000 ,(nnms /100)%60,nnms % 100); qp.drawText(t,Qt::AlignTop | Qt::AlignHCenter,str); t.translate(0, size /10); } } qp.setFont(QFont("Arial",size/15)); qp.setPen(Qt::red); int hh = size / 10; rcLeft = QRect(rc.left(), rc.bottom()-hh*2, rc.width()/2, hh); rcRight = QRect(rc.width()/2, rc.bottom()-hh*2,rc.width()/2,hh); rcBottom = QRect(rc.left(),rc.bottom()-hh*2,rc.width(),hh); switch(state){ default: qp.drawText(rcBottom,Qt::AlignCenter,"开始"); break; case 1: qp.drawText(rcLeft,Qt::AlignCenter,"暂停"); qp.setPen(Qt::blue); qp.drawText(rcRight, Qt::AlignCenter,"计次"); break; case 2: qp.drawText(rcLeft,Qt::AlignCenter,"继续"); qp.setPen(Qt::blue); qp.drawText(rcRight,Qt::AlignCenter,"重置"); break; } } void Dialog::mousePressEvent(QMouseEvent *e) { if(Qt::LeftButton == e->button()){ switch(state){ default: if(rcBottom.contains(e->pos())){ nMSCnt = 0; sTime = QTime::currentTime(); state = 1; } break; case 1: if(rcLeft.contains(e->pos())){ state = 2; nMSCnt +=sTime.msecsTo(QTime::currentTime()); update(); } else if(rcRight.contains(e->pos())){ lstCnt.append(nMSCnt + sTime.msecsTo(QTime::currentTime())); idx = lstCnt.size() - 1; update(); } break; case 2: if(rcLeft.contains(e->pos())){ state = 1; sTime = QTime::currentTime(); } else if(rcRight.contains(e->pos())){ state = 0; nMSCnt = 0; lstCnt.clear(); update(); } break; } } } void Dialog::wheelEvent(QWheelEvent *e) { if(e->delta() >0){ if(idx < lstCnt.size() -1){ ++idx; update(); } } else { if(idx>0){ --idx; update(); } } }
(2)main.cpp
#include "dialog.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); Dialog w; w.show(); return a.exec(); }
(3)规定界面,在ui界面设置里面(这里我只是简单的设计成正方形,节省时间,需要别的设计,或者探讨,可以加我QQ或者vx)
七、编译演示。
(1)如果你工程很多,需要将你要演示的调制成活动项目,如下图所示;
(2)编译 -> 运行 -> 结果显示
刚才就说过了,界面设置你除了手动画,还可以在这个函数里面进行添加,如下图所示;
废话不多说,看演示结果;
点击开始,开始计数;
点击计次,开始加次数;
暂停 -> 重置 重置之后回到清零状态;
另:看完了这个大家也可以试着设计自己手机中秒表的界面,亦或是下图的计时器,原理异曲同工,大家可以试着调用video相关函数,通过鼠标点击函数去实现声音大小的控制。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。