Changing QGraphicsScene Insertion Order Without Reloading - qt

I'm working on a graphical shape editor that uses the QGraphicsScene/QGraphicsView as its basis. I have a lot of experience with the scene/view framework and understand it fairly well. The issue that I'm having is that QGraphicsScene::items always returns items in the insertion order (either ascending or descending) regardless of the Z-order or the use of QGraphicsItem::stackBefore call.
The issue is that, as with most graphics editors, I need to be able to move shapes forward or backward in the stacking order. At the end, to save the resulting data, I have to traverse the list of the items in the scene and save each item's data in whatever format I'm using.
The only way that I've found to do this is that I have to remove items from the scene and reinsert them in the desired stacking order. In this particular task, it's a small number of items and happens without noticeable delay, but in a related editor, it could be many thousands.
While the QGraphicsItem::zValue and QGraphicsItem::stackBefore allow me to influence the drawing order, neither of them changes the order that gets returned from QGraphicsScene::items. Since the data I ultimately save needs to reflect the drawing order, I have to remove and reinsert to get the correct ordering at the end.
Questions:
Have I've overlooked any other techniques for managing items within the scene that will influence the results of QGraphicsItem::items?
Or is there another method for traversing the items within the scene that will give me the drawing order?

I can confirm that QGraphicsScene::items() and items(sortOrder) return the item list in the original creation and stacking order, which does not at all agree with the docs.
However, I found that by using
QGraphicsScene::items( QGraphicsScene::itemsBoundingRect, Qt::IntersectsItemBoundingRect, sortOrder) I do get the items in the correct drawing order, so this function apparently takes calls to QGraphicsItem::stackBefore() into account.
i don't use the z-order feature so I can't comment on whether that works in this scenario or not.

Related

Some instances not appearing when switching rooms [GMS2]

I'm a bit new to GMS2 and am having a bit of a problem.
In the current state of my game, you start in a useless room that only exists to initialize global variables and a persistent object. This room then switches to an actual level. All of this occurs in the creation code of the first room:
globalVars();
instance_create_depth(-2*global.tile_size, -2*global.tile_size, 0, OBJ_UTIL_manager);
room_goto(2);
Upon switching rooms, only some of the instances appear. In particular, only objects without a parent or with one certain parent appear. Objects with another type of parent do not appear. They are present in the room builder. They DO exist, but are invisible.
The same room, if moved to the top of the room queue and therefore being the first room created, works just fine as long as I add the above global variable initialization and manager object creation. Is there anything special that must be done when switching rooms to make things visible?
This is how the room appears in the editor: http://prntscr.com/lg2x3w
Compared to how it appears upon being switched to: http://prntscr.com/lg2wdg
I do not know the full detail of the problem, but I did have a similar issue, so I can tell you a solution without actually knowing what went wrong, but anyways hope it helps.
Firstly, use the instance_create_layer instead of instance_create_depth and make sure that these layers where you create your objects exist in both the first "fake" room and the actual room.
secondly, make sure you do not have any code that change the depth/layer in the create event. [again I do not know why this could cause an issue, but it did cause an issue to me, so maybe you have the same issue/solution]

immutable functional data structure to represent graphs

I (almost) fully understand the Zipper data structure for trees. However, in some publications I saw hints that it is also possible to use the Zipper idea to create immutable functional data structure for arbitrary graphs (which might have cycles as well).
What's the way to do it?
As soon as we have cycles, it means that any node can be reached via several paths. Hence, if I focus on a node, do some change to it, and move the focus away, I might later on come back to the same node via a different path, which means that it would be an 'old' version of the node, prior to the change made.
The only solution I came up with is to include to the context the list of changes to any node. Every time before the focus is changed to node X, it should be checked whether X is the member of the list of changes, and if so, it should be taken as the focused node.
If we also track the number of times N node X was copied from the list of changes, we can remove X from the list of changes, as soon as N = number of edges, inward to X.
Is there any better way to do it?

Accessing a Components Property prior to the Instantiation

I have the following problem:
I have a list of Components, that contain Rectangles with a width of either 200 or 800. I'd like to filter this list, and only create objects of the Rectangles with a width of 200 as I work on a small screen.
Preferably I do not want to create all objects, check their width, and destroy those with the wrong width again. For obvious reasons I really only want to create those with a width of 200.
To do this I would need to aquire knowledge of the width, before I instantiate them.
As far as I have seen, there is no publicly available and documented way of introspecting/reflecting the Component prior to it's instantiation.
My question is: Is there a non-public way to gain knowledge about what is packaged inside of my Component? Might it be possible with C++?
Or would it at least be possible to find out what kind of Object is encapsulated? Whether it will be a CustomComponent1, a Button, a RedRectangle...
Unfortunately not. You can't even predict it, since the Component could even point to a qml file that hasn't even been downloaded yet, if it was fetched from the network.
There are a couple of things you can try though, if you have room to approach the problem from another angle:
What you can do is pass properties from outside the component into it as it gets created. Assuming you control the code within the Component, you can then adjust how the internal elements get created based on the value of the property(ies) that was(were) set from outside.
If that's not good enough, say your Component provides multiple elements and you only want to create the ones that match your criteria (possibly a combination of many), then you can introduce a second Component layer within the first Component, and have that second Component either create the actual element if it matches your criteria, or an empty Item{} if it doesn't, which is as close as it gets to not creating anything.
I hope that helps!

Remove Selected Items from Search Results

Use Case:
End-User searches for something and an ArrayCollection is returned with Result objects. This is displayed in a data grid.
End-User selects a few of the search results and "moves" it over to another datagrid for use later.
End-User does another search.
PROBLEM:
Some of the search results might contain something the user already previously selected and moved over to the second datagrid. I want to remove these from the second search result.
How can I do this quickly, and efficiently in Flex code?
disableAutoUpdate() on both array collection
loop through the first one and for each item of the second remove it if it's present in the first one (or adapt the algorithm based on what you really want - unsure)
enableAutoUpdate() at the end.
Looping through array collection can be quick if no events are dispatched.
Second option, you could also loop through a cheap copy made up of an array, which is arraycollection.source.concat(), or even a vector if all your items are of the same type. That will give the maximum speed, but you might lose in the long run as you need to convert back to an array collection at the end.
So I would stick to the first option.
For the time being, I've implemented a hash collection (extends ArrayCollection). Hash only allows unique values, so in the end, it serves my purpose even though the UI might be confusing to the user. Will probably implement the above method at a later date. :)

Horizontal Label on DateTimeAxis dissappears sometimes after changing data, why?

I'm working with an Adobe Flex project and I have data I'm plotting against a DateTimeAxis (X-axis) but because there are a lot of points, I have to do some manipulation and remove some objects in the array (I do this by copying data to another array, removing items, then copying the new array into the original array). However, sometimes after I do this, the date labels disappear off of the x-axis! Why does this happen? I look through my array and I cannot find a reason its occurring (no objects with nothing in them, everything appears in chronological order). Any ideas?
I have the same problem. It appears the DateTimeAxis is a buggy component. Try to set the disabledDays property to [].
Also, the DateTimeAxis is sometimes not able to compute proper values for its labels, so it simply displays nothing. I guess...
BTW, have you tied to use the slice method to give a piece of your original data to your chart, instead of performing add and remove manipulations ? It could be faster...

Resources