用QT实现Windows定时关机功能

来源:互联网 发布:the essence of sql 编辑:程序博客网 时间:2024/06/08 18:11

      目前网上定时关机的小工具很多,但是按照个人使用经验来说,网上很多小工具都是有毒或者带有恶意代码或者流氓代码的。因为平时经常下载东西,需要使用定时关机,所以干脆自己写了个定时关机的软件,简单易用。

      截图基于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编程序的经验而已。

 

原创粉丝点击