用QT實現Windows定時關機功能

來源:互聯網
上載者:User

      目前網上定時關機的小工具很多,但是按照個人使用經驗來說,網上很多小工具都是有毒或者帶有惡意代碼或者流氓代碼的。因為平時經常下載東西,需要使用定時關機,所以乾脆自己寫了個定時關機的軟體,簡單易用。

      基於WIN7系統,順便說一句,WIN7下的小軟體很漂亮。

      首先,軟體需要最小化托盤運行,並且顯示倒計時懸浮窗。這裡設定為在右下角顯示。代碼如下:

     

 SusWidget.h

#ifndef SUSWIDGET_H#define SUSWIDGET_H#include <QtGui/QWidget>#include <QDateTime>#include <QtGui/QLineEdit>#include <QtCore/QTextCodec>#include <QtGui/QApplication>#include <QDesktopWidget>#ifndef    REMAIN_TIME#define   REMAIN_TIME            0#endif#ifndef    TO_SHUTDOWN#define   TO_SHUTDOWN         1#endif#ifndef    SHUTDOWN_ERROR#define   SHUTDOWN_ERROR  2#endifclass SusWidget : public QWidget{Q_OBJECTpublic:SusWidget(QWidget *parent = 0, Qt::WFlags flags = 0);~SusWidget();private:QLineEdit  *timeEdit;public slots:void SetRemainTime(const QTime &time, int type);};#endif // SUSWIDGET_H

 

 SusWidget.cpp

#include "suswidget.h"SusWidget::SusWidget(QWidget *parent, Qt::WFlags flags): QWidget(parent, flags){setFixedSize(170, 20);QTextCodec::setCodecForTr(QTextCodec::codecForName("gb18030"));setWindowFlags(Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint | Qt::Tool);QRect   screenSize;screenSize = QApplication::desktop()->rect();setGeometry(screenSize.width()-180, screenSize.height()-70, 170, 20);timeEdit = new QLineEdit(this);timeEdit->setGeometry(rect());QPalette palette;QBrush brush(QColor(255, 255, 0, 255));brush.setStyle(Qt::SolidPattern);QBrush brush1(QColor(85, 0, 0, 255));brush1.setStyle(Qt::SolidPattern);palette.setBrush(QPalette::Active, QPalette::Text, brush);palette.setBrush(QPalette::Active, QPalette::Base, brush1);palette.setBrush(QPalette::Inactive, QPalette::Text, brush);palette.setBrush(QPalette::Inactive, QPalette::Base, brush1);palette.setBrush(QPalette::Disabled, QPalette::Text, brush);palette.setBrush(QPalette::Disabled, QPalette::Base, brush1);timeEdit->setPalette(palette);QFont font;font.setFamily(QString::fromUtf8("\351\273\221\344\275\223"));font.setBold(true);font.setWeight(75);timeEdit->setFont(font);timeEdit->setAlignment(Qt::AlignCenter);timeEdit->setText(tr("正在統計關機剩餘時間..."));timeEdit->setReadOnly(true);}SusWidget::~SusWidget(){}void SusWidget::SetRemainTime(const QTime &time, int type){if ( type == REMAIN_TIME ){timeEdit->setText( tr("離關機還有:") + time.toString(tr("hh時mm分ss秒")) );}if ( type == TO_SHUTDOWN ){timeEdit->setText( tr("正在關機...") );}if ( type == SHUTDOWN_ERROR ){timeEdit->setText( tr("關機失敗...") );}}

     定時關機需要一個後台線程來實現計時功能:

TimeThread.h

#ifndef TIMETHREAD_H#define TIMETHREAD_H#include <QDateTime>#include <QThread>#include <Windows.h>#define   REMAIN_TIME            0#define   TO_SHUTDOWN         1#define   SHUTDOWN_ERROR  2class TimeThread : public QThread{Q_OBJECTpublic:QTime m_time;bool m_start;public:TimeThread(QObject *parent = 0);void SetCountTime(QTime time, bool start);bool MySystemShutdown();signals:void RemainTimeChanged(const QTime &time, int type);protected:void run();};#endif

 

TimeThread.cpp

#include "TimeThread.h"TimeThread::TimeThread(QObject *parent) : QThread(parent){m_time = QTime(1, 0, 0);m_start = false;}void TimeThread::SetCountTime(QTime time, bool start){m_time = time;m_start = start;}void TimeThread::run(){QTime  oldTime, newTime;oldTime.setHMS(QTime::currentTime().hour(), QTime::currentTime().minute(), QTime::currentTime().second(), 0);while(m_start){msleep(250);newTime.setHMS(QTime::currentTime().hour(), QTime::currentTime().minute(), QTime::currentTime().second(), 0);if ( oldTime != newTime ){oldTime = newTime;m_time = m_time.addSecs(-1);}emit  RemainTimeChanged(m_time, REMAIN_TIME);if ( m_time == QTime(0, 0, 0) ){emit  RemainTimeChanged(m_time, TO_SHUTDOWN);if ( !MySystemShutdown() ){emit  RemainTimeChanged(m_time, SHUTDOWN_ERROR);}break;}}}bool TimeThread::MySystemShutdown(){HANDLE hToken; TOKEN_PRIVILEGES tkp; //擷取進程標誌if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) return false; //擷取關機特權的LUIDLookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid); tkp.PrivilegeCount = 1; tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; //擷取這個進程的關機特權AdjustTokenPrivileges(hToken, false, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0); if (GetLastError() != ERROR_SUCCESS) return false; // 強制關閉電腦 if (  !ExitWindowsEx(EWX_SHUTDOWN | EWX_FORCE,      SHTDN_REASON_MAJOR_OPERATINGSYSTEM | SHTDN_REASON_MINOR_UPGRADE |SHTDN_REASON_FLAG_PLANNED))  return false; return true;} 

 

       一般的定時關機軟體還需要顯示當前系統時間:

SystemTimeThread.h

#ifndef SYSTEMTIMETHREAD_H#define SYSTEMTIMETHREAD_H#include <QDateTime>#include <QThread>class SystemTimeThread : public QThread{Q_OBJECTpublic:QTime m_time;public:SystemTimeThread(QObject *parent = 0);signals:void CurrentTimeChanged(const QTime &time);protected:void run();};#endif

 

SystemTimeThread.cpp

#include "SystemTimeThread.h"SystemTimeThread::SystemTimeThread(QObject *parent) :  QThread(parent){m_time = m_time.currentTime();}void SystemTimeThread::run(){while(1){msleep(500);m_time = m_time.currentTime();emit CurrentTimeChanged(m_time);}}

      好了,上面的主要部分都已經編寫完成,接下來就是主要介面了。定時關機只是一個小軟體,所以盡量的簡單易用,不要加入過多不必要的功能。代碼如下:

 shutdown.h

#ifndef SHUTDOWN_H#define SHUTDOWN_H#include <QtCore/QVariant>#include <QtGui/QAction>#include <QtGui/QApplication>#include <QtGui/QButtonGroup>#include <QtGui/QDialog>#include <QtGui/QGroupBox>#include <QtGui/QLabel>#include <QtGui/QLineEdit>#include <QtGui/QPushButton>#include <QtGui/QRadioButton>#include <QtGui/QTimeEdit>#include <QRegExpValidator>#include <QString>#include <QDateTime>#include <QSystemTrayIcon>#include "TimeThread.h"#include "SusWidget.h"#include "SystemTimeThread.h"class ShutDown : public QDialog{Q_OBJECTpublic:ShutDown(QWidget *parent = 0, Qt::WFlags flags = 0);~ShutDown();private:QGroupBox *chooseGroup;QRadioButton *countDownRadio;QRadioButton *timerRadio;QTimeEdit *countEdit;QTimeEdit *timeEdit;QLabel *remainText;QLineEdit *remainTimeLine;QLineEdit *systemTimeLine;QLabel *currentTimeText;QPushButton *startButton;QPushButton *exitButton;QAction *susAction;QAction *restoreAction;QAction *quitAction;QSystemTrayIcon *trayIcon;QMenu *trayIconMenu;QTime    m_time;bool       m_start;bool       m_countDown;bool       m_mini;bool       m_suspend;TimeThread  m_timeThread;SystemTimeThread  m_systemTimeThread;SusWidget *swidget;//protected://void closeEvent(QCloseEvent *event);public:void createActions();void createTrayIcon();void SetSusTime(const QTime &time, int type);signals:void RemainTimeChanged(const QTime &time, int type);private slots:void  CountTimeChanged(const QTime &time);void  ClickedCountDownRadio();void  doTimeChanged(const QTime &time);void  ClickedTimerRadio();void  ClickedStartButton();void  SetRemainTime(const QTime &time, int type);void  SetCurrentTime(const QTime &time);void  ShowDialog();void  ClikedTrayIcon(QSystemTrayIcon::ActivationReason reason);void  ShowSusWidget();void  HideOrExit();};#endif // SHUTDOWN_H

 

