How we canfire a window resize event with XTK? - xtk

How we can fire a window resize event with XTK?
ANd is it possible to extract the width and the higth of the image witch is into the canvas ?
Best,
AMAL

The resize event is just a general resize event like here https://stackoverflow.com/a/7622176/1183453
var evt = document.createEvent('UIEvents');
evt.initUIEvent('resize', true, false,window,0);
window.dispatchEvent(evt);

Related

How to know if the mouse hovers over a widget in QT?

I am trying to implement in my program, that if the mouse hovers over my QChartView widget, that I get back the coordinates of the cursor.
I already tried, by installing an event filter on the widget
ui->chartView->setMouseTracking(true);
ui->chartView->installEventFilter(this);
and then writing the method for a mouse event
void MainWindow::mouseMoveEvent(QMouseEvent* event) {
qDebug() << event->pos();
}
but, i only get output when I click on the Mainwindow and hold the mousebutton which I clicked. When I click on the widget chartView I dont get any output.
I need to get output, when the mouse is hovering over the chartview
You don't need an event filter. You need to reimplement the methods QWidget::enterEvent() and QWidget::leaveEvent().
enterEvent() is called when the mouse enters the widget and leaveEvent() when it leaves it again.

How to get a signal when window manager is done resizing window in qt QML?

I'm trying to achieve a similar effect as iTunes' miniPlayer when resizing happens on macOS. That is, detecting when a resizing of the the window has been completed, THEN changing the height to a certain value. Here is a visual example :
The problem is that no signal in a QML window exists to notify me when the window manager is done resizing (that is, the user released the handle). Hence, if I don't have a signal and apply my height change as soon as width or height is changed during resizing, the window will flicker (double resize happens) as long as the user didn't release the handle.
Thanks for any input or help!
You could implement your own resize handle pretty easily, using a MouseArea and handling the final resize calculation using onReleased (here forcing the height to be 75% of the width on release):
Window {
id: window
flags: Qt.FramelessWindowHint
visible: true
height: 300
width: 400
MouseArea {
id: resize
anchors {
right: parent.right
bottom: parent.bottom
}
width: 15
height: 15
cursorShape: Qt.SizeFDiagCursor
property point clickPos: "1,1"
onPressed: {
resize.clickPos = Qt.point(mouse.x,mouse.y)
}
onPositionChanged: {
var delta = Qt.point(mouse.x-resize.clickPos.x, mouse.y-resize.clickPos.y)
window.width += delta.x;
window.height += delta.y;
}
onReleased: {
window.height = .75 * window.width
}
Rectangle {
id: resizeHint
color: "red"
anchors.fill: resize
}
}
}
QML provided some NOTIFY signals when property values are supposed to be updated. So you can use Window.width's and Window.height's:
Window {
id: window
onWidthChanged: {
// Will be executed after window.width value changes.
}
onHeightChanged: {
// Will be executed after window.height value changes.
}
// Other window-related stuff
}
Here is an idea (that I did not try yet, but still):
Implement an event handler reacting to changes of the global cursor position. The cursor position inside the window is not applicable as the cursor is outside the window when grabbing a resize handle. Not sure if and how such an event handler is possible, but at least accessing the screen-global cursor position is possible in Qt.
In the event handler, check if the vertical cursor position change compared to the last call of the handler is the same as the window height change.
If yes, assume that the user still holds the window resizing handle, so don't adapt window height.
If no, assume that the user released the window resizing handle and started to move the cursor around freely. Adapt the window height now.
You'll probably have to overcome several issues, such as (1) allowing for a certain divergence between the window height and cursor y position changes, as window height changes might be less frequent and trail the cursor movement somewhat, (2) engaging the cursor position event handler only during a window resize to limit system load. But if it works, it's a native solution, not implementing own resizing handles.
It seems you want QML to send two different signal types, one to mark the start and finish of resizing, and one to mark size changes during resizing. The event sequence would then be something like this:
window.resizeStarted() // hypothetical new event
window.widthChanged()
window.heightChanged()
window.widthChanged()
window.heightChanged()
...
window.resizeEnded() // hypothetical new event
That is apparently impossible in Qt out of the box, but you should be able to implement it yourself with this approach, originally meant to not repaint the window at all while resizing:
Filter the relevant events out until the mouse button has been released. Specifically, "eat" the resize event while the mouse button is held down, and then synthesize the final resize event once the mouse is released. You can do it all in an event filter attached to the window / widget object that displays your QML interface. (source)
The process would be very similar to the one in the quote:
Extend the QML Window type with custom signals:
//MyWindow.qml
Window {
signal resizeStarted()
signal resizeEnded()
}
Create an event filter on the QML window that "eats" all window resize events. When it encounters the first one, it sends resizeStarted(). Then it forwards the window resize events. When it encounters a mouse release event while resizing, it sends resizeEnded() after the last widthChanged() / heightChanged() event.
Implement a corresponding signal handler onResizeEnded in QML to react, here to adapt the height of your application window to a certain fixed value.
Seems quite a promising route to me, but to note, I haven't tried it in code so far.

