Drawable = new BitmapDrawable( Bitmap )
参考自:
http://laurii.info/articles/2007/03/22/dbus-and-qt-programmin
http://blog.chinaunix.net/u2/69889/showart_2316513.html
根据第二个BLOG,我改动了部分代码,使用dbus interface调用方式,一步一步建立C/S结构代码:
[socol@localhost testdbus]$ ll
client
hotelibs
service
1. 建立库函数hotelibs
[socol@localhost testdbus]$ cd hotelibs
[socol@localhost hotelibs]$ ll
hotel.pro
hotel.cpp
hotel.h
[socol@localhost hotelibs]$cat hotel.h
#ifndef HOTEL_H #define HOTEL_H #include <QObject> #include <QReadWriteLock> #define MAX_ROOMS 10 class Hotel : public QObject { Q_OBJECT // 定义Interface名称为"com.test.hotel.registry" Q_CLASSINFO("D-Bus Interface", "com.test.hotel.registry") public: Hotel() { m_rooms = MAX_ROOMS; } public slots: // Check in,参数为房间数,返回成功拿到的房间数 int checkIn(int num_room); // Check out,参数为房间数,返回成功退回的房间数 int checkOut(int num_room); // Query,用于查询目前还剩下的房间数 int query(); private: int m_rooms; QReadWriteLock m_lock; }; #endif // HOTEL_H
[socol@localhost hotelibs]$cat hotel.cpp
#include <QtCore> #include <QtDBus> #include <QReadLocker> #include <QWriteLocker> #include "hotel.h" int Hotel::checkIn(int num_room) { QWriteLocker locker(&m_lock); if (m_rooms >= num_room) { m_rooms -= num_room; } else { num_room = m_rooms; m_rooms = 0; } return num_room; } int Hotel::checkOut(int num_room) { QWriteLocker locker(&m_lock); m_rooms += num_room; if (m_rooms > MAX_ROOMS) { num_room -= (m_rooms - MAX_ROOMS); m_rooms = MAX_ROOMS; } return num_room; } int Hotel::query() { QReadLocker locker(&m_lock); return m_rooms; }
[socol@localhost hotelibs]$ qdbuscpp2xml -A hotel.h -o com.test.hotel.xml
[socol@localhost hotelibs]$ qdbusxml2cpp com.test.hotel.xml -i hotel.h -p hotelInterface
[socol@localhost hotelibs]$ll
com.test.hotel.xml
hotel.cpp
hotel.h
hotelibs.pro
hotelInterface.cpp
hotelInterface.h
[socol@localhost hotelibs]$cat com.test.hotel.xml
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> <node> <interface name="com.test.hotel.registry"> <signal name="roomChanged"> <arg name="num_room" type="i" direction="out"/> </signal> <method name="checkIn"> <arg type="i" direction="out"/> <arg name="num_room" type="i" direction="in"/> </method> <method name="checkOut"> <arg type="i" direction="out"/> <arg name="num_room" type="i" direction="in"/> </method> <method name="query"> <arg type="i" direction="out"/> </method> </interface> </node>
[socol@localhost hotelibs]$cat hotelibs.pro
QT += dbus QT -= gui TARGET = hotelibs CONFIG += console CONFIG -= app_bundle TEMPLATE = lib SOURCES += hotelInterface.cpp hotel.cpp HEADERS += hotelInterface.h hotel.h
[socol@localhost hotelibs]$qmake-qt4 & make
[socol@localhost hotelibs]$sudo cp libhotelibs.so* /usr/lib
2. 建立服务端service
[socol@localhost testdbus]$ cd service
[socol@localhost service]$ ll
hotelservice.pro
main.cpp
[socol@localhost service]$cat hotelservice.pro
QT += dbus QT -= gui TARGET = hotelservice CONFIG += console CONFIG -= app_bundle TEMPLATE = app SOURCES += main.cpp LIBS += -L../hotelibs -lhotelibs INCLUDEPATH += ../hotelibs
[socol@localhost service]$cat main.cpp
#include <QtCore> #include <QtDBus> #include <QReadLocker> #include <QWriteLocker> #include "hotel.h" int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); // 用于建立到session bus的连接 QDBusConnection bus = QDBusConnection::sessionBus(); // 在session bus上注册名为"com.test.hotel"的service if (!bus.registerService("com.test.hotel")) { qDebug() << bus.lastError().message(); exit(1); } Hotel my_hotel; #if 0 // adaport 方式,需要在hotelibs目录中运行: // qdbusxml2cpp com.test.hotel.xml -i hotel.h -a hotelAdaport new RegistryAdaptor(my_hotel); #else // 注册名为"/hotel/registry"的object。 // "QDBusConnection::ExportAllSlots "表示把类Hotel的所有Slot都导出为这个Object的method // 如果需要使用signal的话可以使用 QDBusConnection::ExportAllSignals bus.registerObject("/hotel/registry", &my_hotel, QDBusConnection::ExportAllSlots); #endif return a.exec(); }
[socol@localhost service]$qmake-qt4 & make
[socol@localhost service]$sudo cp hotelservice /usr/libexec/
[socol@localhost service]$sudo vim /usr/share/dbus-1/services/com.test.hotel.service
[socol@localhost service]$cat /usr/share/dbus-1/services/com.test.hotel.service
[D-BUS Service]
Name=com.test.hotel
Exec=/usr/libexec/hotelservice
3. 建立客户端client
[socol@localhost testdbus]$ cd client
[socol@localhost client]$ ll
main.cpp
hotelclient.pro
[socol@localhost client]$cat main.cpp
#include <QtCore> #include <QtDBus> #include <hotel.h> #include <hotelInterface.h> int main(int argc, char *argv[]) { int num_room; if (argc > 2) { fprintf(stderr, "Usage: %s [num_room]\n", argv[0]); exit(1); } if (argc == 2) { num_room = QString(argv[1]).toInt(); } else { num_room = 1; } // 初始化自动生成的Proxy类com::test::hotel::registry com::test::hotel::registry myHotel("com.test.hotel", "/hotel/registry", QDBusConnection::sessionBus()); // 调用checkIn QDBusPendingReply<int> reply = myHotel.checkIn(num_room); // qdbusxml2cpp生成的Proxy类是采用异步的方式来传递Message, // 所以在此需要调用waitForFinished来等到Message执行完成 reply.waitForFinished(); if (reply.isValid()) { num_room = reply.value(); printf("Got %d %s\n", num_room, (num_room > 1) ? "rooms" : "room"); } else { fprintf(stderr, "Check In fail!\n"); } return 0; }
[socol@localhost client]$cat hotelclient.pro
QT += dbus QT -= gui TARGET = hotelclient CONFIG += console CONFIG -= app_bundle TEMPLATE = app LIBS += -L../hotelibs -lhotelibs INCLUDEPATH += ../hotelibs SOURCES += main.cpp
4.测试
[socol@localhost client]$d-feet
// select query() execut, result 10
[socol@localhost client]$./hotelclient
Got 1 room
[socol@localhost client]$d-feet
// select query() execut, result 9
managedQuery() will use ContentResolver's query(). The difference is that with managedQuery() the activity will keep a reference to your Cursor and close it whenever needed (in onDestroy() for instance.) If you do query() yourself, you will have to manage the Cursor as a sensitive resource. If you forget, for instance, to close() it in onDestroy(), you will leak underlying resources (logcat will warn you about it.)
To query a content provider, you can use either the ContentResolver.query() method or the Activity.managedQuery() method. Both methods take the same set of arguments, and both return a Cursor object. However, managedQuery() causes the activity to manage the life cycle of the Cursor. A managed Cursor handles all of the niceties, such as unloading itself when the activity pauses, and requerying itself when the activity restarts. You can ask an Activity to begin managing an unmanaged Cursor object for you by calling Activity.startManagingCursor().