实例介绍
【实例截图】
【核心代码】
/*************************************************************************** * Copyright (C) 2010 by Peter Hatina * * email: phatina (at) gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License * * version 2.1 as published by the Free Software Foundation * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU Lesser General Public License for more details. * * http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. * ***************************************************************************/ #include "batterymetergui.h" #include "settings.h" #include "action.h" #include "shutdown.h" #include "common.h" #ifdef Q_OS_WIN32 # include "winregistry.h" # include "powerscheme.h" #endif #include <limits> #include <QApplication> #include <QProcess> #include <QDateTime> #include <QFile> //log time (ms) const int LOGGER_TIMEOUT = 60000; BatteryMeterGui::BatteryMeterGui(QObject *parent): QTimer(parent), m_tray(new BatteryMeterTrayIcon), m_menu(new QMenu), m_act_quit(new QAction(QIcon(":/img/exit.png"), "Quit", m_menu.data())), m_act_settings(new QAction(QIcon(":/img/settings.png"), "Settings", m_menu.data())), m_act_info(new QAction(QIcon(":/img/info.png"), "Info", m_menu.data())), m_act_log(new QAction(QIcon(":/img/log.png"), "Log", m_menu.data())), #if (defined (Q_OS_WIN32) && (WINVER >= 0x0600)) m_power_menu(new QMenu()), m_actgrp_power(new QActionGroup(m_power_menu.data())), m_act_min_power(new QAction("Power saver", m_power_menu.data())), m_act_max_power(new QAction("Performance", m_power_menu.data())), m_act_balanced(new QAction("Balanced", m_power_menu.data())), #endif m_dlg_info(new InfoDialog), m_dlg_settings(new SettingsDialog) { connect(m_dlg_settings.data(), SIGNAL(newConfiguration()), this, SLOT(readConfiguration())); // setup menu actions m_act_quit->setIconVisibleInMenu(true); m_act_settings->setIconVisibleInMenu(true); m_act_info->setIconVisibleInMenu(true); m_act_log->setIconVisibleInMenu(true); // fill tray menu m_menu->addAction(m_act_info.data()); m_menu->addAction(m_act_log.data()); m_menu->addAction(m_act_settings.data()); #if (defined (Q_OS_WIN32) && (WINVER >= 0x0600)) m_power_menu.reset(m_menu->addMenu(QIcon(":/img/scheme.png"), "Power scheme")); m_act_min_power->setCheckable(true); m_act_min_power->setChecked(m_power_scheme.isMinPower()); m_act_max_power->setCheckable(true); m_act_max_power->setChecked(m_power_scheme.isMaxPower()); m_act_balanced->setCheckable(true); m_act_balanced->setChecked(m_power_scheme.isBalanced()); m_actgrp_power->addAction(m_act_min_power); m_actgrp_power->addAction(m_act_max_power); m_actgrp_power->addAction(m_act_balanced); m_actgrp_power->setExclusive(true); m_power_menu->addAction(m_act_min_power); m_power_menu->addAction(m_act_balanced); m_power_menu->addAction(m_act_max_power); connect(m_act_min_power.data(), SIGNAL(triggered()), this, SLOT(changePowerStatus())); connect(m_act_max_power.data(), SIGNAL(triggered()), this, SLOT(changePowerStatus())); connect(m_act_balanced.data(), SIGNAL(triggered()), this, SLOT(changePowerStatus())); connect(&m_message_listener, SIGNAL(powerSchemeChanged()), this, SLOT(powerStatusChanged())); if (!m_power_scheme.powrProfLoaded()) { m_menu->removeAction(m_power_menu->menuAction()); m_dlg_settings->setUseSchemes(false); } #endif m_menu->addSeparator(); m_menu->addAction(m_act_quit.data()); m_tray->setContextMenu(m_menu.data()); m_tray->setIcon(QIcon()); #ifdef USE_LOGGING // logger m_logger.setInterval(LOGGER_TIMEOUT); connect(&m_logger, SIGNAL(timeout()), this, SLOT(onLog())); #endif // action connections connect(this, SIGNAL(timeout()), this, SLOT(update())); connect(m_act_info.data(), SIGNAL(triggered()), this, SLOT(infoDlgVisibility())); connect(m_act_settings.data(), SIGNAL(triggered()), m_dlg_settings.data(), SLOT(show())); connect(m_tray.data(), SIGNAL(clicked()), this, SLOT(infoDlgVisibility())); connect(m_tray.data(), SIGNAL(hint()), m_dlg_info.data(), SLOT(show())); connect(m_act_quit.data(), SIGNAL(triggered()), qApp, SLOT(quit())); connect(m_act_quit.data(), SIGNAL(triggered()), m_tray.data(), SLOT(hide())); // read config. file readConfiguration(); } BatteryMeterGui::~BatteryMeterGui() { } void BatteryMeterGui::update() { m_battery_meter.update(); if (!m_battery_meter.batteryPresent() && m_battery_meter.acOnline()) { // no battery present, we run only on an AC adaptor m_act_info->setEnabled(false); m_tray->setPercentage(100); return; } m_act_info->setEnabled(true); // prepare data for infoDlg QString charging_state; switch (m_battery_meter.state()) { case BatteryMeter::CHARGING: charging_state = "Charging"; m_tray->setAnimate(true); break; case BatteryMeter::CHARGED: charging_state = "Charged"; m_tray->setAnimate(false); m_tray->setPercentage(m_battery_meter.percentage()); break; case BatteryMeter::DISCHARGING: charging_state = "Discharging"; m_tray->setAnimate(false); m_tray->setPercentage(m_battery_meter.percentage()); break; case BatteryMeter::UNKNOWN: charging_state = "Unknown"; m_tray->setAnimate(false); m_tray->setPercentage(100); break; } // setup info dialog m_dlg_info->setPercentage(m_battery_meter.percentage()); m_dlg_info->setCapacity(m_battery_meter.remainCapa(), m_battery_meter.designCapa()); m_dlg_info->setRate(m_battery_meter.rate()); m_dlg_info->setBatteryState(m_battery_meter.state()); m_dlg_info->setAcState(m_battery_meter.acOnline()); m_dlg_info->setTimeRemaining(m_battery_meter.remainTime()); // charged status tooltip QString toolTip = QString("Battery state: %1 % (").arg(m_battery_meter.percentage()); toolTip = charging_state ")"; unsigned long mins = m_battery_meter.remainTime(); QTime t(mins / 60, mins % 60); if (t.minute() != 0 || t.hour() != 0) { toolTip = QString("\nRemaining time: ") t.toString("hh:mm"); } else { if (!m_battery_meter.acOnline()) { singleShot(5000, this, SLOT(update())); } } m_tray->setToolTip(toolTip); if (!m_tray->isVisible()) return; static unsigned long prev_perc = std::numeric_limits <unsigned long>::max(); //bool discharge = prev_perc > m_battery_meter.percentage() // || prev_perc == std::numeric_limits <unsigned long>::max(); bool discharge = prev_perc >= m_battery_meter.percentage() && m_battery_meter.state() == BatteryMeter::DISCHARGING; prev_perc = m_battery_meter.percentage(); // process actions if (discharge) dischargeActions(); else chargeActions(); } void BatteryMeterGui::show() { m_tray->show(); } void BatteryMeterGui::hide() { m_tray->hide(); } void BatteryMeterGui::start() { if (this->isActive()) return; // run timer in seconds interval // interal comes from config Settings *settings = Settings::instance(); QTimer::start(settings->updateInterval() * 1000); #ifdef Q_OS_WIN32 m_message_listener.listen(); connect(&m_message_listener, SIGNAL(powerStatusChanged()), this, SLOT(update())); #endif } void BatteryMeterGui::start(int msec) { if (this->isActive()) return; // run in ms interval QTimer::start(msec); #ifdef Q_OS_WIN32 m_message_listener.listen(); connect(&m_message_listener, SIGNAL(powerStatusChanged()), this, SLOT(update())); #endif } void BatteryMeterGui::stop() { #ifdef Q_OS_WIN32 disconnect(&m_message_listener, SIGNAL(powerStatusChanged()), this, SLOT(update())); #endif } #ifdef USE_LOGGING void BatteryMeterGui::onLog() { if (m_log_file.isEmpty()) { // TODO maybe change the behavior m_logger.stop(); return; } QFile fout(m_log_file); if (!fout.open(QIODevice::Append)) return; QString str_line = QDateTime::currentDateTime().toString("yyyy.MM.dd-hh:mm:ss"); QString perc = QString("%1").arg(m_battery_meter.percentage()); while (perc.length() < 3) perc.prepend("0"); str_line = "," perc; str_line = QString(",%1").arg(m_battery_meter.acOnline() ? "conn" : "disc"); str_line = "\n"; QByteArray line; line.append(str_line); fout.write(line); fout.close(); } #endif void BatteryMeterGui::dischargeActions() { while (!m_unprocessed_actions.isEmpty() && (static_cast <unsigned long> (m_unprocessed_actions.last().level()) >= m_battery_meter.percentage())) { // move the action into other container Action action = m_unprocessed_actions.last(); m_unprocessed_actions.pop_back(); m_processed_actions.push_front(action); // process the action switch (action.type()) { case Action::MESSAGE: m_tray->showMessage("Battery Meter", action.attr(), QSystemTrayIcon::Information); break; case Action::ACTION: QProcess::execute(action.attr()); break; case Action::SUSPEND: Shutdown::suspend(); break; case Action::HIBERNATE: Shutdown::hibernate(); break; case Action::POWEROFF: Shutdown::shutdown(); break; default: break; } } } void BatteryMeterGui::chargeActions() { while (!m_processed_actions.isEmpty() && static_cast <unsigned long> (m_processed_actions.first().level()) < m_battery_meter.percentage()) { Action action = m_processed_actions.first(); m_processed_actions.pop_front(); m_unprocessed_actions.push_back(action); } //printActions(); } #if (defined (Q_OS_WIN32) && (WINVER >= 0x0600)) void BatteryMeterGui::changePowerStatus() { if (m_act_min_power->isChecked()) { m_power_scheme.setMinPower(); } else if (m_act_max_power->isChecked()) { m_power_scheme.setMaxPower(); } else { m_power_scheme.setBalanced(); } } void BatteryMeterGui::powerStatusChanged() { m_act_min_power->setChecked(m_power_scheme.isMinPower()); m_act_max_power->setChecked(m_power_scheme.isMaxPower()); m_act_balanced->setChecked(m_power_scheme.isBalanced()); m_dlg_settings->setMinPower(m_act_min_power->isChecked()); m_dlg_settings->setMaxPower(m_act_max_power->isChecked()); m_dlg_settings->setBalanced(m_act_balanced->isChecked()); } #endif void BatteryMeterGui::infoDlgVisibility() { if (!m_battery_meter.batteryPresent()) return; m_dlg_info->isVisible() ? m_dlg_info->hide() : m_dlg_info->show(); } void BatteryMeterGui::readConfiguration() { Settings *settings = Settings::instance(); // load application settings m_unprocessed_actions = settings->actions(); m_processed_actions.clear(); #ifdef USE_LOGGING m_logging = settings.logEnabled() && settings.log(); m_log_file = settings.logFile(); #endif setInterval(settings->updateInterval() * 1000); // TODO some time, maybe it will be ready //m_act_log->setVisible(m_logging); m_act_log->setVisible(false); // move passed events into processed list while (!m_unprocessed_actions.isEmpty() && (static_cast <unsigned long> (m_unprocessed_actions.last().level()) >= m_battery_meter.percentage())) { Action action = m_unprocessed_actions.last(); m_unprocessed_actions.pop_back(); m_processed_actions.push_front(action); } #ifdef USE_LOGGING if (m_logging) m_logger.start(); else m_logger.stop(); #endif } //------------------------------------------------------------------------------ #ifdef Q_OS_WIN32 MessageListener::MessageListener(QWidget *parent): QWidget(parent), m_listen(false) { } MessageListener::~MessageListener() { } void MessageListener::listen(bool l) { if (m_listen == l) return; m_listen = l; # if (WINVER > 0x0600) if (m_listen) { // register for the message m_power_source_notify = RegisterPowerSettingNotification( reinterpret_cast <void *> (winId()), &GUID_ACDC_POWER_SOURCE, DEVICE_NOTIFY_WINDOW_HANDLE); m_battery_perc_notify = RegisterPowerSettingNotification( reinterpret_cast <void *> (winId()), &GUID_BATTERY_PERCENTAGE_REMAINING, DEVICE_NOTIFY_WINDOW_HANDLE); m_power_scheme_notify = RegisterPowerSettingNotification( reinterpret_cast <void *> (winId()), &GUID_POWERSCHEME_PERSONALITY, DEVICE_NOTIFY_WINDOW_HANDLE); } else { UnregisterPowerSettingNotification(m_power_source_notify); UnregisterPowerSettingNotification(m_battery_perc_notify); UnregisterPowerSettingNotification(m_power_scheme_notify); } # endif } bool MessageListener::winEvent(MSG *msg, long *res) { if (!m_listen) return true; if (msg->message == WM_POWERBROADCAST) { # if (WINVER >= 0x0600) //windows vista, 7 if (msg->wParam == PBT_POWERSETTINGCHANGE) { POWERBROADCAST_SETTING *setting = reinterpret_cast <POWERBROADCAST_SETTING *> (msg->lParam); if (sizeof(int) == setting->DataLength && (setting->PowerSetting == GUID_ACDC_POWER_SOURCE || setting->PowerSetting == GUID_BATTERY_PERCENTAGE_REMAINING)) { // change from ac to battery or back // or battery cap. comes up and down emit powerStatusChanged(); } else if (sizeof(GUID) == setting->DataLength && setting->PowerSetting == GUID_POWERSCHEME_PERSONALITY) { emit powerSchemeChanged(); } } # else // windows 2000 pro - xp if (msg->wParam == PBT_APMPOWERSTATUSCHANGE) { // change from ac to batt or back emit powerStatusChanged(); } # endif // do not process this message by Qt return true; } return false; } #endif
标签: 管理
网友评论
小贴士
感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。
- 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
- 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
- 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
- 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
关于好例子网
本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明
支持(0) 盖楼(回复)