wxTreeItemId how to get data - c++

I'm tried to create my own version of the wxTreeItemId which stores extra data. Sew below:
TreeItemId.h
#ifndef TREE_CTRL
#define TREE_CTRL
#include "wx/treectrl.h"
#include "Particle System.h"
class TreeItemId : public wxTreeItemId
{
public:
TreeItemId(ParticleSystem* system);
private:
ParticleSystem* particleSystem;
};
TreeItemId.cpp
TreeItemId::TreeItemId(ParticleSystem* system)
: wxTreeItemId()
{
particleSystem = system;
}
I want to use an event to get the selected TreeItem but I can't work out a way of using my treeItem class rather than the standard.
I want to do something in the line of:
void TopRightPanel::OnSelChanged(wxTreeEvent& event)
{
TreeItemId *item = (TreeItemId)event.GetItem();
}
This doesn't work though... Any advice would be appreciated. Do I need to use my own version of wxTreeItemData?

You should subclass your data object from wxTreeItemData instead of wxTreeItemId.
Let's say you have MyItemData : public wxTreeItemData {}; then
wxTreeItemId itemId = event.GetItem();
MyItemData * data = (MyItemData *)m_MyTreeCtrl->GetItemData(itemId);
if(data) { /* Doo what you need here */ }
In order to set the item data you need to use InsertItem() method and specify the data object there. Or use SetItemData() for existing item and pass item ID and data object to this method.

Related

How to update unique items in a TArray

I'm adding and updating unique items in a TArray* using the following method.
USTRUCT() struct FMyObject
{
GENERATED_BODY()
UPROPERTY(SaveGame) // example for serialization
FName key;
UPROPERTY(SaveGame) // example for serialization
int someContent;
}
UCLASS() class FMyObjectOwner : public UObject
{
GENERATED_BODY()
AddOrReplaceUnique(const FMyObject& newObject)
{
// Remove possibly existing entry.
const auto index = myObjects.IndexOfByKey(newObject.key);
if (index != INDEX_NONE)
{
myObjects.RemoveAtSwap(index, 1, false);
}
// Add new.
myObjects.Add(newObject);
}
UPROPERTY(SaveGame) // example for serialization
TArray<FMyObject> myObjects;
}
Is there a shorter or more convenient way (removing and adding in one call?) to update unique items in a TArray using UnrealEngine >= 4.24?
*I'm using a TArray instead of a TMap or a TSet since I want it to be garbage collected and to be serialized. I'm not sure if both is supported by the latter container types.

Why is QObject ::findChildren returning children with a common base class?

I am using QObject as a base class for a composite pattern.
Say I have a parent class File (in a contrived example) to which I am adding children of different types, HeaderSection and PageSection. File, HeaderSection and PageSection are all Sections. The constructor for Section takes a parent object which is passed through to QObject's constructor, setting the parent.
e.g:
class Section : public QObject {
Q_OBJECT
// parent:child relationship gets set by QObject
Section(QString name, Section *parent=NULL) : QObject(parent)
{ setObjectName(name);}
QString name(){return objectName();}
};
class File: public Section {
public:
// probably irrelevant to this example, but I am also populating these lists
QList<Section *> headers;
QList<Section *> pages;
};
class Header : public Section {
Header(QString name, File *file) : Section(name, file){}
};
class Page: public Section {
Body(QString name, File *file) : Section(name, file){}
};
Syntax for construction in the definition may be incorrect, apologies, I'm used to doing it outside. Anyway, when I do this:
File *file = new file();
Header *headerA = new Header("Title", file);
Header *headerB = new Header("Subtitle", file);
Page *page1 = new Page("PageOne", file);
Page *page2 = new Page("PageTwo", file);
QList<Page*> pages = file->findChildren<Page*>();
for(int i=0; i < pages.size(); i++)
qDebug() << pages.at(i)->name();
I get the following output:
Title
Subtitle
PageOne
PageTwo
What am I missing here? Surely if findChildren looked for common base classes then it would only ever return every single child of a Widget (for example), which I know it doesn't in normal use.
Also, if I iterate over the list of children returned and use dynamic_cast<Page*> on each returned child, I get the expected two Page items.
The answer is as #Mat and #ratchet freak tell me - I needed Q_OBJECT in every subclass, not just the base class.

Need to sort a list using Wicket

I am working on a very simple program, looking like this:
public class WicketApplication extends WebApplication implements Comparable<Object>{
private List<Person> persons = Arrays.asList(
new Person("Mikkel", "20-02-91", 60169803),
new Person("Jonas", "02-04-90", 86946512),
new Person("Steffen", "15-07-90", 12684358),
new Person("Rasmus", "08-12-93", 13842652),
new Person("Michael", "10-10-65", 97642851));
/**
* #see org.apache.wicket.Application#getHomePage()
*/
#Override
public Class<? extends WebPage> getHomePage() {
return SimpleView.class;
}
public static WicketApplication get() {
return (WicketApplication) Application.get();
}
/**
* #return #see org.apache.wicket.Application#init()
*/
public List<Person> getPersons() {
return persons;
}
public List<Person> getSortedList(){
return Collections.sort(persons);
//This won't work before implementing comparator i know, but how??
}
#Override
public void init() {
super.init();
// add your configuration here
}
#Override
public int compareTo(Object o) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}
That was the class where i just put my people into a list.
public class SimpleView extends SimpleViewPage {
public SimpleView() {
ListView persons = new ListView("persons", getPersons()) {
#Override
protected void populateItem(ListItem item) {
Person person = (Person) item.getModelObject();
item.add(new Label("name", person.getName()));
item.add(new Label("birthdate", person.getBirthdate()));
item.add(new Label("phone", person.getPhone()));
}
};
add(persons);
add(new Label("size", "Number of people " + getPersons().size()));
}
}
And here is what i do with the people.
Basicly i want the program to show a table with all the data(this already works).
Now i want to be able to sort them. But i can't for the life of me figure it out. I'm still rather new at programming, and i want to have a button below my table that can sort on name, bday or phone number. Was thinking about trying to Comparable, but can't remember it that well, and not sure how it works with Wicket..
Thanks for the help in advance :)
What you need is the DataView component, which provides all the support you need for sorting (and paging, should you require it later on).
Here's a working example, if you click on the "Source Code" link in the top right corner, you can see that most of the things you want from a sortable table work out of the box. All you need is to create a suitable data provider.
If you use DataView with a SortableDataProvider, you don't need to worry about writing your own dynamic Comparator. (Which is not a terribly hard task itself, but it's easy to get it wrong.)

