基于實現(xiàn)Qt秒表設(shè)計
基于Qt秒表設(shè)計
這個只是虛擬機下的Dialog中設(shè)計的秒表,大家感興趣的可以根據(jù)自己手機的秒表界面來設(shè)計,亦或是有別的想法也可以在ui中添加函數(shù),或者是在ui界面自己添加調(diào)整。本篇將給除了給出Qt秒表設(shè)計例子之外還會為大家提供一些常用函數(shù)。
一、Qt繪圖系統(tǒng)簡介
Qt的繪圖系統(tǒng)允許使用相同的API在屏幕和其它打印設(shè)備上進行繪制。整個繪圖系統(tǒng)基于 QPainter,QPainterDevice和QPaintEngine三個類。
QPainter用來執(zhí)行繪制的操作;
QPaintDevice則允許QPainter在其上面進行繪制,也就是QPainter工作的空間;
QPaintEngine提供了畫筆(QPainter)在不同的設(shè)備上進行繪制的統(tǒng)一的接口。
Qt 的繪圖系統(tǒng)實際上是,使用 QPainter在QPainterDevice上進行繪制,它們之間使用QPaintEngine進行通訊(也就是翻譯QPainter 的指令)。
二、QPainter類的繪圖函數(shù)
drawPoint 點drawLine 線
drawRect 矩形drawPath 路徑
drawArc 圓弧drawChord 弦
drawPie 扇形drawEllipse 橢圓
drawText 文字
drawRoundRect 圓角矩形
drawImage drawPixmap drawPicture 顯示圖像
drawPoints,drawLines,drawRects 多個點、多條線、多個矩形
三、幾種常用函數(shù)效果圖:
四、畫刷和畫筆
QBrush定義了QPainter的填充模式,具有樣式、顏色、漸變以及紋理等屬性。畫刷的style()定義了填充的樣式,使用Qt::BrushStyle枚舉,默認值是Qt::NoBrush,也就是不進行任何填充。
QPen定義了用于QPainter應(yīng)該怎樣畫線或者輪廓線。畫筆具有樣式、寬度、畫刷、筆帽樣式和連接樣式等屬性。畫筆的樣式style()定義了線的樣式。畫筆寬度width()或widthF()定義了畫筆的寬。注意,不存在寬度為 0 的線,畫筆寬度通常至少是 1 像素。
聲明畫刷或畫筆對象的時候,通??梢韵戎付伾?,然后再通過類中的setStyle、setWidth等成員函數(shù)設(shè)置畫刷或畫筆屬性。
QPainter對象要使用畫刷或畫筆,通常是調(diào)用setBrush和setPen成員函數(shù),設(shè)置過畫刷和畫筆的狀態(tài)將會一直保持。
五、圖像處理
Qt提供了4個處理圖像的類:QImage、QPixmap、QBitmap,QPicture,它們有著各自的特點。
QImage優(yōu)化了I/O操作,可以直接存取操作像素數(shù)據(jù)。
QPixmap優(yōu)化了再屏幕上顯示圖像的性能。
QBitmap從QPixmap繼承,只能表示黑白兩種顏色。
QPicture是可以記錄和重啟QPrinter命令的類。
對最簡單的圖片顯示而言,用QImage或QPixmap類比較常見。顯示一副圖像,可以在paintEvent函數(shù)中如下操作:
QPainter painter(this); // 聲明QPainter對象
… // 其他繪圖操作
// 聲明一個QPixmap對象并初始裝載圖像文件
QPixmap pm("/home/fish/HDU.png");
painter.drawPixmap((rect().width() - pm.width()) / 2,
(rect().height() - pm.height()) / 2, pm); // 居中顯示圖像
六、秒表設(shè)計例子
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,"繼續(xù)"); ? ? ? ? ? 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)規(guī)定界面,在ui界面設(shè)置里面(這里我只是簡單的設(shè)計成正方形,節(jié)省時間,需要別的設(shè)計,或者探討,可以加我QQ或者vx)
七、編譯演示。
(1)如果你工程很多,需要將你要演示的調(diào)制成活動項目,如下圖所示;
(2)編譯 -> 運行 -> 結(jié)果顯示
剛才就說過了,界面設(shè)置你除了手動畫,還可以在這個函數(shù)里面進行添加,如下圖所示;
廢話不多說,看演示結(jié)果;
點擊開始,開始計數(shù);
點擊計次,開始加次數(shù);
暫停 -> 重置 重置之后回到清零狀態(tài);
另:看完了這個大家也可以試著設(shè)計自己手機中秒表的界面,亦或是下圖的計時器,原理異曲同工,大家可以試著調(diào)用video相關(guān)函數(shù),通過鼠標(biāo)點擊函數(shù)去實現(xiàn)聲音大小的控制。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Java C++ 算法題解leetcode1608特殊數(shù)組特征值
這篇文章主要為大家介紹了Java C++ 算法題解拓展leetcode1608特殊數(shù)組特征值實例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-09-09怎么實現(xiàn)類的成員函數(shù)作為回調(diào)函數(shù)
不使用成員函數(shù),為了訪問類的成員變量,可以使用友元操作符(friend),在C++中將該函數(shù)說明為類的友元即可2013-10-10