QGraphicsItem under cursor at leaving object while over another item - qt

I have a QGraphicsScene, QGraphicsView and some QGraphicsItems subclassed.
I want to track which item is under the cursor topmost visible.
It works fine using hoverEnterEvent in most situations, but if I have two Objects where one is on top of another it does work on entering both but not on leaving the inner object (and re-entering the outer, since it never left the outer in the first place).
+-------------------------------------+
outside | |
| outer |
| |
| |
| +-------------+ | +-------------+
| | | | | |
| | | | | another |
| | inner | | | |
| | | | | |
| | | | +-------------+
| +-------------+ |
| |
| |
| |
| |
+-------------------------------------+
outside -> outer : works, outer is selected
outside -> outer -> outside -> another : works, first outside is selected, than nothing, than another
outer -> inner : works, inner is seletected
outside -> outer -> inner -> outer: does not work, first outside is selected, than inner, but than nothing (should be outer again)
What can I do, besides looping trough all graphicitems triggered via a slight delayed singleshot on hoverLeaveEvent?
Edit:
I found a temporary solution:
I added a global QList < MyQGraphicsItem *> where on MyQGraphicsItem::hoverEnterEvent I add "this", and on MyGraphicsItem::hoverLeaveEvent I remove the last item in the List. So the myGlobalQList.last() always contains the topmost item visible under the cursor.
I assume this is not the best solution since QList is not threadsafe, therefor I am still interested in other solutions.

Your QGraphicsItems live in a QGraphicsScene which can be displayed by one or more QGraphicsViews.
I know that the model-view mapping usually is 1:1.
Still I suggest to implement mouse handling like this in your view, not in the scene:
Install an eventFilter on your graphicsView->viewport().
Override the eventFilter() function in your filter class.
Watch for QEvent::MousePress, MouseMove, MouseRelease, maybe Enter and Leave, depending on what you need.
Probably you need to setMouseTracking(true) on the viewport.
Then, in the event filter function, use QGraphicsView::mapToScene() and QGraphicsScene::itemAt() to find the topmost item, or ::items() to find all items under the cursor.
I recently used this to decorate the topmost item with a border by painting over the view (QGraphicsView::drawForeground()).

Related

How to resize the Bottom Dock Area

I have a Qt app with the following layout, where the bottom dock-area extends under the right dock-area. This is the default when adding Dock widgets to both side and bottom areas.
+-----------------+-----+
| | DW1 |
| CW +-----+
| | DW2 |
+-----------------+-----+
| DW3 |
+-----------------------+
I would like to instead have the right dock-area extend down to the bottom beside the bottom dock area as such:
+-----------------+-----+
| | DW1 |
| CW +-----+
| | DW2 |
+-----------------+ |
| DW3 | |
+-----------------------+
This should be simple, but I have searched the documentation and asked almighty Google, without success. I am not adding a code sample, since this is more of a general API question.
I think you can use QMainWindow::setCorner...
QMainWindow main_window;
main_window.setCorner(Qt::BottomRightCorner, Qt::RightDockWidgetArea);
That should associate the bottom right corner with the right hand dock area -- haven't tested though.

How to extend side dock widgets vertically even when top/bottom docks are present?

Currently if I have QDockWidgets at the top, bottom and on the sides of my QMainWindow, they are arranged like this:
_____________________
| |
|_____________________|
| | | |
| | | |
| | | |
|___|_____________|___|
| |
|_____________________|
I'd like to have one of the side docks more extended vertically, like this:
_____________________
| | |
|_________________| |
| | | |
| | | |
| | | |
|___|_____________| |
| | |
|_________________|___|
How can I do this with QDockWidget? I've tried looking at the various options in Designer, looked through all the documentation of QDockWidget and QMainWindow multiple times, but haven't found anything relevant. Do I have to create my own layout for this, or maybe subclass QMainWindow?
void QMainWindow::setCorner(Qt::Corner corner, Qt::DockWidgetArea area)
Elaborating on #Tomas's answer. Qt documentation says:
void QMainWindow::setCorner ( Qt::Corner corner, Qt::DockWidgetArea area )
Sets the given dock widget area to occupy the specified corner.
It is in fact misleading: the area won't occupy just the specified corner. Rather this corner will belong to the area, i.e. you can set multiple corners to a single area, so you'd get e.g. side area at right with bottom-right corner, or with top corner, or with both.

Creating a Static Drawing Whose dimensions get changed based on the parameters supplied

