How to get current mouse cursor position on QWidget? - c++

I have to receive the current mouse cursor coordinates in mm/inch, while the cursor hovers over a QWidget.
Already tried: mouseMoveEvent
void darstellung::mouseMoveEvent(QMouseEvent *event){
qDebug() << event->pos();
}
I activated the MouseTracking in the MainWindow constructor as well.
setMouseTracking(true);
It seems that the mouseMoveEvent will only return the cursor position, if the left mouse button is pressed.

I have the same issue, hasMouseTracking() returns false on widget
my Workaround:
//position relative to window| |you might add some ->parentWidget()
QPoint relPos = QCursor::pos() - this->window()->pos();
the positions are relative to virtual screen-coordinates on windows. eg: my widget is displayed at the 2nd monitor, which is left to the 1st -> that gives x=-1000 y=200 (in pixel)
check capability:
if(this->hasMouseTracking() ){
this->setMouseTracking(true);
qDebug("mousetracking on");
}else qDebug("\nmousetracking not available\n");
some useless hints:
https://doc.qt.io/qt-6/qwidget.html#grabMouse (this one is no good practice)
https://stackoverflow.com/a/30960032
So in your constructor you can add a line
this->viewport()->setMouseTracking(true) and then override
mouseMoveEvent

Related

How to display some text besides mouse pointer when the mouse hover over QGraphicsItem's in Qt?

I have a QGraphicsView, which contains many rectangle and polylines. I wanted to print every object names ( every rectangle, polylines have names) once I clicked them on view through mouse click. I did that and worked perfectly.
But now I want to do that over mouse hovering. It means, if I hover a mouse over particular object, it should show its name besides cursor.
I tried that, but
I am not understanding, on hovering, how that particular object should get selected ?
And how to print its name besides cursor point ?
I tried this way:
bool myClass::eventFilter(QObject *watched, QEvent *event)
{
bool filterEvent = false;
switch(event->type())
{
case QEvent::MouseButtonPress:
{....}
case QEvent::MouseButtonRelease:
{...}
case QEvent::Enter:
{
QMouseEvent * mouseEvent = static_cast<QMouseEvent *>(event);
QPointF po = _view->mapToScene(mouseEvent->pos());
FindNamesOverHover(po);
}
return true;
default:
break;
}
return filterEvent;
}
void myClass::FindNamesOverHover(QPointF p)
{
QGraphicsRectItem* rItem = qgraphicsitem_cast<QGraphicsRectItem*>(_scene->itemAt(p,QTransform()));
if(rItem)
{
// some logic
qDebug()<< "Instance name is " << i->Name();
}
}
Constructor of class myClass
myClass::myClass(QWidget* parent) :
QDockWidget(parent)
{
scene = new QGraphicsScene(this);
view = new QGraphicsView(this);
view->setScene(_scene);
view->viewport()->installEventFilter(this);
}
Now above code works only,
When I select object through mouse click and then again hover over it.
Then it prints its name on console.
But I want only hovering ( no selection through mouse click) will show its name besides cursor point.
Can any one help me ?
You can override QGraphicsScene.mouseMoveEvent and inside it use QGraphicsScene.itemAt to query for item under cursor. To display you can use QGraphicsTextItem, just move it to correct position and apply text.

How to get mouse click and release position using override virtual paint()?

I am having QGraphicsView which contains different QGraphicsItem's like rectangle,polyline,text etc. I have installed event filter through which I am managing mouse click and release event and creating rubber band rectangle. Whichever area comes under rubber band rectangle, it gets zoom in.
I am storing rubber band rectangle points in local variables like rubberBandOrigin ( mouse click position ) and rubberBandEnd ( mouse release position)
When I click on any item's, its paint() method gets called. I want to use rubberBandOrigin and rubberBandEnd variables in paint() method.
The way I was told that, you will get these variables ( means mouse click position and release position ) through paint() itself.
paint() has 3rd parameter QWidget *widget. Through this, you will get mouse click and release position (i.e. rubber band rectangle position)
Here is my code:
bool guiSchematicViewUtil::eventFilter(QObject *watched, QEvent *event)
{
bool filterEvent = false;
switch(event->type())
{
case QEvent::MouseButtonPress:
{
QMouseEvent * mouseEvent = static_cast<QMouseEvent *>(event);
rubberBandOrigin = mouseEvent->pos();
rubberBandActive = true;
break;
}
case QEvent::MouseButtonRelease:
{
if (rubberBandActive)
{
QMouseEvent * mouseEvent = static_cast<QMouseEvent *>(event);
rubberBandEnd = mouseEvent->pos();
QGraphicsView * view = static_cast<QGraphicsView *>(watched->parent());
QRectF zoomRectInScene = QRectF(view->mapToScene(rubberBandOrigin),
view->mapToScene(rubberBandEnd));
view->fitInView(zoomRectInScene, Qt::KeepAspectRatio);
rubberBandActive = false;
}
break;
}
default:
break;
}
return filterEvent;
}
paint method:
void guiSchematicRect::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
// Here I want rubberBandOrigin and rubberBandEnd co-ordinates using QWidget* widget parameter
}
I tried with api like parent(), parentWidget() of QWidget but did not get it.
Can any one help me ?

