Implementing a DBus interface exposing an object tree to clients
-
wrote on 15 Dec 2019, 17:32 last edited by
I want to implement a DBus API where the client is able to get a hierarchy of devices and their properties as follows:
Device 0 Some Category Property 1 Property 2 Device 1 Some Other Category Subcategory Property 1
is there a way to access the objects as a tree in the client without manually parsing the relationships from the object paths?
-
Hi,
I am not sure I am following you on this. How would you like to access the data of your data tree ?
-
wrote on 15 Dec 2019, 21:18 last edited by
I'd basically like to get the object located at /DBusInterface/devices and use its subtrees for presentation, something like:
Device d = getRootDeviceFromDbus(); constructItemModel(d); // Construct item model from root device recursively
-
So you are missing the construct model method ?
-
wrote on 17 Dec 2019, 17:43 last edited by
I'm trying to find out if there's a way to get the object tree without manually parsing all the object paths
-
If the structure is fixed. You can create a model on top of these objects.
-
wrote on 19 Dec 2019, 13:26 last edited by Lurkki
The structure isn't fixed, which is the entire reason for needing this
-
Ok, but what would you get from your DBus endpoint ?
-
wrote on 19 Dec 2019, 23:34 last edited by
Ended up writing the following code that parses a list of paths into a tree
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { auto central = new QWidget; auto lo = new QVBoxLayout; auto view = new QTreeView; auto model = new QStandardItemModel; auto root = model->invisibleRootItem(); QStringList pathList; pathList << "/dev" << "/dev/gpu" << "/dev/gpu2" << "/dev/gpu/fans/0" << "/dev/gpu2/powerlim"; struct Node { QString name; QVector <Node*> children; }; auto lowestAncestor = [=](QStringList tokens, Node *root, int *tokenIndex) { int i = 0; bool flag = false; Node *node_it = root; while (node_it && i < tokens.length()) { for (auto node : node_it->children) { if (node->name.compare(tokens[i]) == 0) { i++; flag = true; node_it = node; break; } } if (!flag) { break; } flag = false; } *tokenIndex = i; return node_it; }; std::function<void (QString, QStringList, Node*)> addNode; addNode = [=, &addNode](QString path, QStringList tokens, Node *node) { // Call this function until lowestAncestor.name == tokens.last() int i; auto n = lowestAncestor(tokens, node, &i); if (tokens.last().compare(n->name) != 0) { auto new_ = new Node; new_->name = tokens[i]; n->children.append(new_); addNode(path, tokens, node); } }; Node *rootNode = new Node; for (auto &path : pathList) { addNode(path, path.split(QRegExp("/+"), QString::SkipEmptyParts), rootNode); } std::function <void(QStandardItem*, Node*)> traverse; traverse = [=, &traverse](QStandardItem *item, Node *node) { auto newItem = new QStandardItem; newItem->setData(node->name, Qt::DisplayRole); item->appendRow(newItem); for (auto node : node->children) { traverse(newItem, node); } }; for (auto n : rootNode->children) { traverse(root, n); } view->setModel(model); lo->addWidget(view); central->setLayout(lo); setCentralWidget(central); }
1/9