I want to create an static drawing (say any animals like giraffe) using some points, lines, drawing etc. Now i want to update the drawing by passing the parameters say height of his legs, its width or its color.
The parameters are supplied from the web page. The image will be a 2D image
I am searching on which technology should i implement this for more than 10 hours but cannot find any perfect solution.
Right now i am thinking i can use Adobe flash in which i can do some programming to create an drawing and change the drawing by passing the parameters to a Flash file, i think we can pass it when we embed an flv.
Whether i am right? Or there is any other solution. I have no knowledge of any thing except asp.net
Please help.
Any help is appreciated
I'd like to build on the previous post - you could also incorporate svg graphics into the mix. This would allow you control over color, width, and height. You can manipulate SVG files with javascript (Dynamic SVG). You'll probably get that going faster than learning action script.
If you just want to be able to stretch or recolor parts of an image, you could do that using ordinary HTML parameters. Just create a giraffe image, break it into the chunks that you want to be able to resize independently, and use CSS layout or tables to assemble them. Here's an artistic rendering:
___________________________
|image 1 V__ <<|
|head |oo | <<| <--- delicious acacia leaves
| | < <<<|
---------------------------
|image 2 | | |
|neck |o| |
| | | |
---------------------------
|image 3 / | |
|body /------/ \ |
| | \ |
---------------------------
|image 4| | | | | | | | |
|legs | | | | | | | | |
| \_/ \_/ \_/ \_/ | <--- I do not know what giraffe feet look like
---------------------------
If you want to give your giraffe a short neck without changing anything else about it, you can just alter the height attribute of the second image, like so:
___________________________
|image 1 V__ <<|
|head |oo | <<|
| | < <<<|
---------------------------
|image 2 | | |
---------------------------
|image 3 / | |
|body /------/ \ |
| | \ |
---------------------------
|image 4| | | | | | | | |
|legs | | | | | | | | |
| \_/ \_/ \_/ \_/ |
---------------------------
Obviously, changing the width of just one image would cause the boundaries to no longer match up, so you'd need to change them all to the same value.
To handle color changes, you can make use of image transparency. Each image would be white, with a transparent region representing the giraffe. Then, you'd set the background color of the div or table cell to the color you want the giraffe to appear. Again, this is clunky, but it would let you do what you want without needing anything other than static GIF / PNG images and basic HTML.

Accessing parent iframe from a childs iframe

Okay, I have an html page with two iframes on it so.
-------------------------------------------------
| PARENT |
| |
| |
| [iframe1 id=i1 name=i1] |
| |
| |
| |
| [iframe2 id=i2 name=i2] |
| |
| |
-------------------------------------------------
When I click on a link in iframe1, i need the resulting page to display in iframe2. I have tried:
<a href=blah.html target=parent.i2>link</a>
but that does not work.
any one know how to do this?
I think you might need JavaScript. Something like
onclick="javascript:parent.i2.document.location='blah.html'"
link
You just need to put "i2" it should be unique window name in this page. No need to specify parent etc.

Vertical spacing between display:inline divs in a fluid grid

Ok, not too sure where to start...
I'm putting myself together a blogger, completely gutting it's css and just using it as a simple content manager. here is the test site i've been working with
http://jamesparishtestblog.blogspot.com/
Ignore the header, its broken, but I know what I'm doing there. My problem is with the film reviews (stolen from apple trailers as temp content). As you resize the page, they flow fluidly into rows of different lengths. Great! Trouble is, the second row (and thus third, fourth, etc.) aligns itself vertically to the bottom of the longest (lowest) div in the above row. However, I want each div to fit neatly below the one above, 15px apart, and to flow neatly if another div is expanded (by clicking read more...).
Placing the divs in a column is ruled out, because I want the top row to contain the most recent posts side by side (with a column they would be below one another on the left hand side).
Set heights for the divs is ruled out too, because the articles need to expand, and for the full desired design, be mis-matched intentionally.
This has been troubling me for hours. I hope I've explained myself clearly, and that someone will can help.
Thanks for your time.
So you want this?
--------------------------
| __________ _______ |
| | | | | |
| | | | | |
| | | | | |
| ---------- | | |
| __________ | | |
| | | |_____| |
| | | _______ |
| | | | | |
| ---------- | | |
| ------- |
|________________________|
Without using columns you can't do it relying on CSS alone. You'd need to use some javascript or server side stuff to put things in the right place. Essentially you want a collage, too bad there's no "display: collage"!
Of course, I could be completely misunderstanding you.
Edit:
"any suggestions on the javascript front?"
I use mootools for almost all my sites. I'll define a bit there first:
dispose : takes an element out of the dom and stores it in a variable.
inject : plops an element into the dom.
I'd load these into columns, then dispose all the ones in the "recent" column and inject them back in to the top of the rest of the columns, one for each column. In other words, all the layout is done with CSS, the only javascript going on is putting your "recent" stuff as the top "row".

Resources