Drag and drop on a QGraphicScene - mouse cursor in center of widget

I want the mouse cursor to be in the position where the mouse was clicked on the widget or in the center of the widget.
For example if the widget is a rectangle and it is in drag event it appears like in the image below, event I've clicked in the center and started to drag:
Where is the red circle is the mouse cursor every time, wherever I "pick-up" the widget.
In the mousePressEvent, I do something like:
void
myQFrame::mousePressEvent( QMouseEvent* event )
{
if( event->button() == Qt::LeftButton )
{
QDrag* drag = new QDrag( this );
QMimeData* mimeData = new QMimeData;
//....other stuff
drag->setMimeData( mimeData );
QPixmap widgetPixmap(this->size());
this->render( &widgetPixmap, QPoint(), QRegion( this->rect() ) );
}
}
Haw can I set the cursor to be in center for example if the widget was picket from the center?
QDrag::setHotSpot is your friend.
UPDATE:
Sets the position of the hot spot relative to the top-left corner of
the pixmap used to the point specified by hotspot.
Note: on X11, the pixmap may not be able to keep up with the mouse
movements if the hot spot causes the pixmap to be displayed directly
under the cursor.
drag->setHotSpot( QPoint( this->width() / 2, this->height() / 2 ) );

Qt how to check which mouse button is pressed

I have problems in PySide while trying to determine which mouse button is pressed in event function. I need it in particular for ignoring mouse move event, because it's doing job on both mouse buttons, left and right.
I want to ignore mouse move event if the right button on scene is pressed. Any help?
All of mouse events have two methods (button and buttons) to determine which of buttons are pressed. But for only move event the documentation says:
Note that the returned value is always Qt::NoButton for mouse move events.
for mouseMoveEvent you should use buttons method.
void mouseMoveEvent(QMouseEvent *e)
{
if(e->buttons() == Qt::RightButton)
qDebug() << "Only right button";
}
In order to ignore move events you need to do this work in eventFilter of course.
QApplication::mouseButtons() will return the status of mouseButton,
so, you can get the status of mouse in KeyPressEvent.
you can check, which mouse button is pressed via Qt::RightButton. Sorry for c++ code, but i hope, you would understand idea anyway:
void mousePressEvent(QMouseEvent *event)
{
if (event->button()==Qt::RightButton){
qDebug() << "right button is pressed
}
}
You could use a boolean:
void mousePressEvent(QMouseEvent *event)
{
if (event->button()==Qt::RightButton){
qDebug() << "right button is pressed
pressed=true; //<-----
}
}
and on mouseMoveEvent
void GLWidget::mouseMoveEvent(QMouseEvent *event)
{
float dx = event->x() - lastPos.x(); // where lastpos is a QPoint member
float dy = event->y() - lastPos.y();
if (dx<0) dx=-dx;
if (dy<0) dy=-dy;
if (event->buttons() & Qt::LeftButton) { //if you have MOVEd
...do something
}
if (event->buttons() & Qt::RightButton) {
if (pressed==true) return;
else{
...do
}
}
}
On mouserelease you have to set pressed=false; ( "pressed" must be a member of the class)
Hope it helps,let me know

Select & moving Qwidget in the screen

I'm using QTCreator and I created a QWidget, then I have hidden the title bar with setWindowFlags(Qt::CustomizeWindowHint);.
But I can't select or move my widget. How can I use the mouseEvent to solve that?
If you want to be able to move your window around on your screen by just clicking and dragging (while maintaining the mouse button pressed), here's an easy way to do that:
#include <QtGui>
class W: public QWidget
{
Q_OBJECT
public:
explicit W(QWidget *parent=0) : QWidget(parent) { }
protected:
void mousePressEvent(QMouseEvent *evt)
{
oldPos = evt->globalPos();
}
void mouseMoveEvent(QMouseEvent *evt)
{
const QPoint delta = evt->globalPos() - oldPos;
move(x()+delta.x(), y()+delta.y());
oldPos = evt->globalPos();
}
private:
QPoint oldPos;
};
In mousePressEvent, you save the global (screen-coordinate) position of where the mouse was, and then in the mouseMoveEvent, you calculate how far the mouse moved and update the widget's position by that amount.
Note that if you have enabled mouse tracking, you'll need to add more logic to only move the window when a mouse button is actually pressed. (With mouse tracking disabled, which is the default, mouseMoveEvents are only generated when a button is held down).