I've looked in multiple places and cannot seem to find anything to work for my purpose.
I have this QComboBox that constantly changes (And could change after the program is completely finished).
To make it easier I made an Enum list for switch statements
public:
enum Race{
Race1,
Race2,
ect
}
The combo is filled with the same elements.
However, I want to make it even easier. So instead of changing the Combobox and changing the enum list, is there a way where all i have to do is add a new "race" to the enum list, that it will populate the combobox, so all i would have to do is a switch statement to handle new race?
Additional info:
I'm willing to put the enum list into a qstringlist.
I have Q_ENUMS (Race) set
Using Q_ENUMS will give you a way to iterate over your enum and add their enumerands to the combobox in a loop. However it will not give you the possibility to add a related GUI text for each enumerand. The enumerand name like it is written in your source code will be available only. Maybe your code side name is not what you want to see in your GUI as a text.
Remember that you can add any kind of QVariant supported user values to a combobox while you populate it with text strings... so you do not need to maintain an enumeration if there is some other kind key you can use instead.
Related
You are in a client script and taking the page.descendants (or pageFragment, popup, etc, whatever) and want to iterate its values, it's ok no problem:
app.popups.GlobalFilter.descendants.foreach(function (w){...})
But when you are in the closure you can't determine what kind of widget you dealing with, is it TextEdit or DatePicker, or Multiselect. All you have - properties (name, align, etc.). There is no property like ComponentClass, WidgetClass or ClassName.
You even can't set the values because you don't know what property you have to set (value for Datepicker and values for Multiselect) and it's type (Date for DatePicker and array for Multiselect).
I have to hardcode widget names with their types for now, but maybe I missed something and there is a way to determine widget/component class name?
I need to create QTreeWidgetItems which have support for formatted texts, such as:
MyCreatedType - INTEGER(1)
(ie: the line above should have a "normal" part : MyCreatedType and a "formatted" part (INTEGER(1) in our case).
Any idea how to accomplish this?
Thanks.
What you need is a delegate. Delegates are explained here:
Star Delegate Example http://qt-project.org/doc/qt-4.8/itemviews-stardelegate.html
QItemDelegate Reference http://qt-project.org/doc/qt-4.8/qitemdelegate.html
The general procedure I follow when creating and using custom delegates:
Create a custom type with the information you want to encapsulate.
For your case, perhaps fields for the variable type name and type value.
Store these custom types in your model, wrapping them in QVariants to satisfy the return types required by QAbstractItemModel
Create a control that matches the UI you want.
In this case it might mean a QText label for "MyCreatedType" followed by a second label in bold for "Integer(1)".
Perhaps the control has methods like "setTypeName" and "setTypeValue"
Create a delegate that paints your specific control when your custom type is found.
You will have to map fields in the custom type to fields in the custom UI control as needed.
Associate your model and delegate with the Tree View you are using.
I hope this general procedure makes sense. I would recommend completing the Star Delegate Example and then reading my procedure, as it will make more sense with some background.
I would like to store MetaObjects in a list like this:
myList = QList<QMetaObject>();
myList->append(MyClass::staticMetaObject);
myList->append(MyOtherClass::staticMetaObject);
I want to keep track of these object through out the application but I don't wish to allocate them just yet. By adding some information in my classes I will be able to use the MetaObject function "classInfo(int).value()". I use this when I store them in a QListWidget. When a row in the QListWidget is pressed I would like to be able to create an object of that specific kind that is stored in the list.
(Also have to add that all the classes dervies from the same baseclass)
This sample code describes a bit of what I want to do, except in his example, you add the classes as you go along.
http://lists.qt.nokia.com/pipermail/qt-interest/2012-January/037204.html
I read through the manual and when I try things like:
MyBaseClass *test = qobject_cast<MyBaseClass*>myList->at(i).newInstance();
The project compiles but when I try to print the "test" object its null. What am I doing wrong? And is this the best way of doing this?
Was also looking at MetaType, but where would i be able to store, for example a string for the menus if I'm not allowed to create the object? Would this be a nicer solution if I have a static function that returns a string?
Edit:
I now changed so the constructors are Q_INVOKABLE which solved the problem where "test == null".
But what are the downside of this solution? Should I just use a object factory (the old fashion way with a switch case)?
i've searched for several hours, and didn't find an answer for my problem.
i'm trying to place comboboxes in a datagrid filled with DYNAMIC data. (the number and the content of these comboboxes always change. i don't know in advance how many columns there are, where i need to use comboboxes. so every single combobox gets a unique dataprovider, which comes from an external source, WHEN the program runs.)
-i found MANY threads discussing this problem, but solving via crappy mxml files, filling the comboboxes inside the sourcecode by hand. i want to point out, that isn't good for me.
-i found a better solution, in which they used some sort of custom itemrenderer to get the data from the internet. (kind of a country chooser thing) but sadly that wasn't good enough, because the number and name of the countries in the world are static more or less, they don't change. so their renderer class didn't depend on any parameters from the main algorithm.
but in my program i calculate the data in my own actionscript objects, then fill an arraylist with that. so at the beginning i load the desired data from the net, and when i get the response of the urlrequest, AFTER that i start to populate the datagrid/combobox.
i can fill any datagrid or combobox without trouble, but to put that combobox inside a datagrid cell seems to be impossible.
could anyone please help? it drives me crazy. i managed to do this in several languages before, c#, java, even php+html, but in flex it looks way too complicated then it should be.
EDIT:
i'm aware, that this amount of network activity could mean some load on the server. i didn't design the philosophy behind it, i just need to wrote a client which meets the expectations. my program looks something like this:
(i'm willing to rewrite any part of it, just to make those nasty comboboxes work)
=========
main.mxml file
this is the main program, i handle some login related stuff here, and set basic design properties for the datagrids. (for example: maxwidth, maxheight, layout constraints etc.)
nothing interesting, except the command when i instantiate the actionscript class, which i wrote to fill the datagrid.
"..<fx:Script>
<![CDATA[
private var myGrid1:MyGridType;
..
somefunction {
myGrid1 = new MyGridType(theDatagridDefinedBefore, "argumentNeededToFillDataGridsWithUniqueData");
}
]]>
</fx:Script>.."
=========
MyGridType.as file
in the constructor i call a urlrequest with the help of the second argument, then add an eventlistener to it. when the data arrives, the eventlistener fires the filler function: i read the results into an arraycollection, then make it the dataprovider for the the datagrid in the first argument.
so far so good.
here comes the trouble with the comboboxes. for a specific number columns, i instantiate my combobox class. let's call that class "MyComboBoxType".
"..
blablabla = new MyComboBoxType(theDatagridDefinedBefore, param1, param2, param3);"
=========
MyComboBoxType.as file
i do nearly exactly the same, what i did in the MyGridType class. call for help from the net with param1-2-3. when i receive the data, fill an arraycollection. maybe set that arraycollection to be the dataprovider for a combobox. AAAAAAAND now i want that arraycollection or combobox to be on the datagrid "theDatagridDefinedBefore".
I know it's not exactly what you're trying to accomplish, but I had a somewhat similar issue in the past. Take a look at How to get the value of a ComboBox within a DataGrid to see if it helps.
If it were me, I would populate the entire ArrayCollection set before binding them to the datagrid if at all possible.
You should build up your custom [Bindable] data structure - say MyGridData class - for the rows in the grid (if you haven't done it yet);
the dataProvider of your grid should
be an Array / ArrayCollection /..
of MyGridData objects.
this step clearly works already, but
for the integrity: override the
getItemEditor function, or specify
it explicitly using mxml, to return
the combobox when needed.
as for the dataProvider of the
combobox, you should specify the
data.comboArray from inside the
renderer class, where data is the
MyGridData instance used by the row
you are processing. (overriding the
set data(value: Object):void
function, you can pre-process it.)
this way, you are working with the
reference of your original instances,
and by the binding you can detect /
show any changes to them directly.
Is there an equivalent of .NET's data binding in Qt?
I want to populate some combo boxes and other widgets with QStrings that refer to specific entities in my database. However, it would be cleaner if I could bind the data to these strings rather than either querying the database again based off of a new combobox selection or some other scheme based off of building my own index of entities that would be searched with the QStrings.
The best I've come up with is to derive these entities from QString and pushing them into the widgets this way, but I've yet to actually try it. I'm not sure if it will work the way I want it to, and it seems like a nasty hack.
If there is no data binding, what do you suggest?
Thank you.
As the user nonchalant mentioned in a comment you can use the QDataWidgetMapper class.
This is quite an easy way of binding arbitrary widgets to data that is stored in a QAbstractItemModel.
The example on the linked page shows in a few lines of code, how you can link your data model to common used input widgets:
QDataWidgetMapper *mapper = new QDataWidgetMapper;
mapper->setModel(model);
mapper->addMapping(mySpinBox, 0);
mapper->addMapping(myLineEdit, 1);
mapper->addMapping(myCountryChooser, 2);
mapper->toFirst();
One way is using Qt Model/View Classes (with base at QAbstractItemModel), but they need that you widget inherits QAbstractItemView (this is widgets like QTableView etc.).
If you want map Qt model to set of widgets, which haven't nothing common with QAbstractItemView you can use QDataWidgetMapper, which maps separate widget to Qt Model/View indexes. But anyway, as said Aaron Digulla, you must write some boiler plate code...
Well, for combobox specifically, you can set a model. For QObjects in general you can use the notify signal for properties to connect or other non-property related signals. I think there is another way to do it but I can't recall.