shutdown.cpp

#include "shutdown.h"#include <QtGui>ShutDown::ShutDown(QWidget *parent, Qt::WFlags flags): QDialog(parent, flags){if (objectName().isEmpty())  setObjectName(QString::fromUtf8("ShutDown"));setFixedSize(264, 261);setWindowFlags(Qt::WindowMinimizeButtonHint);QIcon icon;icon.addPixmap(QPixmap(QString::fromUtf8("Resources/shutdown.png")), QIcon::Normal, QIcon::Off);setWindowIcon(icon);createActions();createTrayIcon();chooseGroup = new QGroupBox(this);chooseGroup->setGeometry(QRect(20, 10, 221, 191));chooseGroup->setAlignment(Qt::AlignCenter);countDownRadio = new QRadioButton(chooseGroup);countDownRadio->setGeometry(QRect(20, 30, 101, 21));timerRadio = new QRadioButton(chooseGroup);timerRadio->setGeometry(QRect(20, 70, 101, 21));countEdit = new QTimeEdit(chooseGroup);countEdit->setGeometry(QRect(120, 30, 81, 22));countEdit->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);countEdit->setTime(QTime(1, 0, 0));timeEdit = new QTimeEdit(chooseGroup);timeEdit->setGeometry(QRect(120, 70, 81, 22));timeEdit->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);remainText = new QLabel(chooseGroup);remainText->setGeometry(QRect(20, 110, 81, 21));remainTimeLine = new QLineEdit(chooseGroup);remainTimeLine->setGeometry(QRect(110, 110, 91, 20));remainTimeLine->setAlignment(Qt::AlignCenter);remainTimeLine->setReadOnly(true);systemTimeLine = new QLineEdit(chooseGroup);systemTimeLine->setGeometry(QRect(110, 150, 91, 20));systemTimeLine->setAlignment(Qt::AlignCenter);systemTimeLine->setReadOnly(true);currentTimeText = new QLabel(chooseGroup);currentTimeText->setGeometry(QRect(20, 150, 81, 21));startButton = new QPushButton(this);startButton->setGeometry(QRect(30, 220, 101, 23));exitButton = new QPushButton(this);exitButton->setGeometry(QRect(140, 220, 91, 23));countDownRadio->setChecked(true);timerRadio->setChecked(false);m_time = countEdit->time();remainTimeLine->setText(m_time.toString(tr("hh時mm分ss秒")));m_start = false;m_countDown = true;m_mini = false;m_suspend = true;connect(&m_timeThread, SIGNAL(RemainTimeChanged(const QTime &, int)), this, SLOT(SetRemainTime(const QTime &, int)));connect(&m_systemTimeThread, SIGNAL(CurrentTimeChanged(const QTime &)), this, SLOT(SetCurrentTime(const QTime &)));m_systemTimeThread.start();swidget = new SusWidget(0);connect(exitButton, SIGNAL(clicked()), this, SLOT(HideOrExit()));    //reject()connect(countEdit, SIGNAL(timeChanged(const QTime &)), this, SLOT(CountTimeChanged(const QTime &)));connect(countDownRadio, SIGNAL(clicked()), this, SLOT(ClickedCountDownRadio()));connect(timeEdit, SIGNAL(timeChanged(const QTime &)), this, SLOT(doTimeChanged(const QTime &)));connect(timerRadio, SIGNAL(clicked()), this, SLOT(ClickedTimerRadio()));connect(startButton, SIGNAL(clicked()), this, SLOT(ClickedStartButton()));connect(this, SIGNAL(RemainTimeChanged(const QTime &, int)), swidget, SLOT(SetRemainTime(const QTime &, int)));setWindowTitle(QApplication::translate("ShutDown", "\351\243\230\344\272\221\345\256\232\346\227\266\345\205\263\346\234\272\347\250\213\345\272\217", 0, QApplication::UnicodeUTF8));chooseGroup->setTitle(QApplication::translate("ShutDown", "\350\256\276\345\256\232\345\205\263\346\234\272\346\226\271\345\274\217", 0, QApplication::UnicodeUTF8));countDownRadio->setText(QApplication::translate("ShutDown", "\350\256\276\345\256\232\345\200\222\350\256\241\346\227\266\357\274\232", 0, QApplication::UnicodeUTF8));timerRadio->setText(QApplication::translate("ShutDown", "\350\256\276\345\256\232\345\205\263\346\234\272\346\227\266\351\227\264\357\274\232", 0, QApplication::UnicodeUTF8));remainText->setText(QApplication::translate("ShutDown", "\345\205\263\346\234\272\345\211\251\344\275\231\346\227\266\351\227\264\357\274\232", 0, QApplication::UnicodeUTF8));currentTimeText->setText(QApplication::translate("Dialog", "\345\275\223\345\211\215\347\263\273\347\273\237\346\227\266\351\227\264\357\274\232", 0, QApplication::UnicodeUTF8));startButton->setText(QApplication::translate("ShutDown", "\345\274\200\345\247\213\345\256\232\346\227\266\345\205\263\346\234\272", 0, QApplication::UnicodeUTF8));exitButton->setText(QApplication::translate("ShutDown", "\351\232\220\350\227\217\346\210\226\351\200\200\345\207\272", 0, QApplication::UnicodeUTF8));}ShutDown::~ShutDown(){m_systemTimeThread.terminate();m_systemTimeThread.wait();}/*void ShutDown::closeEvent(QCloseEvent *event){int choose = QMessageBox::question(this, tr("最小化到托盤或退出程式"),tr("飄雲溫情提示:\n      是否將程式最小化到托盤?最小化請點擊Yes,退出程式請點擊No。\n最小化後如需退出程式,請在托盤表徵圖上點擊右鍵,選擇退出!") ,QMessageBox::Yes | QMessageBox::No, QMessageBox::No);if( choose == QMessageBox::Yes ){hide();event->ignore();trayIcon->show();m_mini = true;if(m_start)  trayIcon->setToolTip(tr("定時關機程式正在運行"));else trayIcon->setToolTip(tr("定時關機程式已經停止運行"));m_suspend = true;if(m_start) swidget->show();}else{reject();}}*/void  ShutDown::HideOrExit(){int choose = QMessageBox::question(this, tr("最小化到托盤或退出程式"),tr("飄雲溫情提示:\n      是否將程式最小化到托盤?最小化請點擊Yes,退出程式請點擊No。\n最小化後如需退出程式,請在托盤表徵圖上點擊右鍵,選擇退出!") ,                                     QMessageBox::Yes | QMessageBox::No, QMessageBox::No);if( choose == QMessageBox::Yes ){hide();trayIcon->show();m_mini = true;if(m_start)  trayIcon->setToolTip(tr("定時關機程式正在運行"));else trayIcon->setToolTip(tr("定時關機程式已經停止運行"));m_suspend = true;if(m_start) swidget->show();}else{reject();}}void ShutDown::createActions(){susAction = new QAction(tr("隱藏懸浮窗"), this);connect(susAction, SIGNAL(triggered()), this, SLOT(ShowSusWidget()));restoreAction = new QAction(tr("還原視窗"), this);connect(restoreAction, SIGNAL(triggered()), this, SLOT(ShowDialog()));quitAction = new QAction(tr("退出程式"), this);connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));QIcon icon;icon.addPixmap(QPixmap(QString::fromUtf8("Resources/sus.png")), QIcon::Normal, QIcon::Off);susAction->setIcon(icon);QIcon icon1;icon1.addPixmap(QPixmap(QString::fromUtf8("Resources/restore.png")), QIcon::Normal, QIcon::Off);restoreAction->setIcon(icon1);QIcon icon2;icon2.addPixmap(QPixmap(QString::fromUtf8("Resources/exit.png")), QIcon::Normal, QIcon::Off);quitAction->setIcon(icon2);}void ShutDown::createTrayIcon(){trayIconMenu = new QMenu(this);trayIconMenu->addAction(susAction);trayIconMenu->addAction(restoreAction);trayIconMenu->addSeparator();trayIconMenu->addAction(quitAction);trayIcon = new QSystemTrayIcon(this);trayIcon->setContextMenu(trayIconMenu);QIcon icon;icon.addPixmap(QPixmap(QString::fromUtf8("Resources/shutdown.png")), QIcon::Normal, QIcon::Off);trayIcon->setIcon(icon);connect(trayIcon, SIGNAL(activated (QSystemTrayIcon::ActivationReason)), this, SLOT(ClikedTrayIcon(QSystemTrayIcon::ActivationReason)));susAction->setEnabled(false);}void  ShutDown::ShowDialog(){showNormal();m_mini = false;trayIcon->hide();swidget->hide();}void  ShutDown::ShowSusWidget(){if ( m_suspend ){swidget->hide();susAction->setText(tr("顯示懸浮窗"));m_suspend = false;}else{swidget->show();susAction->setText(tr("隱藏懸浮窗"));m_suspend = true;}}void ShutDown::ClikedTrayIcon(QSystemTrayIcon::ActivationReason reason){if ( reason == QSystemTrayIcon::Trigger )  ShowDialog();}void ShutDown::CountTimeChanged(const QTime &time){countDownRadio->setChecked(true);timerRadio->setChecked(false);m_time = countEdit->time();remainTimeLine->setText( m_time.toString(tr("hh時mm分ss秒")) );m_countDown = true;}void ShutDown::ClickedCountDownRadio(){QTime  time = countEdit->time();CountTimeChanged(time);}void ShutDown::doTimeChanged(const QTime &time){countDownRadio->setChecked(false);timerRadio->setChecked(true);QTime systemTime;systemTime = systemTime.currentTime();QTime setTime = timeEdit->time();m_time = setTime.addSecs(-systemTime.hour()*60*60-systemTime.minute()*60-systemTime.second());remainTimeLine->setText( m_time.toString(tr("hh時mm分ss秒")) );m_countDown = false;}void ShutDown::ClickedTimerRadio(){QTime  time;time = timeEdit->time();doTimeChanged(time);}void ShutDown::ClickedStartButton(){if ( m_countDown ){m_time = countEdit->time();remainTimeLine->setText( m_time.toString(tr("hh時mm分ss秒")) );remainTimeLine->setText( m_time.toString(tr("hh時mm分ss秒")) );}else{QTime systemTime;systemTime = systemTime.currentTime();QTime setTime = timeEdit->time();m_time = setTime.addSecs(-systemTime.hour()*60*60-systemTime.minute()*60-systemTime.second());remainTimeLine->setText( m_time.toString(tr("hh時mm分ss秒")) );}if ( m_start ){//停止計時countDownRadio->setEnabled (true);timerRadio->setEnabled(true);timeEdit->setEnabled(true);countEdit->setEnabled(true);susAction->setEnabled(false);startButton->setText(tr("開始定時關機"));m_start = false;m_timeThread.SetCountTime(m_time, m_start);m_timeThread.terminate();m_timeThread.wait();}else{//開始計時countDownRadio->setEnabled (false);timerRadio->setEnabled(false);timeEdit->setEnabled(false);countEdit->setEnabled(false);susAction->setEnabled(true);startButton->setText(tr("取消定時關機"));m_start = true;m_timeThread.SetCountTime(m_time, m_start);m_timeThread.start();}}void  ShutDown::SetSusTime(const QTime &time, int type){emit RemainTimeChanged(time, type);if ( type == SHUTDOWN_ERROR ){countDownRadio->setEnabled (true);timerRadio->setEnabled(true);timeEdit->setEnabled(true);countEdit->setEnabled(true);susAction->setEnabled(false);startButton->setText(tr("開始定時關機"));m_start = false;}}void ShutDown::SetRemainTime(const QTime &time, int type){if ( !m_mini ){if ( type == REMAIN_TIME ){remainTimeLine->setText( time.toString(tr("hh時mm分ss秒")) );}if ( type == TO_SHUTDOWN ){remainTimeLine->setText( tr("正在關機...") );}if ( type == SHUTDOWN_ERROR ){remainTimeLine->setText( tr("關機失敗...") );countDownRadio->setEnabled (true);timerRadio->setEnabled(true);timeEdit->setEnabled(true);countEdit->setEnabled(true);susAction->setEnabled(false);startButton->setText(tr("開始定時關機"));m_start = false;}}if ( m_mini && m_suspend ){SetSusTime(time, type);}}void ShutDown::SetCurrentTime(const QTime &time){systemTimeLine->setText( time.toString(tr("hh時mm分ss秒")) );}

     對於QT,還有個主函數:

main.cpp

#include <QtGui/QApplication>#include <QtCore/QTextCodec>#include "shutdown.h"int main(int argc, char *argv[]){QApplication a(argc, argv);QTextCodec::setCodecForTr(QTextCodec::codecForName("gb2312"));ShutDown w;w.show();return a.exec();}

     至此一個簡單的定時關機程式就編寫完了。我也是個QT初學者,代碼可能有些生澀,只是分享一下初次使用QT編程式的經驗而已。

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.