Moving object with mouse - qt

I use Qt and I want to move some object with mouse. For example, user clicks on object and drag this object to another place of window. How I can do it?
I tried mouseMoveEvent:
void QDropLabel::mouseMoveEvent(QMouseEvent *ev)
{
this->move(ev->pos());
}
but unfortunately object moves very strange way. It jumps from place to place.
QDropLabel inherits QLabel. Also it has given a pixmap.
I tried to do it with different objects, but result is same.

Your movable widget must have a QPoint offset member. It will store a position of the cursor click relative to the widget's top left corner:
void DropLabel::mousePressEvent(QMouseEvent *event)
{
offset = event->pos();
}
On mouse move event you just move your widget in its parent coordinate system. Note that if you don't subtract offset from the cursor position, your widget will 'jump' so its top left corner will be just under the cursor.
void DropLabel::mouseMoveEvent(QMouseEvent *event)
{
if(event->buttons() & Qt::LeftButton)
{
this->move(mapToParent(event->pos() - offset));
}
}

Related

Zoom in / Zoom out in QT without using scroll button

I want to zoom in/out a part in openGL using mouse. Now I can do it well using the scroll button in mouse. But my goal is now to perform the same operation by holding the left mouse button and moving the mouse to and fro in the screen.
I don't know how to perform the zooming action by detecting the to and fro motion of mouse.
// function for mouse scroll events
void VDUI_GLWidget::wheelEvent (QWheelEvent * e) {
// here comes the code for zoom in / out based on the scrolling
MouseWheel (e->delta () / float (WHEEL_STEP), QTWheel2VCG (e->modifiers ()));
updateGL();
}
Now I want to perform the same using mouse move and mouse press events. I'm unable to pick the event which detects the to and fro motion
Now I have found the solution. Finding the difference between the current & previous Y axis position, I can zoom in / out the Please refer this below mentioned code.
// function for mouse move events
void GLWidget::mouseMoveEvent (QMouseEvent * e) {
static int curY = 0, prevY = 0;
if (e->buttons()) {
curY = e->y(); // current position of Y
if( (curY - prevY) > 0 ) // call zoom in function
else // call zoom out function
updateGL();
}
prevY = curY;
}

Qt plainTextEdit jump to line

I wirte a codeEdit based on plainEdit, and I need to move to specified line. The below code relize the function patially. The proplem is that the cursor is on the bottom of the widget. Is there some way to put the cursor (yellow line) in the middle of the widget.
void MainWindow::run(){
QTextCursor text_cursor(SPUEdit->document()->findBlockByNumber(100));
SPUEdit->setTextCursor(text_cursor);
// SPUEdit->verticalScrollBar()->setValue(12);
}
You should call centerCursor method of QPlainTextEdit:
void QPlainTextEdit::centerCursor()
Scrolls the document in order to
center the cursor vertically.

Items in a QGraphicsScene near the mouse

I am trying to find the items under the mouse in a scene. The code I am using is as follows:
QPainterPath mousePath;
mousePath.addEllipse(mouseEvent -> pos(),5,5);
QList<QGraphicsItem *> itemsCandidate = this->items(mousePath);
if (!(itemsCandidate.contains(lastSelectedItem))) lastSelectedItem =itemsCandidate.first();
PS: this refers to a scene.
The code should find the items intersected by a small circle around the mouse position and keep the item pointer unchanged if the previous intersected one is still intersected, or take the first in the QList otherwise.
Unfortunately, this code does not work with items inside each other. For example, if I have a Rect side a Rect, the outer Rect is always intersecting the mouse position even when this one is near the inner Rect. How can i solve this?
UPDATE: This seems not to be a problem with polygons, but with Rect, Ellipses, etc.
UPDATE: This code is in the redefined scene::mouseMoveEvent
You can reimplement ‍mouseMoveEvent in ‍QGraphicsView‍ to capture mouse move events in view and track items near the mouse like:
void MyView::mouseMoveEvent(QMouseEvent *event)
{
QPointF mousePoint = mapToScene(event->pos());
qreal x = mousePoint.x();
qreal y = mousePoint.y();
foreach(QGraphicsItem * t , items())
{
int dist = qSqrt(qPow(t->pos().x()-x,2)+qPow(t->pos().y()-y,2));
if( dist<70 )
{
//do whatever you like
}
}
QGraphicsView::mouseMoveEvent(event);
}

QMenu being displayed outside the main window

I'm using a custom QGraphicsWidget and when I right click on it I want to bring up a menu. I'm starting it like this:
void myQGraphicsWidget::mousePressEvent(QGraphicsSceneMouseEvent *event){
if(event->button() & Qt::RightButton){
const QString test = "test";
QMenu menu;
menu.setTitle(test);
menu.addAction(test);
menu.exec(mapToScene(event->pos()).toPoint());
//menu.exec(mapToScene(QPointF(0,0)).toPoint());
}
}
but the menu shows up way outside of the main application window towards the bottom right of my other monitor. When I use the commented out version then it appears resting on top of my main window. I've tried adjusting the point manually to massage it inside the window but it will just jump to either resting on top of the window or hanging from the bottom, never inside.
QMenu::exec takes a global position; you're taking the widget-relative position and mapping it to the scene position.
Try this instead:
menu.exec(event->screenPos());

Move QGraphicsItem with mouse hover

I'm trying to move a QGraphicsItem with the mouse hover over the parent item.
BaseItem::BaseItem(const QRectF &bounds)
: theBounds(bounds), theMousePressed(false)
{
theLineItem = new LineItem(theBounds, this);
setAcceptHoverEvents(true);
}
and
void BaseItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
{
QPointF position = mapToScene( event->pos());
theLineItem->setPos( position);
}
But the item is not moving. Is there any other way to move the item on the scene with mouse move, without using the ItemIsMovable flag, because I want the item to be moved around the parent item, once it's invoked?
When you create the LineItem, in its constructor you pass the BaseItem as the parent.
A call to setPos on a GraphicsItem, sets the position of the item relative to its parent which, in this case, is the BaseItem.
Mapping the event->pos() to scene coordinates is wrong here. event->pos() returns the position in local coordinates of the receiving object, which in this case is the BaseItem.
Therefore, you should be setting the position of theLineItem directly with event->pos().
theLineItem->setPos(event->pos());
Note that if you did happen to want the event position in scene coordinates, there's a function already available: -
event->scenePos();
So you would not have needed to call mapToScene.

Resources