Raphael elements event handlers are executed only when the element is filled.
Click event handlers are not executed when the element has no fill. Mouseover events behave differently, (both mouseover and mouseout are triggered.) for non filled elements.
My code:http://jsfiddle.net/U5wda/1/
Why is this so ?
You might want to check out this article on pointer-events. As you can see in this fiddle, if you set pointer-events to 'fill', I think this works the way you want. Keep in mind, though, that this will probably not work in IE, since Raphael does not use SVG in IE.
Basically, pointer-events: fill causes the element to act like it is filled for mouse events.
You may already realize that when the element is not fill,
Raphael draws only the border of the figur, right?
If you click correctly at the border of the element ( which is very unlikely cause the border-width is too small) the event will trigger anyway.
So nothing's wrong with the event handle, but you should fill your element with color or fill: transparent.
Related
In my application I have a table in the foreground. It has a transparent background so I can see a label with an image through it. Both the table and the label have the exact same size.
I want to draw on the label while the table is still viewable, but not usable. Since the label is a layer behind the table, I just can't draw on it, even if I disable the table and disable the focus. It only works if the label is in the foreground which however would mean that the table is not visible anymore.
I want to draw as soon as I hit a button:
void MainWindow::on_btn_draw_clicked()
{
fg_table->setFocusPolicy(Qt::NoFocus);
fg_table->setEnabled(false);
bg_label->setFocusPolicy(Qt::StrongFocus);
bg_label->setFocus();
}
Which however is not working. The table is disabled and not usable (which is correct), but drawing on bg_label is not possible.
In the Designer the bg_label is a placeholder for the class 'DrawLabel' which inherits from QLabel. In the class drawing is made possible and I can react to various mouse events. Everything works fine and in theory I can draw, but just not if the bg_label is a layer behind the table.
I know that you can raise/lower the layer of a widget with
bg_label->activateWindow();
bg_label->raise();
but this is not what I want. The layers should not be changed and I just want to draw behind the table on bg_label.
Is there any way to achieve this? I haven't seen a similar problem anywhere.
The fact that fg_table is visually transparent is irrelevant. The simple fact is that fg_table will receive all mouse events. Those that it doesn't accept will be propogated to the parent -- not necessarily the widget that appears to be visually underneath -- i.e. bg_label.
Assuming the foreground table doesn't need to interact with mouse events you could probably use...
fg_table->setAttribute(Qt::WA_TransparentForMouseEvents);
That should result in all mouse events going to bg_label.
I've a QTreeWidget and need to disable the mouse over highlighting on the childItems but not the click selection. The point here is, that I need to set this per Item because some are selectable. I was thinking about the QTreeWidget::itemEntered signal to check if the item should be highlighted or not but I can't get it to work because the description says
QTreeWidget mouse tracking needs to be enabled for this feature to
work.
and I can't figure out how.
So my questions for are: How can I enable mouse tracking?
Is there an easier way to disable the highlighting?
Simply invoke setMouseTracking() to enable mouse tracking for a specific widget.
I ran into this problem (I know this is an old post, but I might as well post my solution, since it can be useful for others).
I could not properly disable the mouse feedback while keeping the mouse tracking enabled, but I could make this feedback invisible. I'm using qss stylesheets, and I set the mousehover feedback color to transparent:
MyTreeWidget::item:hover {
background-color: transparent
}
It did the trick for me. Sadly it makes the feedback invisible all the time, rather than allowing to turn it off and on.
So as a next step, for when I needed it, I implemented my own feedback by using a delegate and overwritting the paint function.
The QTreeView overwrite mouseMoveEvent and sends mouse coordinates to the delegate. This way, the delegate can adapt what it does in paint to this position. It feels pretty heavy, and a bit dirty, but it works. Delegate should also allow to have different behavior for different items.
PS: If you're using a delegate, in most cases, that should be enough without the qss change. In my case it wasn't, because I call QStyledItemDelegate::paint in my overwritten paint method, so I inherited some unwanted behavior.
I have a QScrollArea with a set of custom sliders arranged on it. I have noticed that when trying to scroll through the scroll area, one of the sliders often ends up moving instead, which is not desirable.
To make the custom sliders ignore the scroll wheel, I think I need to override QAbstractSlider::wheelEvent and just call ignore in there. This might be a silly question, but is there a way to get this behavior without deriving yet another slider-related class?
You may install an event filter on each of the sliders. When your filter receives a wheel event, just return true to filter this event out.
I have a main window with 3 child: hwndTocBox (left panel), hwndSplitter and hwndCanvas (right panel).
hwndTocBox has a child hwndTreeView, which is a TreeView control. When I drag hwndSplitter to the right (i.e want to make hwndTocBox and hence hwndTreeView bigger), the content (and background?) of hwndCanvas and hwndSplitter will remain for a while. (When I drag the splitter to the left, there is no problem at all.)
When hwndSplitter is draged, it uses DeferWindowPos() to resize and move hwndTocBox, hwndSplitter and hwndCanvas. When hwndTocBox is resized, in WM_SIZE case of its windows procedure, it resizes hwndTreeView (still using DeferWindowPos(), since it resizes not only hwndTreeView but also others).
I have tried to use CLIPCHILDREN and WS_CLIPSIBLINGS in several places, but it doesn't solve the problem.
Why the contents remain there for a while and erased later?
Could you indicate me how to solve this issue, please.
You'll need to repaint the portions of the window that you've resized, otherwise you'll get these strange artifacts. There's a reason they look like smears, because that's almost exactly what they are. A certain portion of the content was painted and appeared on screen normally. Then you resized the window. The portion that had already been painted was not repainted because you didn't invalidate it, but the newly-exposed portion had to be repainted because there was nothing there before.
The fix is simple: add a call to the InvalidateRect() function at the bottom of your resizing code to ensure that the portion of the window you're resizing gets redrawn the next time that the window processes a WM_PAINT message.
If you want to make sure that a WM_PAINT message gets processed immediately (resulting in the immediate redrawing of your window's affected regions), follow up with a call to the UpdateWindow() function. But this really shouldn't be necessary. It's much more efficient to postpone all of the redrawing to later when everything is finalized, rather than doing it incrementally. Relatively speaking, repainting a window is an expensive operation.
I have a CListBox with custom drawing being used, and need to detect mouse-clicks within each item to perform actions.
I can listen for mouse-clicks on the main control and mess about translating coords into the local space of the RECT for the item under the mouse. But is it possible to register message handlers for clicks on individual list items... are there messages for that?
You can use the LVM_HITTEST message to find out which item was clicked.
Well you could just listen for the LBN_SELCHANGE notification. This will fire every time the user clicks a new item. It won't activate if the already selected item is selected though. This may, or may not, be a problem.
Beyond that I'm pretty sure you'll need to intercept WM_LBUTTONUP messages and transform them to the list box's client space ...
OR You could just use a single columned CListCtrl (ListView) class with headers turned off (LVS_NOCOLUMNHEADER). You can then trap the NM_CLICK message. Personally, I massively prefer CListCtrl to CListBox. It IS a little more complex but way more powerful :)
Edit: Or you could try using http://msdn.microsoft.com/en-us/library/bb761323(VS.85).aspx
I'm not certain I understand why you need to have the XY coordinate inside each item of a Clistbox ?
anyway,
AFAIK, Individual items are not CWnd derived objects.
You could get the mouse position inside the control with OnLButtonDown (or up), it returns a CPoint.
After that, use CListBox::GetItemRect to get the rect of the currently selected item, do a bit of pixel computation and you should be able to get the XY inside the rect of the selected item.
Max.
Use the DPtoLP function to convert device coordinates into logical coordinates.
http://msdn.microsoft.com/en-us/library/dd162474(v=vs.85).aspx