Storing custom objects in QStandardItemModel

I'd like to store custom objects (let's say instances of MyDataClass) in a tree structure, and linked with a view. So I used QStandardItemModel. I think that MyDataClass should inherit from QStandardItem :
class MyDataClass : public QStandardItem
{
public:
MyDataClass(QString name)
private:
vector<float> someData;
}
But I cannot figure out how to store instances of this class in a QStandardItemModel.
I tried QStandardItem.setChild and then appendRow but it does not work and I think I don't really get the QStandardItemModel thing.
I think that the solution deals woth QStandardItem.setData but I cannot figure out how it works for custom objects.
I have finally make it work using QVariant.
To fill the model with custom data :
MyDataClass *data;
... // adding some data
QVariant variant;
variant.setValue(data);
QStandardItemModel model; // here is your model
QStandardItem *parentItem = model.invisibleRootItem();
QStandardItem *item = new QStandardItem();
item->setData(variant);
parentItem->setChild(0, 0, item); // adding the item to the root
Later, when you want to retrieve your data :
MyDataClass *retrievedData = model.invisibleRootItem()->
child(0, 0)->data().value<MyDataClass*>();
Note that I had to add a line in the class declaration :
class MyDataClass : public QStandardItem
{
public:
MyDataClass(QString name)
private:
vector<float> someData;
}
Q_DECLARE_METATYPE(MyDataClass *) // add this line
Thank you for your help.
You can use QStandardItemModel::setItemPrototype.
http://qt-project.org/doc/qt-4.8/qstandarditemmodel.html#setItemPrototype
Inherit from QStandardItem and reimplement method clone.
Create a new instance of your item and pass it to setItemPrototype.

Qt Do my items are deleted after removing my scene ? Is my program well-architectured?

For some days now, I'm stuck. I'm not sure where my problem is, architecture ? Or just a protection to add for make my scene to not delete my items ?
This is how my program is architectured :
I have 1 GraphView + 1 GraphScene in all my ui, I switch ui with SetCentralWidget in my primary windows.
I saved all my Items in a QList or QVector in another class, all my windows have a pointer to this class passed by my primary windows. (yes, all my saved items are public: ... I know it's bad but how can I do ?).
So now I have this problem :
1 - My primary windows create and initiate my "storage class"
1 - my first ui add items in the QList (in storage class)
2 - I destroy this ui and pass to another ui
3 - I try to add items added before in my QList, and my program crash :
// PointMesure = QGraphicsRectItem and "d_e" is the pointer to the "stockage class"
foreach(PointMesure *point_mesure, d_e->liste_points_mesures) {
scene->addItem(point_mesure);
}
So I think the problem is my items are deleted when I destroy the scene in my first ui ??
I'm a novice so maybe my program is not well architectured... What do you think ?
Be nice ;)
The Stockage class header :
class ConteneurDonneesEtude : public QObject
{
public:
ConteneurDonneesEtude(QWidget *parent = 0);
public:
QList <PointMesure *> liste_points_mesures; // Dérive de QGraphicsRectItem
private:
QWidget *fenetre_principale;
};
I Load from a XML file :
void ConteneurDonneesEtude::creer_items_points_mesures(QXmlStreamReader *fichier_xml) {
// Loading
PointMesure *temp = new PointMesure();
temp->setPos(QPointF(x, y));
temp->setRect(QRect(-offset_centre, -offset_centre,
taille_point_mesure, taille_point_mesure));
// set other things.... this part worked in another project anyway :)
this->liste_points_mesures.insert(numero, temp);
}
My first ui GraphView :
Creation :
void FenetrePrincipale::slot_importer_etude() {
fen_importer_etude = new FenetreImporterEtude(this, d_e);
this->setCentralWidget(fen_importer_etude);
connect(fen_importer_etude, SIGNAL(sig_continuer()), this, SLOT(slot_nommer_points()));
connect(fen_importer_etude, SIGNAL(sig_retour()), this, SLOT(slot_importer_etude()));
}
And then :
void GraphImporterEtude::afficher_donnees_etude() {
foreach(PointMesure *point_mesure, d_e->liste_points_mesures) {
scene->addItem(point_mesure);
}
}
I create another ui, setCentralWidgetwill auto. destroy the last ui :
void FenetrePrincipale::slot_nommer_points() {
fen_nommer_points = new FenetreNommerPointsMesure(this, d_e);
this->setCentralWidget(fen_nommer_points);
connect(fen_nommer_points, SIGNAL(sig_continuer()), this, SLOT(slot_integration_tacheo()));
connect(fen_nommer_points, SIGNAL(sig_retour()), this, SLOT(slot_importer_etude()));
}
And then
void GraphNommerPointsMesure::afficher_points_mesures_actifs() {
foreach(PointMesure *point_mesure, d_e->liste_points_mesures) {
if(point_mesure->actif) {
scene->addItem(point_mesure);
}
}
}
Segmentation fault !