Qtの基礎 - シャットダウン
ナビゲーションに移動
検索に移動
概要
Qtライブラリを使用して、ソフトウェアからOSのシャットダウンや再起動等を行う方法を記載する。
シャットダウン
- shutdownコマンドを実行する場合
#include <QProcess>
#include <QInputDialog>
void Converter::shutdown()
{
// GNOME Power Managementコマンドを試行
if (QProcess::startDetached("gnome-power-cmd.sh shutdown") || QProcess::startDetached("gnome-power-cmd shutdown")) {
qInfo() << "Shutdown initiated via GNOME Power Management command.";
return;
}
// sudo shutdownを試行
qWarning() << "Attempting to shutdown using sudo. This requires root privileges.";
// パスワード入力ダイアログを表示
bool ok;
QString password = QInputDialog::getText(this, "Sudo Password", "Enter your sudo password to proceed with shutdown:",
QLineEdit::Password, QString(), &ok);
if (!ok || password.isEmpty()) {
qWarning() << "Shutdown cancelled: No password provided.";
qCritical() << "All shutdown methods failed.";
return;
}
// sudoコマンドを実行
QProcess process;
process.start("sudo", QStringList() << "-S" << "shutdown" << "-P" << "now");
if (!process.waitForStarted()) {
qCritical() << "Failed to start sudo process:" << process.errorString();
qCritical() << "All shutdown methods failed.";
return;
}
// パスワードを入力
process.write(password.toUtf8() + "\n");
// プロセスの終了を待つ
if (!process.waitForFinished()) {
qCritical() << "Shutdown process did not finish:" << process.errorString();
qCritical() << "All shutdown methods failed.";
return;
}
// 終了コードを確認
if (process.exitCode() != 0) {
qCritical() << "Shutdown failed. Exit code:" << process.exitCode();
qCritical() << "Error output:" << process.readAllStandardError();
qCritical() << "All shutdown methods failed.";
return;
}
qInfo() << "Shutdown initiated via sudo command.";
}
- D-Busを使用する場合
#include <QDBus>
#include <QDebug>
void Converter::shutdown()
{
// GNOMEセッションマネージャを試行
QDBusInterface gnomeSessionManager("org.gnome.SessionManager",
"/org/gnome/SessionManager",
"org.gnome.SessionManager",
QDBusConnection::sessionBus());
if (gnomeSessionManager.isValid()) {
QDBusReply<void> reply = gnomeSessionManager.call("RequestShutdown");
if (reply.isValid()) {
qInfo() << "Shutdown initiated via GNOME Session Manager.";
return;
}
qWarning() << "GNOME Session Manager shutdown failed:" << reply.error().message();
}
// KDEセッションマネージャを試行
QDBusInterface kdeSessionManager("org.kde.ksmserver",
"/KSMServer",
"org.kde.KSMServerInterface",
QDBusConnection::sessionBus());
if (kdeSessionManager.isValid()) {
QDBusReply<void> reply = kdeSessionManager.call("logout", 0, 2, 2);
if (reply.isValid()) {
qInfo() << "Shutdown initiated via KDE Session Manager.";
return;
}
qWarning() << "KDE Session Manager shutdown failed:" << reply.error().message();
}
// HAL (Hardware Abstraction Layer) を試行
QDBusInterface halPower("org.freedesktop.Hal",
"/org/freedesktop/Hal/devices/computer",
"org.freedesktop.Hal.Device.SystemPowerManagement",
QDBusConnection::systemBus());
if (halPower.isValid()) {
QDBusReply<void> reply = halPower.call("Shutdown");
if (reply.isValid()) {
qInfo() << "Shutdown initiated via HAL.";
return;
}
qWarning() << "HAL shutdown failed:" << reply.error().message();
}
// ConsoleKitを試行
QDBusInterface consoleKit("org.freedesktop.ConsoleKit",
"/org/freedesktop/ConsoleKit/Manager",
"org.freedesktop.ConsoleKit.Manager",
QDBusConnection::systemBus());
if (consoleKit.isValid()) {
QDBusReply<void> reply = consoleKit.call("Stop");
if (reply.isValid()) {
qInfo() << "Shutdown initiated via ConsoleKit.";
return;
}
qWarning() << "ConsoleKit shutdown failed:" << reply.error().message();
}
qCritical() << "All shutdown methods failed.";
}
再起動
void Converter::reboot()
{
bool reboot_works = false;
bool gnome_power1 = false;
bool gnome_power2 = false;
bool hal_works = false;
QDBusMessage response;
// GNOME
QDBusInterface gnomeSessionManager("org.gnome.SessionManager", "/org/gnome/SessionManager", "org.gnome.SessionManager", QDBusConnection::sessionBus());
response = gnomeSessionManager.call("RequestReboot");
if(response.type() == QDBusMessage::ErrorMessage)
{
if(verbose)
{
qWarning() << "W: " << response.errorName() << ":" << response.errorMessage();
}
gnome_power1 = QProcess::startDetached("gnome-power-cmd.sh reboot");
gnome_power2 = QProcess::startDetached("gnome-power-cmd reboot");
if(verbose && !gnome_power1 && !gnome_power2)
{
qWarning() << "W: gnome-power-cmd and gnome-power-cmd.sh didn't work";
}
}
else
{
reboot_works = true;
}
// KDE
QDBusInterface kdeSessionManager("org.kde.ksmserver", "/KSMServer", "org.kde.KSMServerInterface", QDBusConnection::sessionBus());
response = kdeSessionManager.call("logout", 0, 2, 1);
if(response.type() == QDBusMessage::ErrorMessage)
{
if(verbose)
{
qWarning() << "W: " << response.errorName() << ":" << response.errorMessage();
}
}
else
{
reboot_works = true;
}
if(!reboot_works && !gnome_power1 && !gnome_power2)
{
QDBusInterface powermanagement("org.freedesktop.Hal", "/org/freedesktop/Hal/devices/computer", "org.freedesktop.Hal.Device.SystemPowerManagement",
QDBusConnection::systemBus());
response = powermanagement.call("Reboot");
if(response.type() == QDBusMessage::ErrorMessage)
{
if(verbose)
{
qWarning() << "W: " << response.errorName() << ":" << response.errorMessage();
}
}
else
{
hal_works = true;
}
}
if(!hal_works && !reboot_works && !gnome_power1 && !gnome_power2)
{
QDBusInterface powermanagement("org.freedesktop.ConsoleKit", "/org/freedesktop/ConsoleKit/Manager", "org.freedesktop.ConsoleKit.Manager",
QDBusConnection::systemBus());
response = powermanagement.call("Restart");
if(response.type() == QDBusMessage::ErrorMessage)
{
if(verbose)
{
qWarning() << "W: " << response.errorName() << ":" << response.errorMessage();
}
QProcess::startDetached("sudo shutdown -r now");
}
}
}
スリープ
- プロセスを直接起動する場合
#include <QProcess>
#include <QDebug>
void Converter::suspend()
{
auto trySuspendCommand = [this](const QString &command, const QStringList &arguments, bool useAuth = false) {
QProcess process;
if (useAuth) {
bool ok;
QString password = QInputDialog::getText(this, "rootパスワード",
"サスペンドを実行するためのsudoパスワードを入力:",
QLineEdit::Password, QString(), &ok);
if (!ok || password.isEmpty()) {
qWarning() << "サスペンドがキャンセルされました: パスワードが提供されていません";
return false;
}
process.start("sudo", QStringList() << "-S" << command << arguments);
if (!process.waitForStarted()) {
qCritical() << "sudoプロセスの開始に失敗: " << process.errorString();
return false;
}
process.write(password.toUtf8() + "\n");
}
else {
process.start(command, arguments);
}
// 5秒待機
if (!process.waitForFinished(5000)) {
qWarning() << "サスペンドプロセスが完了しませんでした: " << process.errorString();
return false;
}
if (process.exitCode() != 0) {
qWarning() << "サスペンドに失敗しました。終了コード: " << process.exitCode();
qWarning() << "エラー出力: " << process.readAllStandardError();
return false;
}
return true;
};
// Systemctlを使用してサスペンドを試行
if (trySuspendCommand("systemctl", QStringList() << "suspend")) {
qInfo() << "Systemctl経由でサスペンド";
return;
}
qWarning() << "Systemctl経由でのサスペンドに失敗";
// pm-suspendを使用してサスペンドを試行 (古いLinuxシステム向け)
if (trySuspendCommand("pm-suspend", QStringList())) {
qInfo() << "pm-suspend経由でサスペンド";
return;
}
qWarning() << "pm-suspend経由でのサスペンドに失敗";
}
- D-Busを使用する場合
#include <QDBus>
#include <QDebug>
void Converter::suspend()
{
auto tryDBusCall = [](const QString &service, const QString &path, const QString &interface, const QString &method) {
QDBusInterface dbusInterface(service, path, interface, QDBusConnection::systemBus());
QDBusReply<void> reply = dbusInterface.call(method);
return reply.isValid();
};
// Systemdを試行
if (tryDBusCall("org.freedesktop.login1",
"/org/freedesktop/login1",
"org.freedesktop.login1.Manager",
"Suspend")) {
qInfo() << "システムはsystemd経由でサスペンドされました";
return;
}
qWarning() << "Systemd経由でのサスペンドに失敗";
// Systemdが失敗した場合、GNOMEのセッションマネージャを試行
if (tryDBusCall("org.gnome.SessionManager",
"/org/gnome/SessionManager",
"org.gnome.SessionManager",
"Suspend")) {
qInfo() << "GNOMEセッションマネージャ経由でサスペンド";
return;
}
qWarning() << "GNOMEセッションマネージャ経由でのサスペンドに失敗";
// UPowerインターフェースを試行
if (tryDBusCall("org.freedesktop.UPower",
"/org/freedesktop/UPower",
"org.freedesktop.UPower",
"Suspend")) {
qInfo() << "UPower経由でサスペンド";
return;
}
qWarning() << "UPower経由でのサスペンドに失敗";
}
ハイバネート
- GNOME Power Managementコマンドを実行する場合
#include <QProcess>
void Converter::hibernate()
{
// GNOME Power Management コマンドを試行
if (QProcess::startDetached("gnome-power-cmd.sh hibernate") ||
QProcess::startDetached("gnome-power-cmd hibernate")) {
qInfo() << "Hibernation initiated via GNOME Power Management.";
return;
}
qWarning() << "GNOME Power Management commands failed. Trying DBus methods.";
}
- D-Busを使用する場合
#include <QDBusInterface>
#include <QDBusReply>
#include <QDebug>
void Converter::hibernate()
{
// HAL (Hardware Abstraction Layer) を試行
QDBusInterface halPower("org.freedesktop.Hal",
"/org/freedesktop/Hal/devices/computer",
"org.freedesktop.Hal.Device.SystemPowerManagement",
QDBusConnection::systemBus());
if (halPower.isValid()) {
QDBusReply<void> reply = halPower.call("Hibernate");
if (reply.isValid()) {
qInfo() << "Hibernation initiated via HAL.";
return;
}
qWarning() << "HAL hibernation failed:" << reply.error().message();
}
else {
qWarning() << "Failed to connect to HAL power management.";
}
// DeviceKit Powerを試行
QDBusInterface dkPower("org.freedesktop.DeviceKit.Power",
"/org/freedesktop/DeviceKit/Power",
"org.freedesktop.DeviceKit.Power",
QDBusConnection::systemBus());
if (dkPower.isValid()) {
QDBusReply<void> reply = dkPower.call("Hibernate");
if (reply.isValid()) {
qInfo() << "Hibernation initiated via DeviceKit Power.";
return;
}
qWarning() << "DeviceKit Power hibernation failed:" << reply.error().message();
}
else {
qWarning() << "Failed to connect to DeviceKit Power.";
}
qCritical() << "All hibernation methods failed.";
}
画面のロック
QDBusモジュールを使用して、GNOMEスクリーンセーバーのD-Busインターフェースに接続して、Lockメソッドを呼び出してスクリーンをロックしている。
#include <QDBus>
#include <QMessageBox>
void Converter::lock()
{
QDBusInterface screensaver("org.gnome.ScreenSaver", "/org/gnome/ScreenSaver", "org.gnome.ScreenSaver");
if (!screensaver.isValid()) {
QMessageBox::warning(this, "Error", "Unable to connect to GNOME ScreenSaver.", QMessageBox::Ok);
return;
}
QDBusReply<void> reply = screensaver.call("Lock");
if (!reply.isValid()) {
QMessageBox::warning(this, "Error", "Unable to lock computer: " + reply.error().message(), QMessageBox::Ok);
}
}