用QT实现Windows定时关机功能
2010-07-16 19:37
851 查看
目前网上定时关机的小工具很多,但是按照个人使用经验来说,网上很多小工具都是有毒或者带有恶意代码或者流氓代码的。因为平时经常下载东西,需要使用定时关机,所以干脆自己写了个定时关机的软件,简单易用。
截图基于WIN7系统,顺便说一句,WIN7下的小软件很漂亮。
首先,软件需要最小化托盘运行,并且显示倒计时悬浮窗。这里设置为在右下角显示。代码如下:
SusWidget.h
SusWidget.cpp
定时关机需要一个后台线程来实现计时功能:
TimeThread.h
TimeThread.cpp
一般的定时关机软件还需要显示当前系统时间:
SystemTimeThread.h
SystemTimeThread.cpp
好了,上面的主要部分都已经编写完成,接下来就是主要界面了。定时关机只是一个小软件,所以尽量的简单易用,不要加入过多不必要的功能。代码如下:
shutdown.h
shutdown.cpp
对于QT,还有个主函数:
main.cpp
至此一个简单的定时关机程序就编写完了。我也是个QT初学者,代码可能有些生涩,只是分享一下初次使用QT编程序的经验而已。
截图基于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 #endif class SusWidget : public QWidget { Q_OBJECT public: 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 2 class TimeThread : public QThread { Q_OBJECT public: 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; //获取关机特权的LUID LookupPrivilegeValue(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_OBJECT public: 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_OBJECT public: 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编程序的经验而已。
相关文章推荐
- 利用Python实现Windows定时关机功能
- Windows内核对象 - 通过异步程序调用(APC)实现的定时功能
- C#实现远程关机功能(windows和linux)
- windows实现不关机自动联网功能(公司)
- XP、Windows7下自动关机vbs脚本,使用windows计划任务+vbs脚本在XP、Windows7下实现定时自动关机
- 轻松实现Windows定时关机,何必麻烦第三方软件
- Win7的定时关机功能(计划任务+shutdown.exe实现)
- 利用select函数的定时返回功能在Windows上实现微秒级的cpu休眠
- 在WINDOWS任务计划程序下执行PHP文件 PHP定时功能的实现
- windows下用vim实现qt代码的自动补全功能(zz)
- 利用PHP安装windows自动运行的服务,PHP程序可以实现长时间、自动运行、定时更新功能,直接可以用在项目中的类源代码
- windows下用vim实现qt代码的自动补全功能
- 在windows平台上使用Qt和libmodbus库实现modbus主机功能--转载
- 【Windows定时关机】windows实现定时关机与取消
- win7系统实现定时关机功能
- 用VC6.0实现定时关机功能
- 在windows平台上使用Qt和libmodbus库实现modbus主机功能--转载
- 在windows平台上使用Qt和libmodbus库实现modbus主机功能
- win7系统通过shutdown命令实现定时关机功能
- 简单实现windows系统普通或强制关机重启注销的功能