通过DBus使用Qt设置系统时间
我尝试通过以下方式使用Qt设置系统时间:通过DBus使用Qt设置系统时间,qt,dbus,freedesktop.org,Qt,Dbus,Freedesktop.org,我尝试通过以下方式使用Qt设置系统时间: #include <QDBusConnection> #include <QDBusInterface> #include <QDBusMessage> #include <QDebug> #include <QDateTime> #include <cstdlib> int main (int /*argc*/, char ** /*argv*/) { QDBusConn
#include <QDBusConnection>
#include <QDBusInterface>
#include <QDBusMessage>
#include <QDebug>
#include <QDateTime>
#include <cstdlib>
int main (int /*argc*/, char ** /*argv*/)
{
QDBusConnection dbConnection = QDBusConnection::systemBus ();
QDBusInterface dbInterface (
"org.freedesktop.timedate1.set-time"
, "/org/freedesktop/timedate1/set-time/Manager"
, "org.freedesktop.timedate1.set-time.Manager"
, dbConnection);
qDebug () << "DBus interface validation: " << dbInterface.isValid ();
if (dbInterface.isValid () ) {
QDBusMessage dbMessage = dbInterface.call ("SetTime", QDateTime::currentDateTime ().toMSecsSinceEpoch () * 1000, false, false);
qDebug () << "DBus message: " << dbMessage;
}
return EXIT_SUCCESS;
}
我得到了一些相关的输出(因此看起来环境没有问题):
源代码和构建脚本位于。简言之:
QDBusInterface
创建上的重试循环完成任务
我探索了更多。该dbus对象由systemd timedated
服务提供。要了解其状态:
sudo systemctl status systemd-timedated
服务的配置位于/lib/systemd/system/systemd timedated中。服务:
[Unit]
Description=Time & Date Service
Documentation=man:systemd-timedated.service(8) man:localtime(5)
Documentation=http://www.freedesktop.org/wiki/Software/systemd/timedated
[Service]
ExecStart=/lib/systemd/systemd-timedated
BusName=org.freedesktop.timedate1
CapabilityBoundingSet=CAP_SYS_TIME
WatchdogSec=1min
PrivateTmp=yes
ProtectSystem=yes
ProtectHome=yes
BusName
设置负责所谓的“服务的D总线激活”。因此,当有人试图访问名称org.freedesktop.timedate1
时,服务就会启动
但显然,这需要时间来开始。我不知道应该如何干净地完成,但您可以创建一个重试循环来创建QDBusInterface
。您将看到sudo systemctl status systemd timedated
变为活动状态,并且Qt检索一个有效的接口
我尝试过的对象名称和路径:
QDBusInterface dbInterface (
"org.freedesktop.timedate1"
, "/org/freedesktop/timedate1"
, "org.freedesktop.timedate1"
, dbConnection);
简而言之:QDBusInterface
创建上的重试循环完成了任务
我探索了更多。该dbus对象由systemd timedated
服务提供。要了解其状态:
sudo systemctl status systemd-timedated
服务的配置位于/lib/systemd/system/systemd timedated中。服务:
[Unit]
Description=Time & Date Service
Documentation=man:systemd-timedated.service(8) man:localtime(5)
Documentation=http://www.freedesktop.org/wiki/Software/systemd/timedated
[Service]
ExecStart=/lib/systemd/systemd-timedated
BusName=org.freedesktop.timedate1
CapabilityBoundingSet=CAP_SYS_TIME
WatchdogSec=1min
PrivateTmp=yes
ProtectSystem=yes
ProtectHome=yes
BusName
设置负责所谓的“服务的D总线激活”。因此,当有人试图访问名称org.freedesktop.timedate1
时,服务就会启动
但显然,这需要时间来开始。我不知道应该如何干净地完成,但您可以创建一个重试循环来创建QDBusInterface
。您将看到sudo systemctl status systemd timedated
变为活动状态,并且Qt检索一个有效的接口
我尝试过的对象名称和路径:
QDBusInterface dbInterface (
"org.freedesktop.timedate1"
, "/org/freedesktop/timedate1"
, "org.freedesktop.timedate1"
, dbConnection);
有几个问题
使用了错误的D-Bus命令。在尝试编写Qt程序之前,我必须使用控制台调试该命令。所以正确的命令是:
dbus-send \
--system \
--print-reply \
--type=method_call \
--dest='org.freedesktop.timedate1' \
'/org/freedesktop/timedate1' \
org.freedesktop.timedate1.SetTime \
int64:120000000 \
boolean:true \
boolean:false
使用ntp服务时,将执行命令,错误为:自动时间同步已启用
。因此(根据建议)必须禁用同步:
timedatectl set-ntp 0
如@Velcan所述,日期为时间的服务处于非活动状态:
当有人试图访问该名称时,服务将启动
org.freedesktop.timedate1
在我的环境(KUbuntu 15.10 x86_64
)中,服务在上次呼叫30秒后处于活动状态
根据报告:
bool QDBusAbstractInterface::isValid()const
如果这是一个错误,则返回true
对远程对象的有效引用。如果存在错误,则返回false
创建此接口时出错(例如,如果
远程应用程序不存在)
注意:在处理远程对象时,并不总是能够
在创建QDBusInterface时确定它是否存在
即使QDBusAbstractInterface::isValid()
返回false
调用函数也会成功执行
最后,正确的代码非常简短:
QDBusInterface dbInterface (
"org.freedesktop.timedate1"
, "/org/freedesktop/timedate1"
, "org.freedesktop.timedate1"
, QDBusConnection::systemBus () );
qDebug () << dbInterface.call ("SetTime", 120000000ll, true, false);
qdbus接口dbInterface(
“org.freedesktop.timedate1”
,“/org/freedesktop/timedate1”
,“org.freedesktop.timedate1”
,QDBusConnection::systemBus());
qDebug()有几个问题
使用了错误的D-Bus命令。在尝试编写Qt程序之前,我必须使用控制台调试该命令。所以正确的命令是:
dbus-send \
--system \
--print-reply \
--type=method_call \
--dest='org.freedesktop.timedate1' \
'/org/freedesktop/timedate1' \
org.freedesktop.timedate1.SetTime \
int64:120000000 \
boolean:true \
boolean:false
使用ntp服务时,将执行命令,错误为:自动时间同步已启用
。因此(根据建议)必须禁用同步:
timedatectl set-ntp 0
如@Velcan所述,日期为时间的服务处于非活动状态:
当有人试图访问该名称时,服务将启动
org.freedesktop.timedate1
在我的环境(KUbuntu 15.10 x86_64
)中,服务在上次呼叫30秒后处于活动状态
根据报告:
bool QDBusAbstractInterface::isValid()const
如果这是一个错误,则返回true
对远程对象的有效引用。如果存在错误,则返回false
创建此接口时出错(例如,如果
远程应用程序不存在)
注意:在处理远程对象时,并不总是能够
在创建QDBusInterface时确定它是否存在
即使QDBusAbstractInterface::isValid()
返回false
调用函数也会成功执行
最后,正确的代码非常简短:
QDBusInterface dbInterface (
"org.freedesktop.timedate1"
, "/org/freedesktop/timedate1"
, "org.freedesktop.timedate1"
, QDBusConnection::systemBus () );
qDebug () << dbInterface.call ("SetTime", 120000000ll, true, false);
qdbus接口dbInterface(
“org.freedesktop.timedate1”
,“/org/freedesktop/timedate1”
,“org.freedesktop.timedate1”
,QDBusConnection::systemBus());
qDebug()看起来需要实例化对象。当我用d型脚看时,它不在那里。然后我从终端启动$gdbus introspect--system--dest org.freedesktop.timedate1--object path/org/freedesktop/timedate1
,timedate1出现(然后Qt应用程序将其报告为有效)。@Velkan,看起来该对象需要实例化。
我不熟悉D-Bus。你能解释一下我应该做什么吗?看起来这个对象需要实例化。当我用d型脚看时,它不在那里。然后我从终端启动$gdbus introspect--system--dest org.freedesktop.timedate1--object path/org/freedesktop/timedate1
,timedate1出现(然后Qt应用程序将其报告为有效)。@Velkan,看起来该对象需要实例化。
我不熟悉D-Bus。你能解释一下我该做什么吗?谢谢你的回答