Custom Qt QGraphicsItem tooltip

I'm looking for some ways to implement a simple custom tooltip for QGraphicsItem.
I know that I can use setToolTip to set text for tooltip. Now what I want is to change the text dynamically when the mouse hovers at different parts of a QGraphicsItem object.
What I'm thinking to do is when I get an event QEvent::ToolTip, I change the tooltip text in that event handler. However, I cannot find an event function that recieve QEvent::ToolTip for QGraphicsItem.
Or is there some ways to handle an event that mouse hovers for 2 seconds.
How can I make it?
You could implement the hoverMoveEvent in your derived QGraphicsItem class, and set the tooltip based on the position within the graphics item
void MyItem::hoverMoveEvent(QGraphicsSceneHoverEvent* event)
{
QPointF p = event->pos();
// use p.x() and p.y() to set the tooltip accrdingly, for example:
if (p.y() < height()/2)
setTooltip("Upper Half");
else
setTooltip("Bottom Half");
}
Notice that you have to enable hover events for your item.

Custom button shape

I want to implement a simple volume up/down button using a custom bitmap, and all it's going to have is a simple hover effect, and mouse down effect.
My first idea was to process WM_MOUSEMOVE for the hover, and process WM_LBUTTONUP and WM_LBUTTONDOWN for the mouse down effect.
First, is this the easiest way to do this? I could superclass a button and just paint the bitmap and forget about the text...
Then I have the problem with the background, which should be transparent, I know I can use a mask by passing SRCAND to BitBlt, but this requires me to have 2 images for each button. Is there any way to do this with just one image? Like if I put a green background on it in my image editor, could I mask that out with a green screen like effect?
You need to create a regular button, and subclass it with SetWindowSubclass. The button must have the owner-draw style on it, which means in the parent WndProc, you are handling WM_DRAWITEM. As you correctly say, you will be BitBlt'ing or StretchBlt'ing the background of the image on.
For hover events you must do the following:
Have some sort of shared boolean between the parent and subclassed WndProc, eg. IsMousedOver
In the subclassed WndProc, process WM_MOUSEMOVE. When this message is hit, you should set IsMousedOver, then invalidate the control with InvalidateRect (this will trigger WM_DRAWITEM in the parent)
In the parent WndProc, if you receive WM_MOUSEMOVE, you should clear IsMousedOver
In WM_DRAWITEM in the parent WndProc, you should check IsMousedOver and BitBlt based on that state
If you want to process MouseUp/MouseDown, you can change the boolean to an int instead and have a tri-state. However, most implementations have MouseDown being the same as the regular button, and MouseUp is then simply the regular moused over background.
As for your query about 2 images, it may well be possible to do it with one but I haven't tried that before.

QT mouse event handling problem

Greetings all,
As seen in the picture
I have an extended QWidget object (which draws the cell images and some countour data) inside a QScrollBar.
User can zoom in/out the Image (QWidget size is changed according to the zoomed size of the QImage ) using mouse wheel.
I process the events (mouseMoveEvent(),wheelEvent()..etc) by implementing the listener methods in QWidget.
My problem is ,I can only perform zooming (and other events) when the mouse pointer is over the QWidget.
If the mouse point is over the QScrollBar (the gray area in the image) ,those events are consumed by the QScroolBar.
Any tips,
[Edit] Sorry I was refering to QScrollArea , not QScrollBar.
thanks,
umanga
I'm uncertain if you want the scroll wheel to only ever be used for zooming the image or if you want the scroll wheel to control zooming when the image is smaller than the scroll area viewport and then use the scroll wheel to do scrolling when the image is larger than the scroll area viewport. In either case, you should be able to customize how the wheel is handled with the following:
Since I've not actually tried this one, I'm not sure if it will work. The hope is that if you install an event filter and set ignore on the event, the event will still be propagated back to your image widget. This will allow you to leave your current mouse handling in the image widget intact.
bool YourImageWidget::eventFilter(QObject *obj, QEvent *event)
{
if((obj == scrollAreaPointer) && (event->type() == QEvent::Wheel))
{
if(!scrollAreaShouldHandleWheel)
{
event->ignore();
}
}
return false; // always pass the event back to the scroll area
}
The scrollAreaShouldHandleWheel flag is a boolean you would set from your image widget based on whether or not you want the scroll area to handle the wheel events.
Somewhere in your code you would install your image widget as an event filter for the scrollarea.
scrollArea->installEventFilter(imageWidget);
If this doesn't work, you can always use this filter to make sure your widget gets the event and handle it directly and then return true so that the scroll area won't be able to receive the event.
I recommend you use QGraphicsScene and QGraphicsView. The graphics framework already provides a lot of useful features (including viewport transformation). And the QGraphicsView is a scroll area.
have you done grabMouse() for Qwidget i.e for the one which you display image?