void runExample(std::ostream& out) { static const AmsNetId remoteNetId { 192, 168, 0, 231, 1, 1 }; static const char remoteIpV4[] = "ads-server"; // uncomment and adjust if automatic AmsNetId deduction is not working as expected //AdsSetLocalAddress({192, 168, 0, 1, 1, 1}); // add local route to your EtherCAT Master if (AdsAddRoute(remoteNetId, remoteIpV4)) { out << "Adding ADS route failed, did you specify valid addresses?\n"; return; } // open a new ADS port const long port = AdsPortOpenEx(); if (!port) { out << "Open ADS port failed\n"; return; } const AmsAddr remote { remoteNetId, AMSPORT_R0_PLC_TC3 }; notificationExample(out, port, remote); notificationByNameExample(out, port, remote); readExample(out, port, remote); readByNameExample(out, port, remote); readStateExample(out, port, remote); const long closeStatus = AdsPortCloseEx(port); if (closeStatus) { out << "Close ADS port failed with: " << std::dec << closeStatus << '\n'; } #ifdef _WIN32 // WORKAROUND: On Win7 std::thread::join() called in destructors // of static objects might wait forever... AdsDelRoute(remoteNetId); #endif }
MainWindow::MainWindow() { tree_view=new VarTreeView(); //construct the GUI widget: tmodel=new VarTreeModel(); //construct the GUI widget's datamodel: tree_view->setModel(tmodel); //link the two together //===================================================== //=======BEGIN OF DATA-TREE CONSTRUCTION=============== //===================================================== //instanciate the root: VarListPtr root(new VarList("root node")); //add a sub-node: VarListPtr v_list1(new VarList("a subtree")); root->addChild(v_list1); //let it be a child of the root //create a trigger-button VarTriggerPtr v_trigger1(new VarTrigger("trigger","click me")); v_list1->addChild(v_trigger1); //add it to the tree //create a slider bar VarShortPtr v_short1(new VarShort("short integer", 1, 0, 100)); v_short1->addFlags(VARTYPE_FLAG_PERSISTENT); v_list1->addChild(v_short1); //create a variable of type double: VarDoublePtr v_double1(new VarDouble("my double")); v_list1->addChild(v_double1); //add it to the tree //create another variable of type double, with a default value: VarDoublePtr v_double2(new VarDouble("double w/ default", 20.0)); v_list1->addChild(v_double2); //add it to the tree VarDoublePtr v_double3(new VarDouble("double w/ persistent editor")); v_double3->addFlags(VARTYPE_FLAG_PERSISTENT); v_list1->addChild(v_double3); //add it to the tree //create another variable of type double, with a default value //and min/max ranges VarDoublePtr v_double4(new VarDouble("double with min/max", 0.5, 0.0, 1.0)); v_list1->addChild(v_double4); //add it to the tree VarListPtr v_list2(new VarList("another subtree")); root->addChild(v_list2); v_list2->addChild(VarStringPtr(new VarString("a string"))); v_list2->addChild(VarStringPtr(new VarString("string w/ default", "foobar"))); VarListPtr v_list3(new VarList("a sub-sub tree")); v_list2->addChild(v_list3); v_list3->addChild(VarIntPtr(new VarInt("an integer"))); v_list3->addChild(VarBoolPtr(new VarBool("a boolean"))); VarStringEnumPtr v_string_enum(new VarStringEnum("food-selector", "French Fries")); v_string_enum->addFlags(VARTYPE_FLAG_PERSISTENT); v_string_enum->addItem("Cheeseburger"); v_string_enum->addItem("French Fries"); v_string_enum->addItem("Ice Cream"); v_list1->addChild(v_string_enum); //some example access printf("old value of node '%s': %f\n", v_double1->getName().c_str(), v_double1->getDouble()); //some example mutation v_double1->setDouble(30.0); printf("new value of node '%s': %f\n", v_double1->getName().c_str(), v_double1->getDouble()); //instead of using accessors/mutators you can also wait for user-input //by using QT event-handling //in this example we link a node to a local event function //Note that each vartype has two events: // "hasChanged()" will be triggered whenever the internal data changes, // no matter whether this happened programmatically or through the GUI // "wasEdited(VarPtr)" will be triggered only if the data was changed by the user // through the GUI. This is usually what you want. //For this event-example, first let's create a standard node: VarDoublePtr v_double(new VarDouble("Event Example (change my value and see console!)")); root->addChild(v_double); //now let's hook up the wasEdited event to a local function 'notificationExample' //which is defined further below in this file //we do so using QT's 'connect' function //qt will make sure that everytime a user changes the node, the event will fire. connect(v_double.get(),SIGNAL(wasEdited(VarPtr)),this,SLOT(notificationExample(VarPtr))); //finally an example of a subtree that's stored in a separate XML file: //simply use VarExternal instead of VarList and provide a filename as constructor. //that's it! VarExternalPtr v_ext(new VarExternal("other_settings.xml", "this tree has its own XML file")); root->addChild(v_ext); v_ext->addChild(VarIntPtr(new VarInt("another int"))); v_ext->addChild(VarBoolPtr(new VarBool("a bool value defaulting to true",true))); //===================================================== //=======END OF DATA-TREE CONSTRUCTION================= //===================================================== //the root is our only toplevel node //(you can have multiple roots if desired): world.push_back(root); //read settings from XML file world=VarXML::read(world,"settings.xml"); //tell our gui what toplevel node(s) we want to visualize tmodel->setRootItems(world); //optional: expand the root node: //Hint: you can call this on any node: tree_view->expandAndFocus(root); //optional: fit columns to maximum data-width: tree_view->fitColumns(); //make the tree view the application's one and only widget: setCentralWidget(tree_view); //give this window a decent size resize(640,480); }