QT自定义控件之倒计时控件
生活随笔
收集整理的這篇文章主要介紹了
QT自定义控件之倒计时控件
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
文章目錄
- 1 效果預覽
- 2 加載背景圖片
- 3 尺子可拉動頭部的實現
- 4 整個尺子部分的實現
- 5 表盤的實現
- 6 主界面代碼實現
1 效果預覽
我們首先來看下實現的效果:
右邊的表帶拉動會使左邊的表盤跟隨轉動,停止后會開啟倒計時。
2 加載背景圖片
先來看下工程目錄:
直接繪制背景即可,比較簡單,實現代碼如下:
ccwindowwidget.h:
#ifndef CCWINDOWWIDGET_H #define CCWINDOWWIDGET_H#include <QWidget>class CCWindowWidget : public QWidget { public:explicit CCWindowWidget(QWidget* parent = 0);~CCWindowWidget();void paintEvent(QPaintEvent *event); };#endif // CCWINDOWWIDGET_Hccwindowwidget.cpp:
#include "ccwindowwidget.h" #include <QPainter> #include <QDebug> #include <QDesktopWidget> #include <QApplication>#define LANUNCHER_WIDTH 436 #define LANUCHER_HEIGHT 775CCWindowWidget::CCWindowWidget(QWidget* parent) : QWidget(parent) {setAutoFillBackground(true);setMaximumSize(LANUNCHER_WIDTH, LANUCHER_HEIGHT);setMinimumSize(LANUNCHER_WIDTH, LANUCHER_HEIGHT);setWindowFlags(windowFlags() & ~Qt::WindowMinMaxButtonsHint);QDesktopWidget* desktop = QApplication::desktop();int startX = (desktop->width() - LANUNCHER_WIDTH) / 2;int startY = (desktop->height() - LANUCHER_HEIGHT) / 2;setGeometry(startX, startY, LANUNCHER_WIDTH, LANUCHER_HEIGHT); }CCWindowWidget::~CCWindowWidget() {}void CCWindowWidget::paintEvent(QPaintEvent *event) {QPainter painter(this);painter.save();painter.drawPixmap(rect(), QPixmap(":/res/images/background.png"));painter.restore(); }3 尺子可拉動頭部的實現
這里的要點就是當被拉動時,需要發送信號給父部件,讓父部件及時感知,并做出相關調整。
相關代碼如下:
ccrulerheader.h:
#ifndef QRULERHEADER_H #define QRULERHEADER_H#include <QWidget> #include <QPushButton> #include <QMouseEvent>class CCRulerHeader:public QWidget {Q_OBJECT public:explicit CCRulerHeader(QWidget* parent=0);virtual ~CCRulerHeader();private:QPoint last_mouse_position;signals:void rulerHeaderMoveSignal(int posY);void rulerHeaderMoveDoneSignal();protected:void mousePressEvent(QMouseEvent* event);void mouseMoveEvent(QMouseEvent* event);void mouseReleaseEvent(QMouseEvent* event);void paintEvent(QPaintEvent* event); };#endif // QRULERHEADER_Hccrulerheader.cpp如下:
#include "ccrulerheader.h" #include <QPainter> #include <QDebug>#define RULERHEADER_WIDTH 82 #define RULERHEADER_HEIGHT 91CCRulerHeader::CCRulerHeader(QWidget* parent):QWidget(parent) {setGeometry(0,0,RULERHEADER_WIDTH,RULERHEADER_HEIGHT);setStyleSheet("border-image:url(:/images/ImageResources/ruler_head.png)" ); } CCRulerHeader::~CCRulerHeader() {} void CCRulerHeader::mousePressEvent(QMouseEvent* event) {if (event->button() == Qt::LeftButton){last_mouse_position = event->globalPos();} }void CCRulerHeader::mouseMoveEvent(QMouseEvent* event) {if (event->buttons() & Qt::LeftButton){const QPoint position = event->globalPos() - last_mouse_position;//qDebug()<<"POSY:"<<last_mouse_position<<""<<event->globalPos()<<" "<< position;emit rulerHeaderMoveSignal(position.y());} }void CCRulerHeader::mouseReleaseEvent(QMouseEvent* event) {Q_UNUSED(event);emit rulerHeaderMoveDoneSignal(); } void CCRulerHeader::paintEvent(QPaintEvent* event) {Q_UNUSED(event);QPainter painter(this);painter.setRenderHint(QPainter::Antialiasing, true);painter.save();painter.drawPixmap(rect(),QPixmap(":/images/ImageResources/ruler_head.png"));painter.restore();}這里我們需要注意的一點是:當我們要實現控件移動時一定要使用globalPos函數,千萬不要使用pos函數,一旦涉及到移動我就要以桌面左上角為參考點來移動,而不是所激活的窗口!
4 整個尺子部分的實現
ccstrechruler.h:
#ifndef QSTRECHRULER_H #define QSTRECHRULER_H#include <QWidget>class CCRulerHeader;class CCStrechRuler : public QWidget {Q_OBJECT public:explicit CCStrechRuler(QWidget *parent = 0);virtual ~CCStrechRuler();void UpdateRulerHeight(float aValue);void SetRulerReset();private:CCRulerHeader* m_pRulerHeader;QPoint m_originalPosition;int m_currentPosY;signals:void rulerStrechSignal(float value);void rulerStrechDoneSignal(float value);private slots:void OnRulerHeadMove(int moveValue);void OnRulerHeadMoveDone();protected:void paintEvent(QPaintEvent* event); };#endif // QSTRECHRULER_Hccstrechruler.cpp:
#include "ccstrechruler.h" #include "ccrulerheader.h"#include <QDebug> #include <QPainter>#define RULERWIDGET_STARTX 351 #define RULERWIDGET_STARTY 100#define RULERWIDGET_WIDTH 82 #define RULERWIDGET_HEIGHT 574#define RULER_MAX_HEIGHT 486CCStrechRuler::CCStrechRuler(QWidget *parent) : QWidget(parent) {setGeometry(RULERWIDGET_STARTX,RULERWIDGET_STARTY,RULERWIDGET_WIDTH,RULERWIDGET_HEIGHT);//setAttribute(Qt::WA_TranslucentBackground);setStyleSheet("background-color: rgba(0,0,0,0)"); // QPalette palette; // palette.setColor(QPalette::Background, Qt::green); // setPalette(palette);m_pRulerHeader = new CCRulerHeader(this);connect(m_pRulerHeader,SIGNAL(rulerHeaderMoveSignal(int)),SLOT(OnRulerHeadMove(int)));connect(m_pRulerHeader,SIGNAL(rulerHeaderMoveDoneSignal()),SLOT(OnRulerHeadMoveDone()));m_originalPosition=m_pRulerHeader->pos();m_currentPosY = m_originalPosition.ry(); } CCStrechRuler::~CCStrechRuler() {} void CCStrechRuler::UpdateRulerHeight(float aValue) {//qDebug()<<"CurrentRatio"<<aValue<<endl;int currentY = aValue *RULER_MAX_HEIGHT;m_pRulerHeader->move(m_originalPosition.rx(),currentY);repaint(); }void CCStrechRuler::SetRulerReset() {m_pRulerHeader->move(m_originalPosition.rx(),0);m_currentPosY =0;repaint(); }void CCStrechRuler::OnRulerHeadMove(int aValue) {if(m_pRulerHeader == NULL){return;}int realPosY= m_currentPosY + aValue;if((realPosY <= RULER_MAX_HEIGHT) && (realPosY >= 0)){m_pRulerHeader->move(m_originalPosition.rx(),realPosY);}//qDebug()<<"POSY:"<<m_pRulerHeader->pos().y()<<" "<<aValue<<" " <<realPosY;float dialRatio = m_pRulerHeader->pos().y() / 486.0;emit rulerStrechSignal(dialRatio);repaint();}void CCStrechRuler::OnRulerHeadMoveDone() {m_currentPosY=m_pRulerHeader->pos().y();float dialRatio = m_pRulerHeader->pos().y() / 486.0;emit rulerStrechDoneSignal(dialRatio); }void CCStrechRuler::paintEvent(QPaintEvent* event) {Q_UNUSED(event);QPainter painter(this);painter.setRenderHint(QPainter::Antialiasing, true);painter.save();painter.setPen(QPen(QColor(127, 159, 124), 1));painter.setBrush(QColor(127, 159, 124));painter.drawRect(15, 3, 52, m_pRulerHeader->pos().y());painter.restore();int lScale =25;int sScale= 5;int currentRulerHeight=m_pRulerHeader->pos().y();int sScale_count = currentRulerHeight / sScale +1;int lScale_count = currentRulerHeight / lScale +1;painter.setPen(QPen(QColor(255, 255, 255),1));for(int i=0; i< sScale_count; i++){if( i % 5 != 0){painter.drawLine(QPointF(67-5, 5*i), QPointF(67, 5*i));}}for(int i=0; i< lScale_count; i++){painter.drawLine(QPointF(67-10, 25*i), QPointF(67, 25*i));}}5 表盤的實現
ccdialclock.h:
#ifndef CCDIALCLOCK_H #define CCDIALCLOCK_H#include <QWidget>class CCDialClock : public QWidget {Q_OBJECT public:explicit CCDialClock(QWidget *parent = 0);virtual ~CCDialClock();public slots:void SetupClockTime(float value);protected:void paintEvent(QPaintEvent* event);private:float m_rotateValue; };#endif // CCDIALCLOCK_Hccdialclock.cpp:
#include "ccdialclock.h" #include <QPainter> #include <QDebug>#define DIALCLOCK_STARTX 75 #define DIALCLOCK_STARTY 188 #define DIALCLOCK_WIDTH 285 #define DIALCLOCK_HEIGHT 285#define NEEDLE_WIDTH 26 #define NEEDLE_HEIGHT 90CCDialClock::CCDialClock(QWidget *parent) : QWidget(parent) {setGeometry(DIALCLOCK_STARTX,DIALCLOCK_STARTY,DIALCLOCK_WIDTH,DIALCLOCK_HEIGHT);setStyleSheet("background-color: rgba(0,0,0,0)");m_rotateValue = 0.0; } CCDialClock::~CCDialClock() { } void CCDialClock::SetupClockTime(float aValue) {m_rotateValue = 360 * aValue;//qDebug()<<"VALUE:"<<m_rotateValue;repaint(); }void CCDialClock::paintEvent(QPaintEvent* event) {Q_UNUSED(event);QPainter painter(this);painter.setRenderHint(QPainter::Antialiasing, true);painter.setRenderHint(QPainter::SmoothPixmapTransform, true);painter.drawPixmap(rect(),QPixmap(":/images/ImageResources/dial.png"));painter.save();painter.translate(width()/2,height()/2);painter.rotate(m_rotateValue);painter.drawPixmap(-13,-78,NEEDLE_WIDTH,NEEDLE_HEIGHT,QPixmap(":/images/ImageResources/needle.png"));painter.restore(); }6 主界面代碼實現
ccwindowwidget.h:
#ifndef CCWINDOWWIDGET_H #define CCWINDOWWIDGET_H#include <QWidget> #include <QMouseEvent> #include <QPushButton> #include <QLabel> #include <QTimer>class CCStrechRuler; class CCDialClock;class CCWindowWidget : public QWidget {Q_OBJECT public:explicit CCWindowWidget(QWidget *parent = 0);virtual ~CCWindowWidget();private:void loadFrontWidgets();QString caculateFormatTimeWithSeconds(int aSeconds);private:QPoint last_mouse_position;CCStrechRuler *m_pStretchRuler;CCDialClock *m_pDialClock;QPushButton *m_pPlayButton;QPushButton *m_pResetButton;QLabel *m_pTimeLabel;int m_nRulerSettedSeconds;QTimer *m_pCountDownTimer;bool m_bTimerPlaying;private slots:void OnPlayButtonClicked();void OnResetButtonClicked();void OnRulerStrechDone(float aValue);void OnCountDownTimerProcess();protected:void paintEvent(QPaintEvent* event); };#endif // CCWINDOWWIDGET_Hccwindowwidget.h:
#include <QDesktopWidget> #include <QApplication> #include <QVBoxLayout> #include <QHBoxLayout> #include <QPushButton> #include <QPainter> #include <QDebug> #include <cstdlib> #include <QTime>#include "ccwindowwidget.h" #include "ccstrechruler.h" #include "ccdialclock.h"#define LANCHERWIDGET_WIDTH 436 #define LANCHERWIDGET_HEIGHT 775#define TOOLBUTTON_WIDTH 75 #define TOOLBUTTON_HEIGHT 75CCWindowWidget::CCWindowWidget(QWidget *parent) : QWidget(parent) {setWindowFlags(windowFlags() & ~Qt::WindowMinMaxButtonsHint);setMinimumSize(LANCHERWIDGET_WIDTH ,LANCHERWIDGET_HEIGHT);setMaximumSize(LANCHERWIDGET_WIDTH ,LANCHERWIDGET_HEIGHT);setAutoFillBackground(true);setAttribute(Qt::WA_TranslucentBackground);QDesktopWidget *deskdop = QApplication::desktop();int startX = (deskdop->width() - LANCHERWIDGET_WIDTH)/2;int startY = (deskdop->height() - LANCHERWIDGET_HEIGHT)/2;setGeometry(startX, startY,LANCHERWIDGET_WIDTH,LANCHERWIDGET_HEIGHT);m_nRulerSettedSeconds =0;m_bTimerPlaying = false;loadFrontWidgets();m_pCountDownTimer= new QTimer(this);connect(m_pCountDownTimer,SIGNAL(timeout()),this,SLOT(OnCountDownTimerProcess()));} CCWindowWidget::~CCWindowWidget() {if(m_pStretchRuler != NULL){delete m_pStretchRuler;m_pStretchRuler = NULL;}if(m_pDialClock != NULL){delete m_pDialClock;m_pDialClock = NULL;} }void CCWindowWidget::loadFrontWidgets() {m_pStretchRuler = new CCStrechRuler(this);m_pDialClock = new CCDialClock(this);connect(m_pStretchRuler,SIGNAL(rulerStrechSignal(float)),m_pDialClock,SLOT(SetupClockTime(float)));connect(m_pStretchRuler,SIGNAL(rulerStrechDoneSignal(float)),this,SLOT(OnRulerStrechDone(float)));QFont font;font.setFamily("PingFang TC");font.setWeight(25);font.setPixelSize(35);m_pTimeLabel = new QLabel(this);m_pTimeLabel->setGeometry(138,525,160,60);m_pTimeLabel->setFont(font);m_pTimeLabel->setStyleSheet("background: transparent;color:#d16b5d");m_pTimeLabel->setAlignment(Qt::AlignCenter);m_pTimeLabel->setText("00:00");m_pPlayButton = new QPushButton(this);m_pPlayButton->setGeometry(111,630,TOOLBUTTON_WIDTH,TOOLBUTTON_WIDTH);m_pPlayButton->setIcon(QIcon(":/images/ImageResources/play.png"));m_pPlayButton->setIconSize(QSize(TOOLBUTTON_WIDTH, TOOLBUTTON_HEIGHT));m_pPlayButton->setAutoFillBackground(true);m_pPlayButton->setFlat( true );m_pPlayButton->setStyleSheet("QPushButton{background: transparent;}");connect(m_pPlayButton,SIGNAL(clicked(bool)),SLOT(OnPlayButtonClicked()));m_pResetButton = new QPushButton(this);m_pResetButton->setGeometry(251,630,TOOLBUTTON_WIDTH,TOOLBUTTON_WIDTH);m_pResetButton->setIcon(QIcon(":/images/ImageResources/reset.png"));m_pResetButton->setIconSize(QSize(TOOLBUTTON_WIDTH, TOOLBUTTON_HEIGHT));m_pResetButton->setAutoFillBackground(true);m_pResetButton->setFlat( true );m_pResetButton->setStyleSheet("QPushButton{background: transparent;}");connect(m_pResetButton,SIGNAL(clicked(bool)),SLOT(OnResetButtonClicked()));}void CCWindowWidget::OnRulerStrechDone(float aValue) {if(aValue >= 1.0 ){aValue = 0.9999;}int mSeconds = (int)3600*aValue;QString formatTime= caculateFormatTimeWithSeconds(mSeconds);m_pTimeLabel->setText(formatTime);m_nRulerSettedSeconds = mSeconds;if(m_pCountDownTimer->isActive()){m_pCountDownTimer->stop();m_bTimerPlaying = false;}m_pCountDownTimer->start(1000);m_bTimerPlaying = true;m_pPlayButton->setIcon(QIcon(":/images/ImageResources/pause.png"));}QString CCWindowWidget::caculateFormatTimeWithSeconds(int aSeconds) {int tMinutes = aSeconds / 60;int tSeconds = aSeconds - tMinutes* 60;QString strMinutes = QString("%1").arg(tMinutes);QString strSeconds = QString("%1").arg(tSeconds);if((tMinutes <10) && (tMinutes >=0)){strMinutes = QString("0%1").arg(tMinutes);}if((tSeconds <10) && (tSeconds >=0)){strSeconds = QString("0%1").arg(tSeconds);}QString formatTime = QString("%1:%2").arg(strMinutes).arg(strSeconds);return formatTime; }void CCWindowWidget::OnCountDownTimerProcess() {if(m_nRulerSettedSeconds <=0){OnResetButtonClicked();}QString formatTime= caculateFormatTimeWithSeconds(m_nRulerSettedSeconds);m_pTimeLabel->setText(formatTime);float currentRatio = m_nRulerSettedSeconds /3600.0;m_pStretchRuler->UpdateRulerHeight(currentRatio);m_nRulerSettedSeconds--;}void CCWindowWidget::OnPlayButtonClicked() {if(m_bTimerPlaying == true){if(m_pCountDownTimer->isActive()){m_pCountDownTimer->stop();m_bTimerPlaying = false;}m_pPlayButton->setIcon(QIcon(":/images/ImageResources/play.png"));}else{m_pCountDownTimer->start(1000);m_bTimerPlaying = true;m_pPlayButton->setIcon(QIcon(":/images/ImageResources/pause.png"));}}void CCWindowWidget::OnResetButtonClicked() {if(m_bTimerPlaying == true){if(m_pCountDownTimer->isActive()){m_pCountDownTimer->stop();}}m_pPlayButton->setIcon(QIcon(":/images/ImageResources/play.png"));m_bTimerPlaying = false;m_nRulerSettedSeconds =0;m_pTimeLabel->setText("00:00");m_pDialClock->SetupClockTime(0.0);m_pStretchRuler->SetRulerReset();}void CCWindowWidget::paintEvent(QPaintEvent* event) {Q_UNUSED(event);QPainter p(this);p.save();p.drawPixmap(rect(),QPixmap(":/images/ImageResources/background.png"));p.restore();}main.cpp:
#include <QApplication> #include "ccwindowwidget.h"int main(int argc, char *argv[]) {QApplication a(argc, argv);CCWindowWidget windowWidget;windowWidget.show();return a.exec(); }總結:如果是不同對象之間的消息傳遞我們使用信號與槽即可,如果是父子對象之間的消息傳遞,子對象向父對象傳遞消息,我們使用信號與槽,而父對象向子對象傳遞消息我們直接使用函數即可!
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的QT自定义控件之倒计时控件的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 俄升级T-90S主战坦克
- 下一篇: QMouseEvent