Getting wrong name in mouse hover property in Qt - qt

I am having QGraphicsScene which contains many digital gates ( AND,OR,NOR etc ) which are made up of Arc, Polyline, Circle, Straight line etc.
I am implementing a feature like, when I hover mouse over input of Gates, it's name should be seen on tool tip.
In above screen shot, there is a gate (i2) which has 2 inputs ( top input line is a[2] and bottom input line is a[3] )
When I hover inside Red line, I get a[3] as hovering name on cursor tool tip.
And when I hover outside Red line and inside of Blue line, I get a[2] as hovering name on cursor tool tip.
But I am expecting, hovering info will be visible only when I hover on input lines of gates. Why am I getting input line names when I hover around input lines ? And moreover, above hovering info is also wrong.
Here is my code :
bool myViewer::eventFilter(QObject* watched, QEvent* event)
{
case QEvent::MouseMove:
{
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
QPointF mousePoint = _view->mapToScene(mouseEvent->pos());
QGraphicsItem* SelectedItem = scene->itemAt(mousePoint, QTransform());
if(SelectedItem)
{
myPoly* item = qgraphicsitem_cast<myPoly*>(SelectedItem);
if(item)
{
item->setToolTip(item->GetPolyLineName()); // GetPolyLineName gives name as a[2] or a[3]
}
}
}
break;
}
myPoly.h
class myPoly : public QGraphicsPathItem {
public:
QString &GetPolyLineName();
}

Related

Dragged QGraphicsItem not visible in items() function

I have created a QGraphicsScene scene and added some graphcis items (lines, rectangles) etc to the scene.
I can loop through them using this list :
QList<QGraphicsItem*> all = items();
I enabled movement for these items and I am able to drag them by click selecting them. But after an element has been dragged, it stops showing up in the call to items() function of the QGraphicsScene.
QList<QGraphicsItem*> all = items();
None of the dragged items show up in the above list, while non-dragged ones do show up.
Does dragging the QGraphicScene elements change their parent ? or any other reason somebody could suggest for such an issue ?
{P.S. Code is too very big to share}
Edit 1 :
I am using the flags QGraphicsItem::ItemIsSelectable and QGraphicsItem::ItemIsMovable for making the items movable.
foreach(QGraphicsItem* itemInVisualScene, items())
{
itemInVisualScene->setFlag(QGraphicsItem::ItemIsSelectable, itemsMovable);
itemInVisualScene->setFlag(QGraphicsItem::ItemIsMovable, itemsMovable);
}
By default I add few rectangle to the scene. Then in the 'move mode' I drag them around. Then in the 'add mode' I click on screen to add new rectangles. I have written a logic to check if I am clicking on any existing drawn rectangle :
void Scene::mousePressEvent(QGraphicsSceneMouseEvent * event)
{
if(eDrawLines == sceneMode)
{
dragBeginPoint = event->scenePos();
dragEndPoint = dragBeginPoint;
QList<QGraphicsItem*> all = items();
for (int i = 0; i < all.size(); i++)
{
QGraphicsItem *gi = all[i];
// Clicked point lies inside existing rect
if( QGraphicsRectItem::Type == gi->type() && gi->contains(dragBeginPoint))
{
std::cout << "Pressed inside existing rect" << std::endl;
return;
}
}
std::cout << "Point not found, add new rectangle" << std::endl;
}
QGraphicsScene::mousePressEvent(event);
}
This adding of rectangles work fine for rects which were not dragged in the 'move mode'. But rects which were moved do not seem to recognize the click anymore. My control comes out of the loop even when I click on an existing rectangle which was dragged earlier.
QGraphicsItem's transform is changed after dragging and therefore need to transform the point to item's local coordinates.
gi->contains(gi->mapFromScene(dragBeginPoint))
To convert or get item's position in scene coordinates, use
gi->mapToScene(0,0) or gi->scenePos()

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);
}

QLabel "hover" area too small

I'm experiencing a problem with hover functionality on QLabel.
I've implemented this as event filter:
HoverLabel::HoverLabel(QWidget *parent) : QWidget(parent)
{
installEventFilter(this);
label = (QLabel *)parent;
show();
}
bool HoverLabel::eventFilter(QObject *object, QEvent *event)
{
if (object == this)
{
if (event->type() == QEvent::Enter)
{
label->setText("Howering");
return true;
}
else if (event->type() == QEvent::Leave)
{
label->setText("Not howering");
return true;
}
}
return false;
}
Calling while main constructor is running as:
hoverLabels[0] = new HoverLabel(ui->hoverLabel_1);
Now everything works fine except that the area where I ger QEvent::Enter is just too small and what's more, constant - you can double the size of label and area that generates event stays the same.
I've marked the hover area on picture with blue rectangle, as the mouse wasn't captured for whatever reason. Beyond that, it say's "Not howering". I've tried various text content, various text sizes, checking all the boxes around, setting different size policies but the area is still the same.
In short, the class had to override eventFilter. In my case class is called PlayerLabel.
See these 2 files for how to:
header file:
https://github.com/metthal/ICP-Projekt/blob/1f0a0f6e919d132bbec6bacd1cff91a3a596460d/inc/gui/mainwindow.h#L40
source file:
https://github.com/metthal/ICP-Projekt/blob/1f0a0f6e919d132bbec6bacd1cff91a3a596460d/src/gui/mainwindow.cpp#L908
Also see how to create this object afterwards:
https://github.com/metthal/ICP-Projekt/blob/1f0a0f6e919d132bbec6bacd1cff91a3a596460d/src/gui/mainwindow.cpp#L358

Moving object with mouse

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));
}
}

I want to know about how to draw a line between two nodes. .

simply i explain: first want to mouse press in graphicsscene and release the mouse. that point should be start point. then another plase i should press the mouse and release that will be end point then the line should be drawn. I can draw a line when mouse pressing and moving. but i want to know that abpve mentioned way. please some one help me. i am stuck in this .
You can capture the location of mouse when mouse is pressed on graphics scene by handling mousePressEvent() of graphics scene, and using QGraphicsSceneMouseEvent's pos() method and store it.
Letter whey you detect second mouse click, use first point and second point to draw line.
From you question it looks you already know how to draw line so i will not put anything on that regards.
Something like following,
mousePressEvent( QGraphicsSceneMouseEvent * mouseEvent) {
QPointF pos = mouseEvent->pos();
if( mStartPoint.isNull() ) {
mStartPoint = pos;
} else {
drawLine(mStartPoint, pos);
mStartPoint = QPointF();
}
}

Resources