My task is to check the value of data from the global data sheet within different UIs, each of them having lots of data.
My idea was to do this in a generic way.
I create a array with the objects name, which corresponds with the name of the data sheet column
And then I just compare the content
Browser("").Page("").GENERIC_TYPE(label).GetROProperty("value") = datasheet.GetParameter(label)
Is there such a Generic Type that works for WebEdit and WebList?
You can use WebElement and this is generic as all elements on the page are web elements.
If you are reading the objects from OR, then you might have to update the element type to WebElement and it's tidious (if you are dealing with multiple objects). So the alternative way is using the below approach.
Browser("").Page("").WebElement("xpath:=//*[#common_attribute=" + element_attribute_value + "]").GetROProperty("value") = datasheet.GetParameter(label)
Related
I am facing issues in performing certain actions based on the value in the excel file cell data.
Actions like if value is "NORMAL" then click Container type = Normal (radio button)
Similarly the Unit Container Value
Following is my code:
I am getting this error while performing action .WebElement("Container_Type_Normal").Click
Your error is because you can't start a line with . unless your within a with - and i can't see a with in your function. (i also don't recommend using a with as the can cause needless confusion)
The .webelement object is a catch-all type of object that is the child of other web objects or .page. You need this to be a full and valid path to the object, by this i mean start with browser().page().
You have a couple of options:
You can either make this a full path to your object based on the object repository:
Browser("<<OR Browser name>>").Page("<<OR Page name>>").WebElement("<<Your webelement name>>".click
For this, look at your OR and insert your names.
Or, option 2, you can use descriptive programming:
Browser("CreationTime:=0").Page("index:=0").WebElement("text:=" & fieldValue,"index:=0").click
That will take the browser that was created first (Creation time 0), the only page it has and the first (index 0) web element that contains your text (text is field value).
I'm assuming that you only have one browser, and that the first element that contains the text you want is what you want to click. You may need to add more layers too this or
A good approach is to mirror what is OR or use the object spy to ensure these properties are correct.
I have a script in which I filter the data in a module by a certain attribute value. When I then loop through these objects, for now, I am displaying the absolute number of the objects in an infoBox. However, the script is displaying absolute numbers of objects that are not in the dataset. Upon further investigation, I found that the extra absolute numbers were for each table within the entire module. I can't figure out why the script would include these tables when they are not in the filtered module data. I have even tried manually filtering the module on this attribute value then use the "Tools -> Edit DXL" to loop through the resulting items and it still displays the numbers for the tables that are not included. Why would it do this?
Here's my code:
bm2 = moduleVar
Filter fltr = contains(attribute "RCR_numbers", sRCRNum, false);
filtering on;
set(bm2, fltr);
for oObj in document(bm2) do {
absNum = oObj."Absolute Number";
infoBox("Object #" absNum ".");
}
I have also tried removing the document cast so it says "for oObj in bm2 do" instead, but this doesn't change the output. Why is the code giving me objects that are not in the filter? Any help would be greatly appreciated since this is a high priority issue for my project and I'm out of ideas myself.
Chris
In the DOORS 9.6.1 DXL Reference Manual you can see that:
for object in document
Assigns the variable o to be each successive
object in module. It is equivalent to the for object in module loop,
except that it includes table header objects, but not the row header
objects nor cells.
So, you must either use for object in module or, within your existing loop, test the hidden attribute TableType - this will be set to TableNone for anything that is not part of a table, table headers included.
This must be easy but for some reasons I can't get this to work.
What I have is 2 GUIs namely GUI1 and GUI2.
In GUI1 I read and stored an Image in say A. It also has a PushButton. Now when I click this Button it should show that image in GUI2's axes1.
I tried setappdata and getappdata but it ends up giving error. I can't understand the syntax. I'm all new to MATLAB. Any help is appreciated.
setappdata / getappdata are discussed in more detail below.
As mentioned in the comments, you can use setappdata(0, ... / getappdata(0, ... to assign/read data to/from the root object.
Excerpted from MATLAB User Interfaces - Passing Data Around User Interface. The original authors were Suever and Hoki. Attribution details can be found on the contributor page. The source is licenced under CC BY-SA 3.0 and may be found in the Documentation archive. Reference topic ID: 2883 and example ID: 9775.
Passing Data Around User Interface
Most advanced user interfaces require the user to be able to pass information between the various functions which make up a user interface. MATLAB has a number of different methods to do so.
guidata
MATLAB's own GUI Development Environment (GUIDE) prefers to use a struct named handles to pass data between callbacks. This struct contains all of the graphics handles to the various UI components as well as user-specified data. If you aren't using a GUIDE-created callback which automatically passes handles, you can retrieve the current value using guidata
% hObject is a graphics handle to any UI component in your GUI
handles = guidata(hObject);
If you want to modify a value stored in this data structure, you can modify but then you must store it back within the hObject for the changes to be visible by other callbacks. You can store it by specifying a second input argument to guidata.
% Update the value
handles.myValue = 2;
% Save changes
guidata(hObject, handles)
The value of hObject doesn't matter as long as it is a UI component within the same figure because ultimately the data is stored within the figure containing hObject.
Best for:
Storing the handles structure, in which you can store all the
handles of your GUI components.
Storing "small" other variables which need to be accessed by most callbacks.
Not recommended for:
Storing large variables which do not have to be accessed by all
callbacks and sub-functions (use setappdata/getappdata for
these).
setappdata/getappdata
Similar to the guidata approach, you can use setappdata and getappdata to store and retrieve values from within a graphics handle. The advantage of using these methods is that you can retrieve only the value you want rather than an entire struct containing all stored data. It is similar to a key/value store.
To store data within a graphics object
% Create some data you would like to store
myvalue = 2
% Store it using the key 'mykey'
setappdata(hObject, 'mykey', myvalue)
And to retrieve that same value from within a different callback
value = getappdata(hObject, 'mykey');
Note: If no value was stored prior to calling getappdata, it will return an empty array ([]).
Similar to guidata, the data is stored in the figure that contains hObject.
Best for:
Storing large variables which do not have to be accessed by all
callbacks and sub-functions.
UserData
Every graphics handle has a special property, UserData which can contain any data you wish. It could contain a cell array, a struct, or even a scalar. You can take advantage of this property and store any data you wish to be associated with a given graphics handle in this field. You can save and retrieve the value using the standard get/set methods for graphics objects or dot notation if you're using R2014b or newer.
% Create some data to store
mydata = {1, 2, 3};
% Store it within the UserData property
set(hObject, 'UserData', mydata)
% Of if you're using R2014b or newer:
% hObject.UserData = mydata;
Then from within another callback, you can retrieve this data:
their_data = get(hObject, 'UserData');
% Or if you're using R2014b or newer:
% their_data = hObject.UserData;
Best for:
Storing variables with a limited scope (variables which are likely to be used only by the object in which they are stored, or objects having a direct relationship to it).
Nested Functions
In MATLAB, a nested function can read and modify any variable defined in the parent function. In this way, if you specify a callback to be a nested function, it can retrieve and modify any data stored in the main function.
function mygui()
hButton = uicontrol('String', 'Click Me', 'Callback', #callback);
% Create a counter to keep track of the number of times the button is clicked
nClicks = 0;
% Callback function is nested and can therefore read and modify nClicks
function callback(source, event)
% Increment the number of clicks
nClicks = nClicks + 1;
% Print the number of clicks so far
fprintf('Number of clicks: %d\n', nClicks);
end
end
Best for:
Small, simple GUIs. (for quick prototyping, to not have to implement the guidata and/or set/getappdata methods).
Not recommended for:
Medium, large or complex GUIs.
GUI created with GUIDE.
Explicit input arguments
If you need to send data to a callback function and don't need to modify the data within the callback, you can always consider passing the data to the callback using a carefully crafted callback definition.
You could use an anonymous function which adds inputs
% Create some data to send to mycallback
data = [1, 2, 3];
% Pass data as a third input to mycallback
set(hObject, 'Callback', #(source, event)mycallback(source, event, data))
Or you could use the cell array syntax to specify a callback, again specifying additional inputs.
set(hObject, 'Callback', {#mycallback, data})
Best for:
- When the callback needs data to perform some operations but the data variable does not need to be modified and saved in a new state.
I am quite new to Qt and am in a situation where I want to use a model for my needs:
I have a dynamic number of instances of a subclass that need to be handled differently (different UI controls for each if it is selected). I want to get a list view where I can add new elements or delete old ones, as well as disabling/enabling existing ones.
Of course I want to rewrite as least of the code as possible, so I thought of utilizing the Listwidget and a ListModel to give some controls to the user. But how to link these (or better the items) to instances of the classes?
Do you know any tutorials on this?
I already looked in QtDemo and Google but I do not know the right words to search for
so I had no good results.
Basically what I think I need is a model item that accepts Collider* for its data.
But when I plug this into QStandardItem.setData() it says error: ‘QVariant::QVariant(void*)’ is private
So I found the solution to this problem.
As QStandardItems are capable of storing QVariants as data I wanted to store a pointer to my data in a QVariant. To achieve this I had to use Q_DECLARE_METATYPE(MyType*).
With this I was able to
MyType *MyInstance = new MyType;
QVariant data;
data.setValue(MyInstance);
QStandardItem *item = new QStandardItem("My Item");
item->setData(data);
standardModel->appendRow(item);
And the best is you can add as many types you want and let QVariant do the work to decide if it contains the type you wanted:
if(v.canConvert<MyType*>())
//Yes it is MyType
else if( v.canConvert<MyOtherType*>())
//Oh it is the other one
So finally this only requires to declare the meta type so you do not have to subclass any items.
Also you should read on the limitations of this here:
Q_DECLARE_METATYPE
qRegisterMetaType
Does this page answer your questions? There's an example of deriving a StringListModel item that you might be able to use as a template
If I have a collection of forms (myForms) and I want to switch the position of two forms in the collection (say items 3 and 4 for example), I would expect that the following code would work:
Dim temp as Form
Set temp = myForms(3)
Set myForms(3) = myForms(4)
Set myForms(4) = temp
But that doesn't work. It fails at the third line with the error "Controls property is read only." If I change the line to:
myForms(3) = myForms(4)
I get a type mismatch error instead.
If myForms is a standard collection:
Dim myForms as New Collection
(which is actually different from the controls collection) and you've added the forms using:
myForms.Add frmOne, myForms.Add frmTwo
etc then (yes) you do need to use the Add and Remove methods because of the way the collection references the added objects.
Otherwise the interpretation is that you actually want to replace one form with another and this is not allowed. You can't say:
Set frmOne = frmTwo
unless these are actually variables of type Form.
Why do you need to switch the order? Are you referencing the item numbers somewhere? Would using a Dictionary to collect the forms and reference them by a key be useful?
PS. The type mismatch is simply because both items are objects and need to be 'Set'.
You can't actually swap around items in the controls collection in VB6. You need to use the Add and Remove functions associated with each. Check out this article:
http://support.microsoft.com/kb/190670
Hope this helps!