Publish and Subscribe ExampleFiles:
The Publish and Subscribe example shows how to use the Qt Publish and Subscribe API to publish and retrieve values from the platforms Publish and Subscribe system. This example program can act as either a publisher of Value Space content, a subscriber of Value Space content or both. It can also optionally act as the Value Space Manager. The behavior is selected by passing a combination of three optional command line parameters when starting the program. If no parameters are supplied the program defaults to acting as both a publisher and a subscriber.
PublisherWhen acting as a publisher of Value Space content the program creates a PublisherDialog. This dialog contains a widget for setting the base path of the QValueSpacePublisher and widgets for setting the value of the three fixed attributes 'intValue', 'stringValue' and 'byteArrayValue'. We declare the slots which we will use to respond to user input in the dialog. private slots: void createNewObject(); void intValueChanged(int value); void unsetIntValue(); void setStringValue(); void setByteArrayValue(); And connect them to signals from the widgets in the constructor. connect(ui->connectButton, SIGNAL(clicked()), this, SLOT(createNewObject())); connect(ui->intValue, SIGNAL(valueChanged(int)), this, SLOT(intValueChanged(int))); connect(ui->unsetIntButton, SIGNAL(clicked()), this, SLOT(unsetIntValue())); connect(ui->setStringButton, SIGNAL(clicked()), this, SLOT(setStringValue())); connect(ui->setByteArrayButton, SIGNAL(clicked()), this, SLOT(setByteArrayValue())); To publish values in the Value Space we first need to create a QValueSpacePublisher. This is done in the createNewObject() slot, which is also used to handle changes in the base path. After the object is constructed we publish the initial values by explicitly calling the other slots. void PublisherDialog::createNewObject() { if (publisher) delete publisher; publisher = new QValueSpacePublisher(QValueSpace::WritableLayer, ui->basePath->text()); if (publisher->isConnected()) { ui->setters->setEnabled(true); intValueChanged(ui->intValue->value()); setStringValue(); setByteArrayValue(); } else { ui->setters->setEnabled(false); } } We use QValueSpacePublisher::setValue() to set the values in response to dialog input. void PublisherDialog::intValueChanged(int value) { publisher->setValue("intValue", value); } void PublisherDialog::unsetIntValue() { publisher->resetValue("intValue"); } void PublisherDialog::setStringValue() { publisher->setValue("stringValue", ui->stringValue->text()); } void PublisherDialog::setByteArrayValue() { publisher->setValue("byteArrayValue", ui->byteArrayValue->text().toAscii()); } As a final step in the constructor we explicitly call the createNewObject() slot to create an initial QValueSpacePublisher. createNewObject(); SubscriberWhen acting as a subscriber of Value Space content the program creates a SubscriberDialog. This dialog contains a widget for setting the base path of the QValueSpaceSubscriber and a table for displaying all of the values directly under base path in the Value Space. We declare two slots to propagate values from the Value Space to the dialog in response to change notifications from QValueSpaceSubscriber. private slots: void changeSubscriberPath(); void subscriberChanged(); To read values from the Value Space we first create a QValueSpaceSubscriber and connect to the contentsChanged() signal. We explicitly call our subscriberChanged() slot to populate the table with the initial values. void SubscriberDialog::changeSubscriberPath() { if (listWidget) listWidget->clear(); else if (tableWidget) tableWidget->clearContents(); if (!subscriber) subscriber = new QValueSpaceSubscriber(ui->basePath->text(), this); else subscriber->setPath(ui->basePath->text()); connect(subscriber, SIGNAL(contentsChanged()), this, SLOT(subscriberChanged())); subscriberChanged(); } In response to the contentsChanged() signal we update all the values in the table. void SubscriberDialog::subscriberChanged() { QStringList subPaths = subscriber->subPaths(); if (listWidget) { listWidget->clear(); } else if (tableWidget) { tableWidget->clearContents(); tableWidget->setRowCount(subPaths.count()); } for (int i = 0; i < subPaths.count(); ++i) { QVariant v = subscriber->value(subPaths.at(i)); if (listWidget) { const QString itemTemplate("%1 (%2)\n%3"); QListWidgetItem *item = new QListWidgetItem(itemTemplate.arg(subPaths.at(i), v.typeName(), v.toString())); item->setFlags(item->flags() & ~Qt::ItemIsEditable); listWidget->addItem(item); } else if (tableWidget) { QTableWidgetItem *pathItem = new QTableWidgetItem(subPaths.at(i)); pathItem->setFlags(pathItem->flags() & ~Qt::ItemIsEditable); QTableWidgetItem *valueItem = new QTableWidgetItem(v.toString()); valueItem->setFlags(valueItem->flags() & ~Qt::ItemIsEditable); QTableWidgetItem *typeItem = new QTableWidgetItem(v.typeName()); typeItem->setFlags(typeItem->flags() & ~Qt::ItemIsEditable); tableWidget->setItem(i, 0, pathItem); tableWidget->setItem(i, 1, valueItem); tableWidget->setItem(i, 2, typeItem); } } } X
|