📄 qdbusconnection.cpp
字号:
{// Q_ASSERT_X(QCoreApplication::instance(), "QDBusConnection::addConnection",// "Cannot create connection without a Q[Core]Application instance"); QDBusConnectionPrivate *d = _q_manager()->connection(name); if (d || name.isEmpty()) return QDBusConnection(name); d = new QDBusConnectionPrivate; DBusConnection *c = 0; switch (type) { case SystemBus: c = dbus_bus_get_private(DBUS_BUS_SYSTEM, &d->error); break; case SessionBus: c = dbus_bus_get_private(DBUS_BUS_SESSION, &d->error); break; case ActivationBus: c = dbus_bus_get_private(DBUS_BUS_STARTER, &d->error); break; } d->setConnection(c); //setConnection does the error handling for us _q_manager()->setConnection(name, d); QDBusConnection retval(name); // create the bus service d->busService = new QDBusConnectionInterface(retval, d); d->ref.deref(); // busService has a increased the refcounting to us // avoid cyclic refcounting QObject::connect(d->busService, SIGNAL(serviceOwnerChanged(QString,QString,QString)), d, SIGNAL(serviceOwnerChanged(QString,QString,QString))); return retval;}/*! Opens a peer-to-peer connection on address \a address and associate with it the connection name \a name. Returns a QDBusConnection object associated with that connection.*/QDBusConnection QDBusConnection::connectToBus(const QString &address, const QString &name){// Q_ASSERT_X(QCoreApplication::instance(), "QDBusConnection::addConnection",// "Cannot create connection without a Q[Core]Application instance"); QDBusConnectionPrivate *d = _q_manager()->connection(name); if (d || name.isEmpty()) return QDBusConnection(name); d = new QDBusConnectionPrivate; // setConnection does the error handling for us d->setConnection(dbus_connection_open(address.toUtf8().constData(), &d->error)); _q_manager()->setConnection(name, d); QDBusConnection retval(name); // create the bus service // create the bus service d->busService = new QDBusConnectionInterface(retval, d); d->ref.deref(); // busService has a increased the refcounting to us // avoid cyclic refcounting QObject::connect(d->busService, SIGNAL(serviceOwnerChanged(QString,QString,QString)), d, SIGNAL(serviceOwnerChanged(QString,QString,QString))); return retval;}/*! Closes the connection of name \a name. Note that if there are still QDBusConnection objects associated with the same connection, the connection will not be closed until all references are dropped. However, no further references can be created using the QDBusConnection constructor.*/void QDBusConnection::disconnectFromBus(const QString &name){ if (_q_manager()) _q_manager()->removeConnection(name);}/*! Sends the \a message over this connection, without waiting for a reply. This is suitable for errors, signals, and return values as well as calls whose return values are not necessary. Returns true if the message was queued successfully, false otherwise.*/bool QDBusConnection::send(const QDBusMessage &message) const{ if (!d || !d->connection) { QDBusError err = QDBusError(QDBusError::Disconnected, QLatin1String("Not connected to D-BUS server")); if (d) d->lastError = err; return false; } return d->send(message) != 0;}/*! Sends the \a message over this connection and blocks, waiting for a reply, for at most \a timeout milliseconds. When the reply is received, the given \a method is called in the \a receiver object. The default \a timeout is -1, meaning that the function won't wait for a reply before calling the specified \a method. This function is suitable for method calls only. It is guaranteed that the slot will be called exactly once with the reply, as long as the parameter types match. If they don't, the reply cannot be delivered. Returns the identification of the message that was sent or 0 if nothing was sent.*/bool QDBusConnection::callWithCallback(const QDBusMessage &message, QObject *receiver, const char *method, int timeout) const{ if (!d || !d->connection) { QDBusError err = QDBusError(QDBusError::Disconnected, QLatin1String("Not connected to D-BUS server")); if (d) d->lastError = err; return 0; } return d->sendWithReplyAsync(message, receiver, method, timeout) != 0;}/*! Sends the \a message over this connection and blocks, waiting for a reply, for at most \a timeout milliseconds. This function is suitable for method calls only. It returns the reply message as its return value, which will be either of type QDBusMessage::ReplyMessage or QDBusMessage::ErrorMessage. See the QDBusInterface::call() function for a more friendly way of placing calls. \warning If \a mode is QDBus::BlockWithGui, this function will reenter the Qt event loop in order to wait for the reply. During the wait, it may deliver signals and other method calls to your application. Therefore, it must be prepared to handle a reentrancy whenever a call is placed with call().*/QDBusMessage QDBusConnection::call(const QDBusMessage &message, QDBus::CallMode mode, int timeout) const{ if (!d || !d->connection) { QDBusError err = QDBusError(QDBusError::Disconnected, QLatin1String("Not connected to D-BUS server")); if (d) d->lastError = err; return QDBusMessagePrivate::fromError(err); } if (mode != QDBus::NoBlock) return d->sendWithReply(message, mode, timeout); d->send(message); QDBusMessage retval; retval << QVariant(); // add one argument (to avoid .at(0) problems) return retval;}/*! Connects the signal specified by the \a service, \a path, \a interface and \a name parameters to the slot \a slot in object \a receiver. The arguments \a service and \a path can be empty, denoting a connection to any signal of the (\a interface, \a name) pair, from any remote application. Returns true if the connection was successful. \warning The signal will only be delivered to the slot if the parameters match. This verification can be done only when the signal is received, not at connection time.*/bool QDBusConnection::connect(const QString &service, const QString &path, const QString& interface, const QString &name, QObject *receiver, const char *slot){ return connect(service, path, interface, name, QString(), receiver, slot);}/*! Disconnects the signal specified by the \a service, \a path, \a interface and \a name parameters from the slot \a slot in object \a receiver. The arguments \a service and \a path can be empty, denoting a disconnection from all signals of the (\a interface, \a name) pair, from all remote applications. Returns true if the disconnection was successful.*/bool QDBusConnection::disconnect(const QString &service, const QString &path, const QString &interface, const QString &name, QObject *receiver, const char *slot){ return disconnect(service, path, interface, name, QString(), receiver, slot);}/*! \overload Connects the signal to the slot \a slot in object \a receiver. Unlike the other connect() overload, this function allows one to specify the parameter signature to be connected using the \a signature variable. The function will then verify that this signature can be delivered to the slot specified by \a slot and return false otherwise.*/bool QDBusConnection::connect(const QString &service, const QString &path, const QString& interface, const QString &name, const QString &signature, QObject *receiver, const char *slot){ if (!receiver || !slot || !d || !d->connection) return false; if (!interface.isEmpty() && !QDBusUtil::isValidInterfaceName(interface)) return false; if (interface.isEmpty() && name.isEmpty()) return false; // check the slot QDBusConnectionPrivate::SignalHook hook; QString key; QString name2 = name; if (name2.isNull()) name2.detach(); QString owner = d->getNameOwner(service); // we don't care if the owner is empty hook.signature = signature; // it might get started later if (!d->prepareHook(hook, key, service, owner, path, interface, name, receiver, slot, 0, false)) return false; // don't connect // avoid duplicating: QWriteLocker locker(&d->lock); QDBusConnectionPrivate::SignalHookHash::ConstIterator it = d->signalHooks.find(key); QDBusConnectionPrivate::SignalHookHash::ConstIterator end = d->signalHooks.constEnd(); for ( ; it != end && it.key() == key; ++it) { const QDBusConnectionPrivate::SignalHook &entry = it.value(); if (entry.service == hook.service && entry.owner == hook.owner && entry.path == hook.path && entry.signature == hook.signature && entry.obj == hook.obj && entry.midx == hook.midx) { // no need to compare the parameters if it's the same slot return true; // already there } } d->connectSignal(key, hook); return true;}/*! \overload Disconnects the signal from the slot \a slot in object \a receiver. Unlike the other disconnect() overload, this function allows one to specify the parameter signature to be disconnected using the \a signature variable. The function will then verify that this signature is connected to the slot specified by \a slot and return false otherwise.*/bool QDBusConnection::disconnect(const QString &service, const QString &path, const QString& interface, const QString &name, const QString &signature, QObject *receiver, const char *slot){ if (!receiver || !slot || !d || !d->connection) return false; if (!interface.isEmpty() && !QDBusUtil::isValidInterfaceName(interface)) return false; if (interface.isEmpty() && name.isEmpty()) return false; // check the slot QDBusConnectionPrivate::SignalHook hook; QString key; QString name2 = name; if (name2.isNull()) name2.detach(); QString owner = d->getNameOwner(service); // we don't care of owner is empty hook.signature = signature; if (!d->prepareHook(hook, key, service, owner, path, interface, name, receiver, slot, 0, false)) return false; // don't disconnect // avoid duplicating: QWriteLocker locker(&d->lock); QDBusConnectionPrivate::SignalHookHash::ConstIterator it = d->signalHooks.find(key); QDBusConnectionPrivate::SignalHookHash::ConstIterator end = d->signalHooks.constEnd(); for ( ; it != end && it.key() == key; ++it) { const QDBusConnectionPrivate::SignalHook &entry = it.value(); if (entry.service == hook.service && entry.owner == hook.owner && entry.path == hook.path && entry.signature == hook.signature && entry.obj == hook.obj && entry.midx == hook.midx) { // no need to compare the parameters if it's the same slot d->disconnectSignal(key, hook); return true; // it was there } } // the slot was not found
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -